SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sasuser1000
Calcite | Level 5

I need to create a code that will give me the below , but in a generic way

here i have 3, 2 and 1  open slots that can be filled only with A or B. but this can change in the future to 4 slots and a,b,c,d,e as a filling options. so the code need to be generic.

Any  memory efficient idea on how to tackle this?

a a b

a b a

b a a

b b a

b a b

a b b

a b

b a

a

b

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

Why my code be changed? Is there some html sensitive word in my code?

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to &num ;
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i&num ;
%do j=1 %to &num ;
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen

Ksharp

View solution in original post

14 REPLIES 14
sasuser1000
Calcite | Level 5

Thanks, I saw it before but this is without returns, so chip can't appear twice..

                 permutations of 4 items taken 2 at a time

                           OBS    R1         R2

                           1    Chip       Pete

                           2    Chip       Mike

                           3    Chip       William

                           4    Pete       Chip

                           5    Pete       Mike

                           6    Pete       William

                           7    Mike       Chip

                           8    Mike       Pete

                           9    Mike       William

                          10    William    Chip

                          11    William    Pete

                          12    William    Mike

art297
Opal | Level 21

Why not?  You would just have to roll the permutations macro into a driver macro that accomplishes each level.  I'm not sure how you want the final file, but that could easily be accomplished with proc append.

Try, e.g.,

%macro permute(r) / parmbuff;      /* the parmbuff option assigns */

%let i=2;               /* the invocation parameter list to the */

%let things=;                       /* macro variable &syspbuff */

%do %while (%Qscan(&syspbuff,&i,%STR(,%))) ne );  /* scan the syspbuff */

    %let p&i="%Qscan(&syspbuff,&i,%STR(,%)))";  /* to determine r */

   %if &i=2 %then %let things=&&p&i;     /* and count the number */

   %else %let things=&things,&&p&i;            /* of elements, n */

   %let i=%eval(&i+1);

%end;

%let n=%eval(&i-2);

data permute&r;

    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 data set */

     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;

%mend permute;

%macro allperms(k);

  %do L=1 %to &k.;

    %permute(&L.,a,b,c)

  %end;

%mend allperms;

%allperms(3)

sasuser1000
Calcite | Level 5

Thanks but what i reaaly need is returns

the code give this

r1r2r3
abc
acb
bac
bca
cab
cba

but what i do not understand is how to do this on top of the above

a a a

a a b

a b b

a c c...etc

art297
Opal | Level 21

If the following does what you want, then it would be easy to expand it to automatically account for the duplicates:

%permute(1,a,b,c)

%permute(2,a,a,b,b,c,c)

%permute(3,a,a,a,b,b,b,c,c,c)

Ksharp
Super User

I don't understand why not like be:

aaa

bbb

a a b

a b a

b a a

b b a

b a b

a b b

a b

b a

aa

bb

a

b

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to #
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i#
%do j=1 %to #
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen



Ksharp

sasuser1000
Calcite | Level 5

Thanks Ksharp but  I get this error when running the code, I think it's related to this "#" I am not sure I fully understand how the code works, so I don't know to which number should I input there

Ksharp
Super User

Why my code be changed? Is there some html sensitive word in my code?

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to &num ;
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i&num ;
%do j=1 %to &num ;
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen

Ksharp

sasuser1000
Calcite | Level 5

Thanks so much!

art297
Opal | Level 21

KSharp,

While the OP appears to be satisfied with the code, I don't think it does exactly what the OP had asked for.  It appears to leave off the two and three-way same combinations like:

aaa

aa

bbb

bb

ccc

cc

sasuser1000
Calcite | Level 5

you are right, I didn't catch it.

Ksharp
Super User

Art.

Yes. That was what I am confused.

Actually I do not exactly know what OP want.

It is midnight at my time zone.

Good Night! Doctor Art.

Ksharp

art297
Opal | Level 21

Have a good night's rest KSharp.  I was surprised to see you here this late.

sasuser1000
Calcite | Level 5

ksharp, Art thank you both

I will use proc plan

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 14 replies
  • 2558 views
  • 6 likes
  • 3 in conversation