Doris
Doris

Reputation: 9

SAS for loop questions

Players from 1 to 50 are placed in a row in order. The coach said: "Odds number athletes out!" The remaining athletes re-queue and re-number. The coach ordered again: "Odds number athletes out!" In this way, there is only one person left at last. What number of athletes is he? What if the coach's keep ordering "Even number athletes out!" Who is left at the end?

I know it requires me to use loop in SAS to answer the question. But can only write code below:

data a;
do i=1 to 50;
output;
end;
run;

proc sql;
select i
from a 
where mod(i,2**5)=0;
quit;

But it won't work for keeping the last odd number athelete. Could you guys figure out a way to simulate this process by using loop? Thanks so much

Upvotes: 0

Views: 83

Answers (2)

Tom
Tom

Reputation: 51566

Just use algebra.

want = 2 ** floor( log2(n) );

So if you are starting with an arbitrary dataset you can find the one observation you need directly.

data want;
  point = 2**floor(log2(nobs));
  set a point=point nobs=nobs;
  output;
  stop;
  put i= ;
run;

Here is example using array showing how it works.

373   data test;
374     array x [15];
375     do index=1 to dim(x); x[index]=index; end;
376     do iteration=1 by 1 while(n(of x[*])>1);
377       do index= 2**(iteration-1) to dim(x) by 2**iteration ;
378         x[index]=.;
379       end;
380       put iteration=  (x[*]) (3.);
381     end;
382     do index=1 to dim(x) until(x[index] ne .);
383     end;
384     put index= x[index]= ;
385
386   run;

iteration=1   .  2  .  4  .  6  .  8  . 10  . 12  . 14  .
iteration=2   .  .  .  4  .  .  .  8  .  .  . 12  .  .  .
iteration=3   .  .  .  .  .  .  .  8  .  .  .  .  .  .  .
index=8 x8=8

Upvotes: 0

PeterClemmensen
PeterClemmensen

Reputation: 4937

@Doris welcome :-)

Try this. The Final_Player data set contains the number of the final player in the simulation.

Simply change the mod(N, 2) = 0 to = 1 for the even problem. Feel free to ask.

data _null_;
   dcl hash h(ordered : 'y');
   h.definekey('p');
   h.definedone();
   dcl hiter ih('h');
   
   dcl hash i(ordered : 'Y');
   i.definekey('id');
   i.definedone();
   dcl hiter ii('i');
    
   do p = 1 to 50;
      h.add();
   end;
   
   id = .;
   
   do while (h.num_items > 1);
   
      do _N_ = 1 by 1 while (ih.next() = 0);
         if mod(_N_, 2) = 1 then do;
            i.add(key : p, data : p);
         end;
      end;
      
      do while (ii.next() = 0);
         rc = h.remove(key : id);
      end;
      
      i.clear();
   
   end;
   
   h.output(dataset : 'Final_Player');
     
run;

Upvotes: 2

Related Questions