This is a typical Power Loop problem, and I only need a simple and elegant (compact) solution... I will show fist the sample of problem/solution with nested for loops. Suppose that I need to transform this piece of code into a recursion:
console.log("bits","Binary")
for (let i=0; i<2; i++) {
show(i)
for (let j=0; j<2; j++) {
show(i,j)
for (let k=0; k<2; k++)
show(i,j,k) // ... l,m,n,o,p
} // j
} // i
function show(...args) {
let code = String( args.reduce( (ac,cur) => ''+ac+cur ) )
console.log( code.length, code )
}
The 14-unique-lines output of this 3-level sample is
bits Binary
1 '0'
2 '00'
3 '000'
3 '001'
2 '01'
3 '010'
3 '011'
1 '1'
2 '10'
3 '100'
3 '101'
2 '11'
3 '110'
3 '111'
I am trying to solve using as reference this solution:
callManyTimes([2,2,2], show);
function callManyTimes(maxIndices, func) {
doCallManyTimes(maxIndices, func, [], 0);
}
function doCallManyTimes(maxIndices, func, args, index) {
if (maxIndices.length == 0) {
let x = args.slice(0); // cloning
while(x.length>0) {
func(x); // why send array[array]?
x.shift();
}
} else {
var rest = maxIndices.slice(1);
for (args[index] = 0; args[index] < maxIndices[0]; ++args[index]) {
doCallManyTimes(rest, func, args, index + 1);
}
}
}
function show(...args) {
if (typeof args[0] == 'object') args=args[0] // workaround... can optimize?
let code = String( args.reduce( (ac,cur) => ''+ac+cur ) )
console.log( code.length, code )
}
The output have duplicated lines, but there are a subset of lines that are the solution... So, seems near, but is ugly (no elegant use of the recurrence stack, etc.)
3 '000'
2 '00'
1 '0'
3 '001'
2 '01'
1 '1'
3 '010'
2 '10'
1 '0'
3 '011'
2 '11'
1 '1'
...
You could take a function which takes a temporary array for the generated values.
function show(...args) {
let code = args.join('');
console.log(code.length, code);
}
function callManyTimes(max, cb, items = []) {
var i, temp;
if (items.length === max.length) return;
for (i = 0; i < max[items.length]; i++) {
temp = items.concat(i);
cb(...temp);
callManyTimes(max, cb, temp);
}
}
callManyTimes([2, 2, 2], show);
A simple backtracking recursive function will visit these in the order of the first example with something like:
function iter(maxlength, cur = ''){
if (cur.length >= maxlength) return
for (let i = 0; i < 2; i++){
console.log(cur.length + 1 + ":", cur + i)
iter(maxlength, cur + i)
}
}
iter(3)
You can also generate an array with the same idea and a generator function (here it's returning an array of arrays to join later, but the same principle):
function* iter(maxlength, prefix = []){
if (prefix.length >= maxlength) return
for (let i = 0; i < 2; i++){
yield [i, ...prefix]
yield * iter(maxlength, [i, ...prefix])
}
}
console.log([...iter(3)].map(a => a.join(',')))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With