Re: Combination problem


From           Greg Nelson <greg_nelson@INTERNET.GALLUP.COM>
Date           Wed, 10 Apr 1996 13:00:19 CST
Newsgroups     comp.soft-sys.sas
Message-ID     <9603108291.AA829166686@internet.gallup.com>

     Subject:       Combination problem
     Summary:       Macro to obtain the combinations and permutations of n
                    items taken k at a time.  Original source from SAS
                    Communications.
     Author:        mcgowan1@niehs.nih.gov at Internet
     Respondent:    Greg Barnes Nelson <gnelson@gallup.com



     If I understand the problem correctly, you want all the possible
     permutations of the 5 numbers (in thise case 5).  If this is tryuly
     your problem, here is a macro that will help....taken from SAS
     communications a long time ago...


     --greg barnes nelson


     /* Macro to get all the combinations or permutations of n items taken
        k at a time....

        greg barnes nelson gnelson@gallup.com

     */


     %macro permute(r) / parmbuff;      /* the parmbuff option assigns */
       %let i=2;                /* the invocation parameter listto the */
       %let things=;                       /* macro variable &syspbuff */
       %do %while (%scan(&syspbuff,&i) ne );      /* scan the syspbuff */
         %let p&i="%scan(&syspbuff,&i)";             /* to determine r */
         %if &i=2 %then %let things=&&p&i;      /* and count thenumber */
         %else %let things=&things,&&p&i;            /* of elements, n */
         %let i=%eval(&i+1);
       %end;
       %let n=%eval(&i-2);

       Data permute;
          drop i j copy;
          array check (*) $ 10 r1-r&r;          /* create a total of r */
           %do m=1 %to &r;                   /* variables  for looping */
             do r&m = &things;
           %end;
           copy=0;
             do i=2 to &r;                 /* look for duplicate items */
               do j=1 to i-1;              /* and keep the unique ones */
                 if check(j)=check(i) then copy+1;
               end;
             end;
           if copy = 0 then output;        /* writes to a SAS dataset */
           if copy = 0 then put r1-r&r;        /* writes to the log   */
           %do m=1 %to &r;
            end;                               /* end the r DO LOOPS  */
           %end;
         run;

     Proc print uniform data=permute;
             title "Permutations of &n items taken &r at a time";
             run;
      %mend permute;



     %macro combo(r)/parmbuff;
       %let i=2;
       %let things=;
       %do %while (%scan(&syspbuff,&i) ne );
        %let p&i="%scan(&syspbuff,&i)";
         %if &i=2 %then %let things=&&p&i;
        %else %let things=&things,&&p&i;
         %let i=%eval(&i+1);
       %end;
        %let n=%eval(&i-2);
      data combo;
             keep v1-v&r;
             array word $8  w1-w&n (&things);
             array rr (*) r1-r&r;
             array v $8  v1-v&r;
            %do i=1 %to &r;                    /* create the DO LOOPS */
              %if &i=1 %then %do;
                do r&i=1 to &n-(&r-&i);
                %end;
              %else %do;
                do r&i=r%eval(&i-1)+1 to &n-(&r-&i);
                %end;
              %end;
                do k=1 to &r;              /* select subscripted items */
                v(k)=word (rr(k));               /* for a SAS dataset  */
                put v(k)      '  ' @;                       /*for log  */
                end;
                put;                                  /* writes to log */
                output;                    /* writes to a SAS dataset  */
            %do i=1 %to &r;
              end;                     /* create ENDs for the DO LOOPS */
              %end;
             put;
             run;
     Proc print uniform data=combo;
             title "Combinations of &n items taken &r at a time";
             run;
        %mend combo;


     run;


     %combo(5,1,2,3,4,5);
     %permute(5,1,2,3,4,5);