Yes. This can be performed by recursive programming.

I assume you do not like to WRITE DOWN these nested for's in source code - as in your example, because this is really ugly programming - like the commentors explain.

The following (pseudo Java-like) code illustrates it. I assume a fixed depth for the nesting. Then you actually like to loop over an integer vector of dimension depth.

int[] length = new int[depth];
int[] counters = new int[depth];

The array counters has to be initialised to 0 (Arrays.fill(counters,0)). The array length has to be initialised to the number of iterations for the respective for loop.

I assume that you like to perform a certain operation within the inner loop. I will call this performOperation(int[] counters); - it depends on the multi-dimensional counter, i.e. the counters of the outer for's.

Then you can run the nested for loops by calling

nestedLoopOperation(counters, length, 0);

where

void nestedLoopOperation(int[] counters, int[] length, int level) {
    if(level == counters.length) performOperation(counters);
    else {
        for (counters[level] = 0; counters[level] < length[level]; counters[level]++) {
            nestedLoopOperation(counters, length, level + 1);
        }
    }
}

In your case your System.out.println() would be

performOperation(int[] counters) {
    String counterAsString = "";
    for (int level = 0; level < counters.length; level++) {
        counterAsString = counterAsString + counters[level];
        if (level < counters.length - 1) counterAsString = counterAsString + ",";
   }
   System.out.println(counterAsString);
}
Answer from Christian Fries on Stack Overflow
🌐
Mathemathinking
corysimon.github.io › articles › recursion
Nested loops via recursion – Mathemathinking
May 2, 2016 - We can use a recursive algorithm instead to write a function for a general n: n = 8 lattice_state = zeros(Int, n) function nested_loop(loop_level::Int) """ Recursive algorithm to perform nested loop: for i = [-1, 1] lattice_state[1] = i for j = [-1, 1] lattice_state[2] = j ....
Top answer
1 of 2
19

Yes. This can be performed by recursive programming.

I assume you do not like to WRITE DOWN these nested for's in source code - as in your example, because this is really ugly programming - like the commentors explain.

The following (pseudo Java-like) code illustrates it. I assume a fixed depth for the nesting. Then you actually like to loop over an integer vector of dimension depth.

int[] length = new int[depth];
int[] counters = new int[depth];

The array counters has to be initialised to 0 (Arrays.fill(counters,0)). The array length has to be initialised to the number of iterations for the respective for loop.

I assume that you like to perform a certain operation within the inner loop. I will call this performOperation(int[] counters); - it depends on the multi-dimensional counter, i.e. the counters of the outer for's.

Then you can run the nested for loops by calling

nestedLoopOperation(counters, length, 0);

where

void nestedLoopOperation(int[] counters, int[] length, int level) {
    if(level == counters.length) performOperation(counters);
    else {
        for (counters[level] = 0; counters[level] < length[level]; counters[level]++) {
            nestedLoopOperation(counters, length, level + 1);
        }
    }
}

In your case your System.out.println() would be

performOperation(int[] counters) {
    String counterAsString = "";
    for (int level = 0; level < counters.length; level++) {
        counterAsString = counterAsString + counters[level];
        if (level < counters.length - 1) counterAsString = counterAsString + ",";
   }
   System.out.println(counterAsString);
}
2 of 2
1

I created this program to show all the different possible combination of cards (non repeating). It uses recursive for loops. Maybe it can help you.

//I'm lazy, so yeah, I made this import...
import static java.lang.System.out;

class ListCombinations {

    //Array containing the values of the cards
    static Symbol[] cardValues = Symbol.values();

    //Array to represent the positions of the cards,
    //they will hold different card values as the program executes
    static Symbol[] positions = new Symbol[cardValues.length];

    //A simple counter to show the number of combinations
    static int counter = 1;

    /*Names of cards to combine, add as many as you want, but be careful, we're
    talking about factorials here, so 4 cards = 24 different combinations (4! = 24),
    but 8 cards = 40320 combinations and 13 cards = 6.23 billion combinations!*/
    enum Symbol {
        AofSpades, TwoofSpades, ThreeofSpades, FourofSpades
    }

    public static void main(String args[]) {

        //I send an argument of 0 because that is the first location which
        //we want to add value to. Every recursive call will then add +1 to the argument.
        combinations(0);
    }

    static void combinations(int locNumber) {

        /* I use a recursive (repeating itself) method, since nesting for loops inside
        * each other looks nasty and also requires one to know how many cards we will
        * combine. I used 4 cards so we could nest 4 for loops one after another, but
        * as I said, that's nasty programming. And if you add more cards, you would
        * need to nest more for loops. Using a recursive method looks better, and gives
        * you the freedom to combine as many cards as you want without changing code. */

        //Recursive for loop nesting to iterate through all possible card combinations
        for(int valueNumber = 0; valueNumber < cardValues.length; valueNumber++) {
            positions[locNumber] = cardValues[valueNumber];
            if (locNumber < (cardValues.length-1)) {
                combinations(locNumber + 1);
            }

            //This if statement grabs and displays card combinations in which no card value
            // is repeated in the current "positions" array. Since in a single deck,
            // there are no repeated cards. It also appends the combination count at the end.
            if (locNumber == (cardValues.length-1) && repeatedCards(positions)) {
                for (int i = 0; i < cardValues.length; i++) {
                out.print(positions[i]);
                out.print(" ");
                }
                out.printf("%s", counter);
                counter++;
                out.println();
            }
        }
    }

    static boolean repeatedCards(Symbol[] cards) {

        /*Method used to check if any cards are repeated in the current "positions" array*/

        boolean booleanValue = true;

        for(int i = 0; i < cardValues.length; i++) {
            for(int j = 0; j < cardValues.length; j++) {
                if(i != j && cards[i] == cards[j]) {
                    booleanValue = false;
                }
            }
        }
        return booleanValue;
    }
}
Discussions

java - Nested Loop Recursion - Stack Overflow
I am learning recursions and I wanna to rewrite the following code with some "n" number of nested loops in terms of recursion for (int a = 0; a More on stackoverflow.com
🌐 stackoverflow.com
Arbitrary depth nested for-loops without recursion - Computer Science Stack Exchange
My understanding is that any recursive function can be rewritten iteratively, though it usually requires some augmentation. (For example, an in-order traversal of a binary tree can be done iteratively if you augment each node with two bits and a parent pointer.) How can I rewrite nestForLoopRecursive... More on cs.stackexchange.com
🌐 cs.stackexchange.com
June 13, 2020
algorithms - General way to convert a loop (while/for) to recursion or from a recursion to a loop? - Software Engineering Stack Exchange
This problem is mainly focusing on the algorithm, maybe something abstract and more academic. The example is offering a thought, I wanna a generic way, so example is only used as to make us more c... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
April 14, 2015
c - Convert nested loop to recursion - Stack Overflow
I have used 3 nested loop. Now i want to convert these loops to recursive. Also is there a general way to convert a loop into recursive? #include #define f(x, y, z) ((x + y) * (y ... More on stackoverflow.com
🌐 stackoverflow.com
June 7, 2017
🌐
Reddit
reddit.com › r/learnprogramming › [python] converting nested for-loop into recursion
r/learnprogramming on Reddit: [Python] Converting Nested For-Loop into Recursion
February 17, 2020 -

Hey guys, I'm pretty new to python and I'd like to practice using Recursion in my code to further assist my understandings with the recursive function. From what I am aware of, identifying a base case is required to prevent infinite recursion but I cannot seem to figure out the base case for this scenario.

Simplified code as shown below:

for y in range(N):         
    for x in range(M):             
        if origin[x][y] == 1 and CellsMap[x][y] == 0:                        
           CellsCounter += 1             
        DiscoverCells(origin, x, y, CellsCounter)  

Basically the above code will scan for every (x, y) coordinate in a grid (Implemented by the nested For Loop)

How do I go about converting this code into recursion, with a call to function of def DiscoverCells()?

Thanks in advance!!

Top answer
1 of 3
3
First, let's eliminate for loops because we want to avoid thinking about what a for loop in Python translates to. y = 0 while y < N: x = 0 while x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) x = x + 1 y = y + 1 What state do we have N, y, M, x, origin and CellsCounter. so let's start with making a function taking these inputs as arguments. def f(y, N, x, M, origin, CellsCounter): pass This looks too complicated to do all at once so lets start with the inner loop while x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) x = x + 1 will be converted to def inner(y, N, x, M, origin, CellsCounter): pass First, let's copy paste the body of the loop into inner def inner(y, N, x, M, origin, CellsCounter): if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) x = x + 1 Now, at the end we need to do the following logic if while condition is true: loop again else: return result So, let's just put that logic in def inner(y, N, x, M, origin, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, N, x + 1, M, origin, CellsCounter) else: return (y, N, x, M, origin, CellsCounter) Notice that we return all things that can change during any execution of our loop. We'll eliminate the unchanging stuff later. Now, we do a similar thing for the outer loop y = 0 while y < N: x = 0 INNER LOOP y = y + 1 Converting to a function outer def outer(y, N, x, M, origin, CellsCounter): x = 0 INNER LOOP y = y + 1 Adding the looping logic back in def outer(y, N, x, M, origin, CellsCounter): if y < N: x = 0 INNER LOOP return outer(y + 1, N, x, M, origin, CellsCounter) else: return (y, N, x, M, origin, CellsCounter) How does inner loop work? We call the inner loop function and then update all 6 of our variables to what they are after performing the inner loop. def outer(y, N, x, M, origin, CellsCounter): if y < N: x = 0 (y, N, x, M, origin, CellsCounter) = inner(y, N, x, M, origin, CellsCounter) return outer(y + 1, N, x, M, origin, CellsCounter) else: return (y, N, x, M, origin, CellsCounter) Now let's pretty some stuff up. First, notice that the value x is never changed between calls to outer so let's eliminate that variable from outer It also won't get us def outer(y, N, M, origin, CellsCounter): if y < N: (y, N, x, M, origin, CellsCounter) = inner(y, N, x, M, origin, CellsCounter) return outer(y + 1, N, M, origin, CellsCounter) else: return (origin, CellsCounter) Also, the caller of outer won't use y or N or x or M as passed into outer so let's avoid returning those. Let's look at inner some more. def inner(y, N, x, M, origin, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, N, x + 1, M, origin, CellsCounter) else: return (y, N, x, M, origin, CellsCounter) our caller doesn't need us to tell it what y, x, N and M are after we finish our loop iteration so let's not bother returning those values. def inner(y, N, x, M, origin, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, N, x + 1, M, origin, CellsCounter) else: return (origin, CellsCounter) Notice that we no longer use N anywhere so we can eliminate that too. def inner(y, x, M, origin, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, x + 1, M, origin, CellsCounter) else: return (origin, CellsCounter) So our two functions that do recursion are def outer(y, N, M, origin, CellsCounter): if y < N: (origin, CellsCounter) = inner(y, x, M, origin, CellsCounter) return outer(y + 1, N, M, origin, CellsCounter) else: return (origin, CellsCounter) def inner(y, x, M, origin, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, x + 1, M, origin, CellsCounter) else: return (origin, CellsCounter) Now the only variables that "change" between loops are x, y, and CellsCounter so we can use nested functions to avoid passing those as inputs (and because origin doesn't change we can avoid returning that too. def big(N, M, origin): def outer(y, CellsCounter): if y < N: CellsCounter = inner(y, x, CellsCounter) return outer(y + 1, CellsCounter) else: return CellsCounter def inner(y, x, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(y, x + 1, CellsCounter) else: return CellsCounter return outer(y=0, CellsCounter=0) And likewise if we do another nested definition, inner never changes y so it can just be a closure capturing y from outer. def big(N, M, origin): def outer(y, CellsCounter): def inner(x, CellsCounter): if x < M: if origin[x][y] == 1 and CellsMap[x][y] == 0: CellsCounter += 1 DiscoverCells(origin, x, y, CellsCounter) return inner(x + 1, CellsCounter) else: return CellsCounter if y < N: CellsCounter = inner(x=0, CellsCounter) return outer(y + 1, CellsCounter) else: return CellsCounter return outer(y=0, CellsCounter=0)
2 of 3
1
To all following commenters: please, do not bring up the old circlejerk jokes/memes about recursion ("Understanding recursion...", "This is recursion...", etc.). We've all heard them n+2 too many times. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
Top answer
1 of 2
2

Have a look at your loops, i.e. how they are related to each other. As an example let's take the 1st and 2nd:

for (int a = 0; a < N; a++) {      
    for (int b = a + 1; b < N; b++) {      

As you can see each loop uses 3 values/variables:

  • the loop variable (a, b), let's call it x
  • the maximum value N
  • an initial value (0, a + 1), let's call it start

Thus both loops could be rewritten as

for (int x = start; x < N; x++ ) { ... }

Now put that into a method and add a condition for the recursion:

void runInnerLoop( int start, int N) {
  for (int x = start; x < N; x++ ) { 
    runInnerLoop( x + 1, N );
  }  
}

Note that in your case you'd need to also pass the list of strings as a parameter and add a string to it, either before of after the recursion.

Also note that I didn't include any additional check whether to do the recursive call or not. That way you'd eventually end up with start == N but the loop condition would take take of that. Adding a condition like if( x < N - 1 ) would prevent an unnecessary recursive call at the cost of additional condition evaluation. Which option would be faster remains to be seen but since that's probably not really relevant I'd opt for the easier to read version.

However, since you're current learing recursion: keep in mind to always check whether the abort condition can be reached in all cases or not. Otherwise you'd run into StackOverflowError etc. - which could also happen if your N is too big in which case you'd need a different approach.

Edit:

I must admit that I overlooked a piece of information in your question, i.e. there is a limited recursion depth which you called M. Thus I'll expand my answer with that information and I'll also explain how to get the "lists" you want to print.

Basically handling the recursion depth is easy: you pass the current depth + 1 to each call as well as the maximum depth and before doing a recursive call you check for depth < maxDepth - if this is true you do a recursice call, if it is false you print the current branch (i.e. the "list" of integers).

Handling the lists isn't that hard but doing it efficiently requires some thought. Basically each iteration adds a new list, i.e. 0,1,2 and 0,2,3 are different lists.

If you'd use lists you'd have to pass the current list to the recursive call and inside the loop create a new list, add all the values of the top list to it and finally add the current loop variable to it (e.g. List<Integer> list = new ArrayList<>( topList ); list.add(x);).

However, you only need the lists in the deepst calls, i.e. when printing or collecting them. This means all those intermediate lists are a waste of time and memory. So instead you might want to use a Stack to track the current loop values, i.e. at the start of an iteration you push the current value to the stack and remove the top value at the end of the iteration. That way you can reuse the same stack and print only the current loop variables (or collect them into a new list for later use).

Here's the top example using recursion depth and a stack:

void runInnerLoop( int start, int N, int depth, int maxDepth, Stack<Integer> stack) {    
  for (int x = start; x < N; x++ ) {
    stack.push( x ); //add the current value to the stack
    if( depth < maxDepth ) { //max depth not reached, do another recursion
      runInnerLoop( x + 1, N, depth + 1, maxDepth, stack );
    } else {
      System.out.println( stack ); //max depth reached, print now
    }
    stack.pop(); //remove the top value from the stack
  }  
}

The inital call for your first example (N=4, maxDepth=3) would look like this:

runInnerLoop( 0, 4, 1, 3, new Stack<>() );
2 of 2
0

Update 4

static List<List<Integer>> f(int init, int N, int depth, List<Integer> ls) {
    List<List<Integer>> all = new ArrayList<>();

    for(int i = init; i < N; i++) {
        List<Integer> ls_ = new ArrayList<Integer>();
        ls_.addAll(ls);
        ls_.add(i);
        if(depth == 0) {
            all.add(ls_);
        } else {
            all.addAll(f(i + 1, N, depth-1, ls_));
        }
    }

    return all;
}

Original

Without spoiling too much maybe this helps you:

for (int i = 0; i < 10; i++)
        System.out.println(i);

is semantically the same as:

public static void f(final int i) {
    if (i < 10) {
        System.out.println(i);
        For.f(i + 1);
    }
}

You will also notice that:

while(i < 10) {
  System.out.println(i);
  i++;
}

is basically the same thing and can be translated to recursion the same way.

I wouldn't recommend coding like this but you can rewrite every for-loop to a recursive function this way. for loops don't consume as much stack space.

When you nest for loops you can translate them using the same algorithm:

for (int x = 0; x < 3; x++)
        for (int y = 0; y < 3; y++)
            System.out.println(x + "," + y);

becomes two functions f,g:

public static void f(final int x) {
    if (x < 3) {
        For.g(x, 0);
        For.f(x + 1);
    }
}

public static void g(final int x, final int y) {
    if (y < 3) {
        System.out.println(x + "," + y);
        For.g(x, y + 1);
    }
}

Update

To answer the comments:

It doesn't matter how many for-loops you have nested. Every for-loop can be rewritten as a recursive function. If you have N nested for-loops you can rewrite them to N recursive functions. The method is as follow:

If you have for(TYPE i = INIT; CONDITION; P-EXPRESSION) { CODE } you can translate it to:

function NAME(TYPE i) {
   if(CONDITION) {
     CODE
     P-EXPRESSION
     NAME(i); //this is the recursive call
   }
}

NAME(INIT)

If you have nested for-loops the method is the same but you have to pass local variables as parameters.

for(int a = INIT_A; CONDITION_A; P-EXPRESSION_A) {
  CODE_A
  for(int b = INIT_B; CONDITION_B; P-EXPRESSION_B) {
    CODE_B
    //^- if you use a in this you have to pass a as a parameter
    for(int c = INIT_C; CONDITION_C; P-EXPRESSION_C) {
      CODE_C
      //^- same deal
    }
  }
}

Becomes roughly (pseudo-code):

function f(int a) {
  if(CONDITION_A) {
    CODE_A
    g(a, INIT_B);
    P-EXPRESSION_A
    f(a);
  }
}

function g(int a, int b) {
  if(CONDITION_B) {
    CODE_B
    h(a,b, INIT_C);
    P-EXPRESSION_B
    g(a, b);
  }
}

function h(int a, int b, int c) {
  if(CONDITION_C) {
    CODE_C
    P-EXPRESSION_C
    h(a,b,c);
  }
}

f(INIT_A)

Update 2

The direct 1:1 translation using the above method gives you:

public static List<String> f(int a, int N, List<String> stringList) {       
    if(a < N) {
        g(a, a + 1, N, stringList);
        f(a + 1, N, stringList);
    }
    return stringList;
}

public static List<String> g(int a, int b, int N, List<String> stringList) {
    if(b < N) {
        h(a, b, b+1, N, stringList);
        g(a, b+1, N, stringList);
    }
    return stringList;
}

public static List<String> h(int a, int b, int c, int N, List<String> stringList) {
    if(c < N) {
        String str = " ( " + Integer.toString(a)
        + " , " + Integer.toString(b)
        + " , " + Integer.toString(c) +" ) ";
            stringList.add(str);
        h(a, b, c+1, N, stringList);
    }
    return stringList;
}

It's not beautiful/optimal code but it's a translation of each for-loop to a recursive function.

Update 3

A nicer translation would have the form:

h a b c n
 |c < n = (a,b,c) : h a b (succ c) n
 |otherwise = []

g a b n
 |b < n = h a b (succ b) n ++ g a (succ b) n
 |otherwise = []

f a n
 |a < n = g a (succ a) n ++ f (succ a) n
 |otherwise = []

main = print $ f 0 4

but this would translate to java as:

public static List<String> f(int a, int N) {        
    if(a < N) {
        List<String> ls = new ArrayList<String>();

        ls.addAll(g(a, a + 1, N));
        ls.addAll(f(a + 1, N));

        return ls;
    }
    return new ArrayList<String>();
}

public static List<String> g(int a, int b, int N) {


    if(b < N) {

        List<String> ls = new ArrayList<String>();
        ls.addAll(h(a,b,b+1,N));
        ls.addAll(g(a,b+1,N));


        return ls;
    }
    return new ArrayList<String>();
}

public static List<String> h(int a, int b, int c, int N) {
    if(c < N) {
        String str = " ( " + Integer.toString(a)
        + " , " + Integer.toString(b)
        + " , " + Integer.toString(c) +" ) ";

        List<String> ls = new ArrayList<String>();
        ls.add(str);
        ls.addAll(h(a,b,c+1,N));

        return ls;
    }
    return new ArrayList<String>();
}

Which is not efficient Java :).

🌐
Coderanch
coderanch.com › t › 543269 › Recursion-Nested-loops
Recursion vs Nested loops. (Programming Diversions forum at Coderanch)
this forum made possible by our volunteer staff, including ... ... I was writing an algorithm to find unique objects in a array using Java. I have written two methods one is recursive and other is having nested loops. According to the time taken recursive is quite slow and also its takes more memory because each recursion will have a new stack allocated to the method.
🌐
Refactoring
refactoring.com › catalog › replaceIterationWithRecursion.html
Replace Iteration with Recursion - Refactoring
Formal methods folks use the term "loop-invariant" to describe the condition that exists as the result of each iteration. An invariant can be added to code as either comments or assertions. The use of good identifier names can often reduce the need for this type of comment. But in the example above, there are no appropriate identifiers to name -- and do you really want to introduce a temp? The solution is to replace the iteration with recursion...
Find elsewhere
Top answer
1 of 2
49

Actually you should break the function down first:

A loop has a few parts:

  1. the header, and processing before the loop. May declare some new variables

  2. the condition, when to stop the loop.

  3. the actual loop body. It changes some of the header's variables and/or the parameters passed in.

  4. the tail; what happens after the loop and return result.

Or to write it out:

foo_iterative(params){
    header
    while(condition){
        loop_body
    }
    return tail
}

Using these blocks to make a recursive call is pretty straightforward:

foo_recursive(params){
    header
    return foo_recursion(params, header_vars)
}

foo_recursion(params, header_vars){
    if(!condition){
        return tail
    }

    loop_body
    return foo_recursion(params, modified_header_vars)
}

Et voilà; a tail recursive version of any loop. breaks and continues in the loop body will still have to be replaced with return tail and return foo_recursion(params, modified_header_vars) as needed but that is simple enough.


Going the other way is more complicated; in part because there can be multiple recursive calls. This means that each time we pop a stack frame there can be multiple places where we need to continue. Also there may be variables that we need to save across the recursive call and the original parameters of the call.

We can use a switch to work around that:

bar_recurse(params){
    if(baseCase){
        finalize
        return
    }
    body1
    bar_recurse(mod_params)
    body2
    bar_recurse(mod_params)
    body3
}


bar_iterative(params){
    stack.push({init, params})

    while(!stack.empty){
        stackFrame = stack.pop()

        switch(stackFrame.resumPoint){
        case init:
            if(baseCase){
                finalize
                break;
            }
            body1
            stack.push({resum1, params, variables})
            stack.push({init, modified_params})
            break;
        case resum1:
            body2
            stack.push({resum2, params, variables})
            stack.push({init, modified_params})
            break;
        case resum2:
            body3
            break;
        }
    }
}
2 of 2
2

Following up on @ratchet freak's answer, I created this example of how the Fibonacci function can be rewritten to a while loop in Java. Note that There's a much simpler (and efficient) way to rewrite the Fibonacci with a while loop though.

class CallContext { //this class is similar to the stack frame

    Object[] args;

    List<Object> vars = new LinkedList<>();

    int resumePoint = 0;

    public CallContext(Object[] args) {
        this.args = args;
    }

}


static int fibonacci(int fibNumber) {
    Deque<CallContext> callStack = new LinkedList<>();
    callStack.add(new CallContext(new Object[]{fibNumber}));
    Object lastReturn = null; //value of last object returned (when stack frame was dropped)
    while (!callStack.isEmpty()) {
        CallContext callContext = callStack.peekLast();
        Object[] args = callContext.args;
        //actual logic starts here
        int arg = (int) args[0];
        if (arg == 0 || arg == 1) {
            lastReturn = arg;
            callStack.removeLast();
        } else {
            switch (callContext.resumePoint) {
                case 0: //calculate fib(n-1)
                    callStack.add(new CallContext(new Object[]{arg - 1}));
                    callContext.resumePoint++;
                    break;
                case 1: //calculate fib(n-2)
                    callContext.vars.add(lastReturn); //fib1
                    callStack.add(new CallContext(new Object[]{arg - 2}));
                    callContext.resumePoint++;
                    break;
                case 2: // fib(n-1) + fib(n-2)
                    callContext.vars.add(lastReturn); //fib2
                    lastReturn = (int) callContext.vars.get(0) + (int) callContext.vars.get(1);
                    callStack.removeLast();
                    break;
            }
        }
    }
    return (int) lastReturn;
}
🌐
Fssnip
fssnip.net › 80A › title › Nested-Recursive-Loop
Nested Recursive Loop | F# Snippets
Nested recursive loop which has certain uses cases for loop optimization when you don't want to traverse across entire ranges but rather subsets incrementally and decrementally etc.
🌐
Google Sites
sites.google.com › site › samsoninfinite › c-programs › recursive-functions › nested-for-loop-as-recursion
Samson in Finite - Nested for loop as recursion
In the above code there are 4 loops are nested, if we want a result of say 5 nested loop then we have to modify the code to add 5 loop. Lets say for 10 nested for loops, once again we have to modify the source code to add 10 loops which will be very difficult to implement and keep track of. The recursive solution below can handle any number of nested for loop by simple recursion.
🌐
University of Illinois
courses.grainger.illinois.edu › cs173 › sp2021 › ALL-lectures › lectures › algorithms3.html
CS173 Lectures
We'll define our input size n to be the sum of their lengths. There are two recursive calls in the code but only one of them is called each time we go through the function. All the other steps in the function take constant time. So we can set up a recursive running time formula like this:
Top answer
1 of 3
5

A loop like:

for (int i=0; i<n; i++) {
    func(i);
}

can be translated to recursion as:

void rec_fun(int i,int n) {
    if (!(i<n)) return;
    func(i);
    rec_fun(i+1,n);
}
...
rec_fun(0,n);

So:

for (i = 0; i < q; i++) { // I have convert this to recursion.
    for (j = 0; j < p; j++) {
        for (k = 0; k < r; k++) {
            if (b[i] >= a[j] && b[i] >= c[k]) {
                sum += f(a[j], b[i], c[k]);
            }
        }
    }
}

can be translated as:

void rec_k(int k,int r,int i,int j) { // k-loop
    if (!(k<r)) return;
    if (b[i] >= a[j] && b[i] >= c[k]) {
        sum += f(a[j], b[i], c[k]);
    }
    rec_k(k+1,r,i,j); // recurse
}

void rec_j(int j,int p,int i,int r) { // j-loop
    if (!(j<p)) return;
    rec_k(0,r,i,j); // inner loop
    rec_j(j+1,p,i,r); // recurse
}

void rec_i(int i,int q,int p,int r) { // i-loop
    if (!(i<q)) return;
    rec_j(0,p,i,r); // inner loop
    rec_i(i+1,q,p,r); // recurse
}
...
rec_i(0,q,p,r);

I'm not sure this is either more readable or useful, but it meets your initial needs.

2 of 3
1

Let us assume that the intention of this code is to only calculate the sum.

You can make a function as

int recurse_sum(int i, int j, int k) {
      int res = .... // Logic for calculating sum for these indices i, j, k.
      k++;
      if (k==r) {
          k = 0;
          j++;
      }
      if(j==p){
          j=0;
          i++;
      }
      if(i==q){
          return res;
      }
      return res + recurse_sum(i,j,k);
}

Now you can just call with recurse_sum(0,0,0); The rest of the parameters can either be made global or just passed along with i,j,k.

I hope this helps.

Edit:

As mentioned by @dlasalle this code can be made open to tail call recursion optimization by placing the call at the end of the function.

In that case you can have the following version.

int recurse_sum(int i, int j, int k, int sum) {
      int res = .... // Logic for calculating sum for these indices i, j, k.
      k++;
      if (k==r) {
          k = 0;
          j++;
      }
      if(j==p){
          j=0;
          i++;
      }
      if(i==q){
          return res + sum;
      }
      return recurse_sum(i,j,k,res+sum);
}

Here the function ends with returning the value from the inner call and hence can be easily optimized.

Ofcourse in this case it will have to be called as recurse_sum(0,0,0,0);

Top answer
1 of 2
1

This maybe

def do_step(item, position_dict, depth):
    print position_dict

    if depth > 0:           
        new_positions = available_pos(item, position_dict)

        for (x, y) in new_positions:
            position_dict[item] = (x, y)

            for next_item in ['a', 'b', 'c', 'd']:
                do_step(next_item, position_dict.copy(), depth - 1)

You call do_step('a', position_dict.copy(), 10). position_dict was given.

This is the non-functional version which should run faster

def do_step(item, position_dict, depth):
    print position_dict

    if depth > 0:   
        old_position = position_dict[item]        
        new_positions = available_pos(item, position_dict)

        for (x, y) in new_positions:
            position_dict[item] = (x, y)

            for next_item in ['a', 'b', 'c', 'd']:
                do_step(next_item, position_dict, depth - 1)

        # Restore the old position  
        position_dict[item] = old_position
2 of 2
0

Recursion is the way to go here. Since you're doing the same thing multiple times, it's only natural to write a function to do it.

Let's start with a non-recursive function. It could look like this:

def update_pos(item):
    ava1 = available_pos(item, position_dict)

    for a in ava1:
        position_dict[item] = a
        # but now what? we need to update the next item's location

This updates 1 item's position, so the next step is to make it update multiple items' positions. So instead of passing a single item, we'll pass it a list of items.

def update_pos(items_): # I called it items_ to avoid a name clash with the global items list
    item= items_[0]
    ava1 = available_pos(item, position_dict)

    for a in ava1:
        position_dict[item] = a
        #recursively update the remaining items' positions
        if len(items_) > 1:
            update_pos(items_[1:])

All that's left to do now is to actually produce a result:

def update_pos(items_):
    item= items_[0]
    ava1 = available_pos(item, position_dict)

    for a in ava1:
        position_dict[item] = a
        #recursively update the remaining items' positions
        if len(items_) > 1:
            update_pos(items_[1:])
        else:
            pos.append([position_dict[i] for i in items])

I didn't test this code, but it should at least give you an idea how to solve your problem.

🌐
freeCodeCamp
forum.freecodecamp.org › javascript
Nested Loops and Recursive Functions - JavaScript
March 2, 2021 - these two concepts are making knots on my mind. Specially recursive functions. What were the examples of codes and/or analogies that worked best FOR YOU personally and made it click?
🌐
i-Programmer
i-programmer.info › ebooks › 34 › 343-recursion.html
Recursion
Programming book reviews, programming tutorials,programming news, C#, Ruby, Python,C, C++, PHP, Visual Basic, Computer book reviews, computer history, programming history, joomla, theory, spreadsheets and more.
Top answer
1 of 4
4

You have a single little error in your code:

You call a recursive function from your i + 1, but not your index + 1.
It causes index to be equal not current array index but it's value.

For example, when you passed [0, 1, 2], your data now is [0, 1] and you are about to insert 3, you call loop(3 + 1), index 4 goes out of an array range. if (index === end) condition fails and it doesn't output. for (var i = index; i < len; i++) loop fails as well, and everything is going wrong.

It should be:

var len = 4;
var end = 3;
var data = [];

var loop = function (index) {
  if (index === end) {
    console.log(data);
    return;
  }
  for (var i = index; i < len; i++) {
    data[index] = i;
    loop(index + 1); // <--- HERE
  }
}

loop(0);

Here is the working JSFiddle demo.

Update:

Oh, now I see. You need a[i] > a[i-1] condition to be true for all combinations. Just add a start variable which will save the last inserted value in order to comply with this rule.

var len = 4;
var end = 3;
var data = [];

var loop = function (start, index) {
  if (index === end) {
    document.body.innerHTML += "<br/>" + data;
    return;
  }
  for (var i = start; i < len; i++) { // We start from 'start' (the last value + 1)
    data[index] = i;
    loop(i + 1, index + 1); // Here, we pass the last inserted value + 1
  }
}

loop(0, 0); // At beginning, we start from 0

Updated JSFiddle demo with passing argument.

You can check the previous value instead of passing a value as an argument if it looks wrong for you. Condition will be like "if it is a first number, start from 0; else - start from the next number after the previous one".

var start = (index === 0 ? 0 : data[index-1] + 1);  

Updated JSFiddle demo with calculating start.

2 of 4
3

There are a couple of errors; you are recursing starting from i+1 instead of index+1 and you are counting from index instead of counting from data[index-1]+1.

The corrected version is:

var len = 4;
var end = 3;
var data = [];

var loop = function (index) {
  if (index === end) {
    console.log(data);
    return;
  }
  for (var i = (index==0 ? 0 : data[index-1]+1); i < len; i++) {
    data[index] = i;
    loop(index + 1);
  }
}
Top answer
1 of 2
2

This is not a recursion problem, it's an "async problem." Your issue is that NodeJS access memcached asynchronously and your procedural style code does not. So, you need to think about the problem differently.

function getMemcacheData(key, data)
{
    DB.get(key, function(err, result)
    {
        if (err) return false;

        data[ key ] = result;
    })
}

var oData = {};

for (var x = startX; x <= endX; x++)
{
    for (var y = startY; y <= endY; y++)
    {
        var key = x + "_" + y;
        getMemcacheData(key, oData);
    }
}

That will work, but - you have another problem then. You have no way of knowing when your MemcacheD data has been loaded into oData, you just have to sit and wait and guess. There are ways to deal with this; but my favorite way is to use a library named async.

With async, you could do this:

var syncStack = [],
    oData = {};

for (var x = startX; x <= endX; x++)
{
    for (var y = startY; y <= endY; y++)
    {
        (function(key)
        {
            syncStack.push(function(callback)
            {
                DB.get(key, function(err, result)
                {
                    /** If you don't care about data not being loaded 
                    you do this: */
                    if (!err)
                    {               
                        data[ key ] = result;
                    }

                    callback();

                    /** If you do care, and you need to terminate if 
                    you don't get all your data, do this: */
                    if (err)
                    {
                        callback(err);
                        return false;
                    }

                    data[ key ] = result;

                    callback();
                })                    
            });
        })(x + "_" + y);  
    }
}

async.parallel(syncStack, function(error)
{
    //this is where you know that all of your memcached keys have been fetched.
    //do whatever you want here.

    //if you chose to use the 2nd method in the fetch call, which does
    //"callback(error)" error here will be whatever you passed as that
    //err argument
});

What this code is actually doing is creating an array of functions, each of which calls the Db.get method for a specific key, and adds the result to the oData variable.

After the array of functions is created, we use the async library's parallel method, which takes an array of functions and calls them all in parallel. This means that your code will send a bunch of requests off to memcached to get your data, all at once. When each function is done, it calls the callback function, which tells the async lib that the request finished. When all of them are finished, async calls the callback closure you supplied as the 2nd argument in the call to the parallel method. When that method is called, you either know A. something went wrong, and you have the error to recover from it or B. all requests are finished, and you may or may not have all the data you requested (expired or stale keys requested, or whatever). From there, you can do whatever you want, knowing you have finished asking for all the keys you needed.

I hope this helps.

2 of 2
0

parallel get:

function loadPoints(cb)
{
  var oData = {};
  for( x = startX; x <= endX; x++ )
  {
    for( y = startY; y <= endY; y++ )
    {
       var key = x + '_' + y;     
       num_points++;
       Db.get(key, function(err, val) {
         if (err)
           return cb(err);

         oData[key] = val;
         num_points--;
         if (num_points === 0)
            cb(null, oData);         
       });
    } 
  }
}

sequential get:

function loadPoints(cb)
{
   var oData = {};

   function loadPoint(x, y)
   {
      var key = x + '_' + y;
      Db.get(key, function(err, val) {
         if (err)
           return cb(err);
         oData[key] = val;
         if (x + 1 < endX)
            return loadPoint(x + 1, y);
         else if (y + 1 < endY)
            return loadPoint(startX, y+1);
         else
            cb(null, oData);
      });
   }
   loadPoint(startX, startY);
}
🌐
MathWorks
mathworks.com › matlabcentral › answers › 367320-how-to-make-recursive-for-loop
How to make recursive for loop - MATLAB Answers - MATLAB Central
November 16, 2017 - I recommend the "odometer" pattern when the number of for loops must be handled dynamically. https://www.mathworks.com/matlabcentral/answers/357969-using-recursive-function-to-calculate-all-possible-peptide-combinations#answer_282766