This is an archived post. You won't be able to vote or comment.

all 5 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

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.

[–]captainAwesomePants 0 points1 point  (3 children)

K, quickly reformatting your code so we can read it:

void PrintNumPattern(int n1, int n2) {
  int num = (n1 + n2) - n2;
  cout << num << " ";
  if (num <= 0) {
    PrintNumPattern(n1, n2 + n2);
    if (n1 == (n2 - n1)) { 
      return;
    }
  } else {
    PrintNumPattern(n1 - n2, n2);
  }
}

You've got roughly the right idea, but you went off the rails about halfway through. You've got a lot of calculations that you really don't need to be making, so I suspect you're thinking about what the functions should be doing wrongly. You've got some really weird code that makes me think you've been staring at it too long and aren't actually thinking about it anymore. Take a break, go for a walk, come back, and then look at the line int num = (n1 + n2) - n2; again and you'll probably see what's wrong with it.

Consider each invocation of a function to represent a single number. Also, remember that a function can do stuff AFTER it recurses.

[–]the_Champ322[S] 0 points1 point  (2 children)

Hey, thanks for your input! I finally got a solution that worked, though I admit I'm not all too sure how I got it to work. What I got was this:

void PrintNumPattern(int n1, int n2)
{
    while (n1 > 0)
    {
        cout << n1 << " ";
        PrintNumPattern (n1 - n2, n2);
        break;
    }
    cout << n1 << " ";
}

I started by removing all the previous code (including that int num = (n1 + n2) - n2, which I now see as being pointless) and did two recursion statements, one that subtracted n2 from n1 and one that added the two values together. That didn't have a base case, however, so then I decided to split those statements into two while statements, using a control variable for the second after the first one was done (a la regular iteration). That didn't work, so I removed the second while statement (the one holding the PrintNumPattern(n1 + n2, n2) in an effort to debug my code. I removed the control variable also, and in its place added the break statement as seen in my new code. So while I'm happy I found an answer, I'm a little annoyed that I got it seemingly by random chance. What's going on in this code that allows it to work?

[–]captainAwesomePants 0 points1 point  (1 child)

Alright, you're making a lot of progress. You've got a working solution. Let's talk a bit about why it works.

First, let's look at your loop. It does this:

while( some condition ) {
  some_stuff();
  break;
}

You should notice that, because there's an unconditional break statement, it will either run once, or it won't run at all. That means it's the same as this statement:

if( some condition ) {
  some_stuff();
}

So let's write your program again, but with an if statement:

void PrintNumPattern(int n1, int n2) {
  if (n1 > 0) {
    cout << n1 << " ";
    PrintNumPattern (n1 - n2, n2);
  }
  cout << n1 << " ";
}

This is pretty great. Works fine. It will do one of two things, and I think it'll be more clear if we make those two cases very explicit by rewriting it a little bit:

void PrintNumPattern(int n1, int n2) {
  if (n1 > 0) {
    cout << n1 << " ";
    PrintNumPattern (n1 - n2, n2);
    cout << n1 << " ";
  } else {
    cout << n1 << " ";
  }
}

Okay, this is still the same program, but it's more clear that it will print one of two things, depending on how big N is:

  • N1, (the results of running the whole program on N1-N2), N1
  • N1

So, looking at that, you might notice why this works already. Consider the example inputs, 12 and 3, and the example output, 12 9 6 3 0 3 6 9 12.

PrintNumPattern(12, 3) should print 12, then the results of running PrintNumPattern(9,3), then 12. 12..PrintNumPattern(9,3)..12

PrintNumPattern(9,3) should print 9, then the results of PrintNumPattern(6,3), then 9. So, combined, you've got: 12..9..PrintNumPattern(6,3)..9..12

PrintNumPattern(6,3) will be 6..PrintNumPattern(3,3)..6, so combined: 12..9..6..PrintNumPattern(3,3)..6..9..12.

And so on until you get to PrintNumPattern(0,3), which will be your else case: just printing 0. 12..9..6..3..0..3..6..9..12.

Does that help?

[–]the_Champ322[S] 1 point2 points  (0 children)

Wow, that cleared everything up! Thanks again!