DATA Step, Macro, Functions and more

Problem revisiting a previous question that was answered

Reply
Super Contributor
Posts: 259

Problem revisiting a previous question that was answered

[ Edited ]

 

Hi 

 

I posted a question a couple of years ago (link below). I needed help on an algorithm for ranking poker hand values. Haikuo responded with an excellent algorithm which worked perfectly at the time. You will see in the link below he has included code that can be copied and pasted into sas and run straight away. I had to make some adjustments in cases where the code was garbled (see picture attached for example - i replaced the dot with [*]). When I run the code now I get an error. So I copied the solution code into sas, replaced garbled text and then ran the program (which worked a couple of years ago). I don't have the sas program I used before so I'm desperately trying to recreate it. I've spent a few hours at this so far but I keep getting errors, I have attached an screenshot showing the error I am getting. 

 

Can someone try to copy and paste the same code, correct for the garbled text (I think it only involves replacing the dot in the attached picture file "Capture). 

 

Many thanks

 

 

https://communities.sas.com/t5/SAS-Procedures/Allocating-Values-to-Poker-Hands/td-p/146459

 

Here is the first part pf the code. The error occurs afte the last statement. 

 

DATA CAT;
INPUT SUIT :$1. @@;
CARDS;
S C H D
;
DATA SEQ;
INPUT NUM :$2. @@;
CARDS;
14 13 12 11 10 09 08 07 06 05 04 03 02
;
PROC SQL NOPRINT;
SELECT DISTINCT QUOTE(CATS(SUIT,NUM)) INTO :HANDS SEPARATED BY ' ' FROM CAT, SEQ;
QUIT;
/*EMBED RANKING ALGORITHM INTO THE FOLLOWING MACRO*/
%MACRO SIM;
DO Z=1 TO 5;
FST(Z)=FIRST(C(Z));
NUM(Z)=INPUT(COMPRESS(C(Z),,'KD'),2.);
END;
CALL SORTC (OF FST(*));
CALL SORTN (OF NUM(*));
/*STRAIGHT FLUSH*/
IF FST(1)=FST(5) AND NUM(5)-NUM(4)=1 AND NUM(4)-NUM(3)=1 AND NUM(3)-NUM(2)=1 AND NUM(2)-NUM(1)=1 THEN
DO;
RANK1=9;
RANK2=NUM(5);
RANK3=999;
RANK4=999;
RANK5=999;
RANK6=999;
END;
ELSE IF FST(1)=FST(5) AND NUM(1)=2 AND NUM(2)=3 AND NUM(3)=4 AND NUM(4)=5 AND NUM(5)=14 THEN DO;
RANK1=9;
RANK2=NUM(4);
RANK3=999;
RANK4=999;
RANK5=999;
RANK6=999;
END;
/*FOUR OF A KIND*/
ELSE IF NUM(1)=NUM(4) OR NUM(2)=NUM(5) THEN
DO;
RANK1=8;
IF NUM(1)=NUM(4) THEN
DO;
RANK2=NUM(1);
RANK3=NUM(5);
RANK4=999;
RANK5=999;
RANK6=999;
END;
ELSE IF NUM(2)=NUM(5) THEN
DO;
RANK2=NUM(2);
RANK3=NUM(1);
RANK4=999;
RANK5=999;
RANK6=999;
END;
END;
/*FULL HOUSE*/
ELSE IF (NUM(1)=NUM(2) AND NUM(3)=NUM(5)) OR (NUM(1)=NUM(3) AND NUM(4)=NUM(5)) THEN
DO;
RANK1=7;
IF (NUM(1)=NUM(2) AND NUM(3)=NUM(5)) THEN
DO;
RANK2=NUM(3);
RANK3=NUM(1);
RANK4=999;
RANK5=999;
RANK6=999;
END;
ELSE IF (NUM(1)=NUM(3) AND NUM(4)=NUM(5)) THEN
DO;
RANK2=NUM(1);
RANK3=NUM(4);
RANK4=999;
RANK5=999;
RANK6=999;
END;
END;
/*FLUSH*/
ELSE IF FST(1)=FST(5) THEN
DO;
RANK1=6;
RANK2=NUM(5);
RANK3=NUM(4);
RANK4=NUM(3);
RANK5=NUM(2);
RANK6=NUM(1);
END;
/*STRAIGHT*/
ELSE IF NUM(5)-NUM(4)=1 AND NUM(4)-NUM(3)=1 AND NUM(3)-NUM(2)=1 AND NUM(2)-NUM(1)=1 THEN
DO;
RANK1=5;
RANK2=NUM(5);
RANK3=999;
RANK4=999;
RANK5=999;
RANK6=999;
END;
ELSE IF NUM(1)=2 AND NUM(2)=3 AND NUM(3)=4 AND NUM(4)=5 AND NUM(5)=14 THEN
DO;
RANK1=5;
RANK2=NUM(4);
RANK3=999;
RANK4=999;
RANK5=999;
RANK6=999;
END;
/*THREE OF A KIND*/
ELSE IF (NUM(1)=NUM(3) OR NUM(2)=NUM(4) OR NUM(3)=NUM(5)) THEN
DO;
RANK1=4;
IF NUM(1)=NUM(3) THEN
DO;
RANK2=NUM(1);
RANK3=NUM(5);
RANK4=NUM(4);
RANK5=999;
RANK6=999;
END;
IF NUM(2)=NUM(4) THEN
DO;
RANK2=NUM(2);
RANK3=NUM(5);
RANK4=NUM(1);
RANK5=999;
RANK6=999;
END;
IF NUM(3)=NUM(5) THEN
DO;
RANK2=NUM(3);
RANK3=NUM(2);
RANK4=NUM(1);
RANK5=999;
RANK6=999;
END;
END;
/*TWO PAIR*/
ELSE IF (NUM(1)=NUM(2) AND NUM(3)=NUM(4)) OR (NUM(1)=NUM(2) AND NUM(4)=NUM(5)) OR (NUM(2)=NUM(3) AND NUM(4)=NUM(5)) THEN
DO;
RANK1=3;
IF (NUM(1)=NUM(2) AND NUM(3)=NUM(4)) THEN
DO;
RANK2=NUM(3);
RANK3=NUM(1);
RANK4=NUM(5);
RANK5=999;
RANK6=999;
END;
IF (NUM(1)=NUM(2) AND NUM(4)=NUM(5)) THEN
DO;
RANK2=NUM(5);
RANK3=NUM(1);
RANK4=NUM(3);
RANK5=999;
RANK6=999;
END;
IF (NUM(3)=NUM(2) AND NUM(5)=NUM(4)) THEN
DO;
RANK2=NUM(5);
RANK3=NUM(3);
RANK4=NUM(1);
RANK5=999;
RANK6=999;
END;
END;
/*ONE PAIR*/
ELSE IF NUM(1)=NUM(2) OR NUM(2)=NUM(3) OR NUM(3)=NUM(4) OR NUM(4)=NUM(5) THEN
DO;
RANK1=2;
IF NUM(1)=NUM(2) THEN
DO;
RANK2=NUM(1);
RANK3=NUM(5);
RANK4=NUM(4);
RANK5=NUM(3);
RANK6=999;
END;
IF NUM(2)=NUM(3) THEN
DO;
RANK2=NUM(3);
RANK3=NUM(5);
RANK4=NUM(4);
RANK5=NUM(1);
RANK6=999;
END;
IF NUM(3)=NUM(4) THEN
DO;
RANK2=NUM(4);
RANK3=NUM(5);
RANK4=NUM(2);
RANK5=NUM(1);
RANK6=999;
END;
IF NUM(4)=NUM(5) THEN
DO;
RANK2=NUM(5);
RANK3=NUM(3);
RANK4=NUM(2);
RANK5=NUM(1);
RANK6=999;
END;
END;
/*HIGH CARD*/
ELSE
DO;
RANK1=1;
RANK2=NUM(5);
RANK3=NUM(4);
RANK4=NUM(3);
RANK5=NUM(2);
RANK6=NUM(1);
END;
%MEND;
/*SCORE ALL OF THE COMBINATIONS*/
data HANDS;
array c[5] $3;
array x[52] $3 (&HANDS.);
array i[5];
ARRAY NUM(5) num1-num5;
ARRAY FST(5) $ 1 fst1-fst5;
n=dim(x);
k=dim(i);
i[1]=0;
ncomb=comb(n,k);
do j=1 to ncomb;
call allcombi(n, k, of i[*]);
do h=1 to k;
c=x[i];
end;
%SIM
OUTPUT;
end;
KEEP C: RANK: num:;
run;

 

 


error.GIFCapture.GIF
Super User
Posts: 11,343

Re: Problem revisiting a previous question that was answered

It really helps to paste code in the code boxes using the {i} icon. Then it doesn't get reformatted.

 

I also submit that the code did not work because of this line::

c=x[i];

 

It the data step this line is used both C and I are Arrays. So they would need to be used such as

c[1] and x[ i[1]] or similar. possibly (from context)

 

c[h] = x[ h];

or

c[h] = x[ i[h] ];

From a log AFTER correcting the odd character in the allcombi function call:

1330  do j=1 to ncomb;
1331             call allcombi(n, k, of i(*));
1332
1333             do h=1 to k;
1334                  c=x[i];
ERROR: Illegal reference to the array i.
ERROR: Illegal reference to the array c.
1335             end;
1336             %SIM
1337             OUTPUT;

Ask a Question
Discussion stats
  • 1 reply
  • 124 views
  • 0 likes
  • 2 in conversation