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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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