DATA Step, Macro, Functions and more

SAS programming "golf": highest digit in a string of digits

Accepted Solution Solved
Reply
Community Manager
Posts: 3,452
Accepted Solution

SAS programming "golf": highest digit in a string of digits

This question came in for @SASJedi and me on Twitter:

You have a character var with the string "000112010302". What's the least about of [SAS] code that can be written to determine what is the highest number (3) in the string?

I have an answer that works, but I'm certain it isn't the least amount of code possible.  I figured that I'd post to the community and learn something.

 

Chris


Accepted Solutions
Solution
yesterday
Trusted Advisor
Posts: 1,322

Re: SAS programming "golf": highest digit in a string of digits

[ Edited ]
Posted in reply to ChrisHemedinger

How about this?

%sysfunc(findc(123456789,000112010302,b));

Or, in a data step:

data;
c='000112010302';
h=findc('123456789',c,-9);
run;

 

(Edit: replaced 'b' by -9 in the data step to save one more character)

 

Edit 2: At the cost of readability, one could replace '123456789' with 1e10/81-1 (two characters less).

 

Editor's note: this was the earliest, best solution that came in -- so it's the Accepted Solution.  But it's worth reading through ALL of the responses to learn about different approaches and pick up several "tricks" to make SAS do your bidding.

View solution in original post


All Replies
Super User
Posts: 2,049

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to ChrisHemedinger

My stab

 

data w;
k="000112010302";
do _n_=1 to length(k);
highest=max(highest,char(k,_n_));
end;
run;
Contributor
Posts: 38

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to novinosrin

Well, I'm not sure that can be beat here.  Here was mine, but it's a few lines longer.

 

%macro m();
data q;
s = '000112010302';
%do i = 1 %to 12;
c&i. = substr(s,&i.,1);
%end;
max = max(of c1-c12);
drop c1-c12 i;
run;
%mend;
%m;
Community Manager
Posts: 3,452

Re: SAS programming "golf": highest digit in a string of digits

[ Edited ]

Well, @ProcWes, it looks like you've been lured by the siren song of SAS macro.  Macro is tempting for its reusability, but if you turned on MPRINT you'd see that this code actually generates a lot more statements.

 

If we allow that we know the length of the string going in, then we can use the max of construct as you've done.

 

data _null_;
 c = '000112010302';
 array chars{12} 3;
 do i = 1 to length(c);
  chars(i) = input(substr(c,i,1),1.);
 end;
 answer = max(of chars[*]);
 put answer=;
run;

But so far @novinosrin has got these both beat.

 

I suspect that SAS/IML can probably do even better -- load the chars into a matrix and then get the max.

Contributor
Posts: 38

Re: SAS programming "golf": highest digit in a string of digits

[ Edited ]
Posted in reply to ChrisHemedinger

@ChrisHemedinger- yeah, I just wanted the c&i loop to work horizontally.  If I do a regular do, I can't get that - it executes vertically. (i can't reference the "i" value for the variable name.)

 

I don't use arrays enough to set it up, but i'm not surprised there is an option there.

Frequent Contributor
Posts: 112

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to ChrisHemedinger

Chris,

 

Methinks FreelanceReinhard clearly wins this race since his offer doesn't even require looping. With a loop, infinite variants are possible. For example:

 

data _null_ ;                           
  c = '000112010302' ;                  
  do j = 0 to 9 until (length (c) = 1) ;
    c = compress (c, put (j, 1.)) ;     
  end ;                                 
  put c= ;                              
run;                                    

Or just:

data _null_ ;                         
  c = '000112010302' ;                
  do j = 1 to length (c) ;            
    d = d <> input (char (c, j), 1.) ;
  end ;                               
  put d=;                             
run;                                  

And so forth ...

 

Paul D.

 

Trusted Advisor
Posts: 1,322

Re: SAS programming "golf": highest digit in a string of digits

Thanks a lot for chiming in, Paul. This is a great honor.

 

 

 

I'm hesitant to point out that the UNTIL condition length (c) = 1 would not be effective in the case of a tie.

Frequent Contributor
Posts: 112

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to FreelanceReinhard

The honor more than deserved.

 

And you shouldn't be hesitant about the UNTIL. Thou art speaketh the truth.

SAS Employee
Posts: 7

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to ChrisHemedinger
proc iml;
 str='000112010302';
 maximum=max((substr(str,1:length(str),1)));
 print maximum;
quit;

Here's my crack at it in IML. Credit the assist to https://blogs.sas.com/content/iml/2014/05/05/iml-character-vectors.html

 

 

SAS Super FREQ
Posts: 4,269

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to ChanceTGardener

Chance beat me to the punch. Not sure what the rules are ... do we just need to compute it? Print it?

 

proc iml;
k="000112010302";
m=max(substr(k,1:nleng(k),1));


/* OR if need print */

proc iml;
k="000112010302";
print (max(substr(k,1:nleng(k),1)));
Solution
yesterday
Trusted Advisor
Posts: 1,322

Re: SAS programming "golf": highest digit in a string of digits

[ Edited ]
Posted in reply to ChrisHemedinger

How about this?

%sysfunc(findc(123456789,000112010302,b));

Or, in a data step:

data;
c='000112010302';
h=findc('123456789',c,-9);
run;

 

(Edit: replaced 'b' by -9 in the data step to save one more character)

 

Edit 2: At the cost of readability, one could replace '123456789' with 1e10/81-1 (two characters less).

 

Editor's note: this was the earliest, best solution that came in -- so it's the Accepted Solution.  But it's worth reading through ALL of the responses to learn about different approaches and pick up several "tricks" to make SAS do your bidding.

Frequent Contributor
Posts: 112

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to FreelanceReinhard

It doesn't get any terser and more ingenious than that. Kudos.

Super User
Super User
Posts: 8,272

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to FreelanceReinhard

That might be the shortest, but it doesn't handle an empty string properly.  It treats a missing string as if it was all 0 digits.

Here is a version using FINDC() that returns -1 for missing strings.

data have;
  input k $12.;
  x=10-findc('9876543210 ',k);
  y=findc('123456789',k,-9);
  put k $12. +1 x= y=;
cards;
000112010302
0
1
2
3
4
5
6
7
8
9
0123456789
.
;

 

SAS Employee
Posts: 127

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to FreelanceReinhard

You are a code poet, sir! Nicely done. 

Contributor
Posts: 38

Re: SAS programming "golf": highest digit in a string of digits

Posted in reply to FreelanceReinhard
What does the -9 modifier do here?
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats