Search code examples
recursionfortrannested-loops

How to make recursive nested loops which use loop variables inside?


I need to make a nested loop with an arbitrary depth. Recursive loops seem the right way, but I don't know how to use the loop variables in side the loop. For example, once I specify the depth to 3, it should work like

count = 1 
for i=1, Nmax-2
    for j=i+1, Nmax-1
        for k=j+1,Nmax
            function(i,j,k,0,0,0,0....) // a function having Nmax arguments
            count += 1
        end
    end
end

I want to make a subroutine which takes the depth of the loops as an argument.

UPDATE:

I implemented the scheme proposed by Zoltan. I wrote it in python for simplicity.

count = 0;

def f(CurrentDepth, ArgSoFar, MaxDepth, Nmax): 
    global count;
    if CurrentDepth > MaxDepth:
        count += 1;
        print count, ArgSoFar;
    else:
        if CurrentDepth == 1:
            for i in range(1, Nmax + 2 - MaxDepth):
                NewArgs = ArgSoFar;
                NewArgs[1-1] = i;
                f(2, NewArgs, MaxDepth, Nmax);
        else:
            for i in range(ArgSoFar[CurrentDepth-1-1] + 1, Nmax + CurrentDepth - MaxDepth +1):
                NewArgs = ArgSoFar;
                NewArgs[CurrentDepth-1] = i;
                f(CurrentDepth + 1, NewArgs, MaxDepth, Nmax);

f(1,[0,0,0,0,0],3,5)

and the results are

1 [1, 2, 3, 0, 0]
2 [1, 2, 4, 0, 0]
3 [1, 2, 5, 0, 0]
4 [1, 3, 4, 0, 0]
5 [1, 3, 5, 0, 0]
6 [1, 4, 5, 0, 0]
7 [2, 3, 4, 0, 0]
8 [2, 3, 5, 0, 0]
9 [2, 4, 5, 0, 0]
10 [3, 4, 5, 0, 0] 

There may be a better way to do this, but so far this one works fine. It seems easy to do this in fortran. Thank you so much for your help!!!


Solution

  • you can define your function to have a List argument, which is initially empty

    void f(int num,List argumentsSoFar){
    
      // call f() for num+1..Nmax
      for(i = num+1 ; i < Nmax ; i++){
        List newArgs=argumentsSoFar.clone();
        newArgs.add(i);
        f(i,newArgs);
      }
      if (num+1==Nmax){
         // do the work with your argument list...i think you wanted to arrive here ;)
      }
    
    }
    

    caveat: the stack should be able to handle Nmax depth function calls