In Javascript, I am attempting to iterate through an array of indices indexArray
. This array can be any length, but for ease of explanation, I will use length 3 indexArray.length = 3
.
I have an external function: getResult(indexArray)
which returns an integer.
I would like to recursively loop through indexArray
calling getResult(indexArray)
and incrementing each index until a condition has been met: getResult(indexArray) > 5
The initial array is always an array of 1s: indexArray = [1, 1, 1]
. I would like the indices to increment from the last element to the 0th element in the following manner:
[1,1,1], [1,1,2], [1,1,3], [1,1,4] *Condition Met* [1,2,1], [1,2,2], [1,2,3], ...
And so on until the condition has been met for every combination over the integers.
I found this stackoverflow question which helped me formulate my initial attempts, however as I do not know the constraints on my indices, for loops do not work for my use case.
Here is what I have attempted so far:
numVars = 3;
currentIndices = Array(numVars).fill(1);
end = false
function callManyTimes(indices, func) {
doCallManyTimes(indices, func, [], 0);
}
function doCallManyTimes(indices, func, args, index) {
if (indices.length == 0) {
func(args);
end = true;
} else {
var rest = indices.slice(1);
args[index] = 1;
while(!end){
currentIndices[index] = args[index]
currentVal = func(currentIndices);
if(currentVal > 5){
doCallManyTimes(rest, func, args, index + 1)
}
++args[index];
}
}
}
function getResult(indices){
res = indices.reduce((partialSum, a) => partialSum + a, 0);
console.log(currentIndices);
return res;
}
callManyTimes(currentIndices, getResult);
And the output I get (from logging the indices on each loop) is:
[ 1, 1, 1 ]
[ 2, 1, 1 ]
[ 3, 1, 1 ]
[ 4, 1, 1 ]
[ 4, 1, 1 ]
[ 4, 1, 1 ]
[ 4, 1, 1 ]
Clearly I'm doing something wrong with my looping condition, but I can't seem to understand why the recursion is not iterating through the different indices. Or why it repeats its final state 4 times. If someone could help clear this up, it would be much appreciated. Thanks!
EDIT: My Expected/Desired Output is:
[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 1, 4] //condition met here
[1, 2, 1]
[1, 2, 2]
[1, 2, 3] //condition met here
[1, 3, 1]
[1, 3, 2] //condition met here
[1, 4, 1] //condition met here
[2, 1, 1]
[2, 1, 2]
[2, 1, 3] //condition met here
[2, 2, 1]
[2, 2, 2] //condition met here
[2, 3, 1] //condition met here
[3, 1, 1]
[3, 1, 2] //condition met here
[3, 2, 1] //condition met here
[4, 1, 1] //condition met here
EDIT #2: Reduced, but accurate condition-calculating logic
Instead of the line currentVal > 5
, I am storing the previous value (previousVal
) of currentVal
, and checking the following: (currentVal > 0) && ((currentVal/previousVal) > .99)
. If both of those conditions are met, I'd like to increment the array of indices as previously described. Below is a rough version of my getResults(indices)
function after ripping out extraneous steps in order to keep the logic as close to original as possible.
const BigNumber = require("bignumber.js");
function getResults(indices){
sum = BigNumber(0);
for(i = 0; i < indices.length; i++){
fiveTerm = indices.length - 1 - i;
fiveValue = BigNumber(5).pow(fiveTerm);
var threeValue;
if(i == 0){
threeValue = BigNumber(1);
} else {
threeIndices = indices.slice(-i);
threeIndexSum = threeIndices.reduce((partialSum, a) => partialSum + a, 0);
threeValue = BigNumber(3).pow(threeIndexSum);
}
currentTerm = fiveValue.times(threeValue);
sum = sum.plus(currentTerm);
}
indexSum = indices.reduce((partialSum, a) => partialSum + a, 0);
divisor = (BigNumber(3).pow(indexSum)).minus(BigNumber(5).pow(indices.length))
result = sum.div(divisor);
console.log("Indices: " + indices + "\nResult: " + result.toFixed())
return result;
}
I hope this edit is helpful for clarification regarding the conditions around which I'd like the iterators to increment.