DATA Step, Macro, Functions and more

output last iteration for i in a do loop

Accepted Solution Solved
Reply
Super Contributor
Posts: 413
Accepted Solution

output last iteration for i in a do loop

[ Edited ]

Hi,

 

I am trying to replicate a math problem (for more info see the 4 min video https://www.youtube.com/watch?v=m4CjXk_b8zo)

 

I am doing a loop for numbers 1 to 10. For each number, if it is even then it becomes number/2, and if it is odd then it becomes 3*number+1. I stop the loop for each number when the number becomes 4, and then I go to the next number.

For each number I want to count how many steps until the number becomes 4.  

 

 

 

Here is my code:

 

data problem;
do i = 1 to 10;
count = 0;
number = i;
  do while (number ne 4);
    if mod(number,2) = 0 then number = number/2;
    else number = 3*number +1;
    count = count +1;
    output; 
   end;
end;
run;           

I get the result that I want, but the output gives me all the steps for each i. Is it possible to get only the last step for each i?

 

 

Thanks!


Accepted Solutions
Solution
‎11-21-2016 11:43 PM
Super Contributor
Posts: 413

Re: output last iteration for i in a do loop

Strictly speaking, you are right that according to the video the number always reduced to 4 when the process was done in a supercomputer. 

To summarize for future readers, the solution is the one given by KSharp. It is basically what I did but the "output" is placed in a different stage which allows to output only the last iteration for each i:

 

data problem;
do i = 1 to 10;
count = 0;
number = i;
  do while (number ne 4);
    if mod(number,2) = 0 then number = number/2;
    else number = 3*number +1;
    count = count +1;
   end;
   output;
end;
run;  

Please note that the remark of Astounding is very important in that the code can potentally run an infinite loop if for a certain i the number never reaches 4, so in such a case it would be safe to modify the do while statement into a do statement such as "do k=1 to 5000 while (number ne 4);"

View solution in original post


All Replies
Valued Guide
Posts: 797

Re: output last iteration for i in a do loop

[ Edited ]

This program does what you ask, and write out the numeric sequence for each starting point:

 

data _null_;

  do I=1 to 10;

    count=0;

    put "Start=" I @;

    do N=I by 0 until (N=4);

      if mod(N,2)=0 then N=N/2;

      else N=1+3*N;

      put +(-1)',' N @;

      count+1;

    end;

    put  +3 count=;

  end;

run;

 

 

Sorry - misread your post.  I think you want the next_to_last value of N before N=4, and as you said you don't want the sequence:

 

data want (keep=START next_to_last count);

  do START=1 to 10;

    count=0;

    do N=START by 0 until (N=4);

      if mod(N,2)=0 then N=N/2;

      else N=1+3*N;

      count+1;

      next_to_last=coalesce(lag(n),start);

    end;

    put start= count= next_to_last=;

    output;

  end;

run;

Super Contributor
Posts: 413

Re: output last iteration for i in a do loop

Hi mkeintz,

 

thanks for the code, I didn't know that so much computation can be done with PUT.

 

Your first code does actually give the result that my code gets, its just that I want to have the last (and not before last) iteration for each i.

 

Thanks!

Valued Guide
Posts: 797

Re: output last iteration for i in a do loop

Then I don't understand what you mean by "the last iteration"? Since by definition of the problem the last iteration is N=4.
Super User
Posts: 5,099

Re: output last iteration for i in a do loop

You already got the right suggestion, moving the OUTPUT statement.  Here's one more, just on general principles.  

 

Your DO WHILE loop is dangerous.  What if the logic never arrives at NUMBER=4?  In theory, at least, you could be writing an infinite loop.  It would be safer to have two ways that the loop might end, such as:

 

do k=1 to 5000 while (number ne 4);

Valued Guide
Posts: 797

Re: output last iteration for i in a do loop

It's not dangerous in this case.  According to the youtube videa every starting number up to 2**60 has been test and will ultimately arrive at 1  (and the next step would be 4).

 

MK

Super User
Posts: 5,099

Re: output last iteration for i in a do loop

Don't take this seriously, but ...

 

You heard it on the internet, so it must be true?

Valued Guide
Posts: 797

Re: output last iteration for i in a do loop

In the case of this video,which reviewed the history of this problem, I am confident of the assertion - even though it was reported on the internet.

 

MK

Solution
‎11-21-2016 11:43 PM
Super Contributor
Posts: 413

Re: output last iteration for i in a do loop

Strictly speaking, you are right that according to the video the number always reduced to 4 when the process was done in a supercomputer. 

To summarize for future readers, the solution is the one given by KSharp. It is basically what I did but the "output" is placed in a different stage which allows to output only the last iteration for each i:

 

data problem;
do i = 1 to 10;
count = 0;
number = i;
  do while (number ne 4);
    if mod(number,2) = 0 then number = number/2;
    else number = 3*number +1;
    count = count +1;
   end;
   output;
end;
run;  

Please note that the remark of Astounding is very important in that the code can potentally run an infinite loop if for a certain i the number never reaches 4, so in such a case it would be safe to modify the do while statement into a do statement such as "do k=1 to 5000 while (number ne 4);"

Super User
Posts: 9,691

Re: output last iteration for i in a do loop

I like idea of @Astounding . Safety first. If any problem occurred in the code of LOOP ,that would lead to infinite iterative, you have to stop sas session by hand, that doesn't sound good .

Super User
Posts: 9,691

Re: output last iteration for i in a do loop

data problem;
do i = 1 to 10;
count = 0;
number = i;
  do while (number ne 4);
    if mod(number,2) = 0 then number = number/2;
    else number = 3*number +1;
    count = count +1;
   end;
   output;
end;
run;  
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 10 replies
  • 508 views
  • 8 likes
  • 4 in conversation