@ProcWes wrote:
What does the -9 modifier do here?
It instructs the FINDC function to start the search at the 9th character (of the first argument) with search direction – because of the negative sign – from right to left.
No. If the first argument of FINDC (not c) was '12345678' the modifier -8 could be used, but in this case obviously FINDC would fail to find any digit '9' in '12345678'. So, if c had contained a digit '9' the result would have been incorrect (0) with that code modification. Similarly, with '1234567890' and -10 the '0' in c would have been found first, again leading to an incorrect answer (10, which is absurd) to the original question.
Here is another Base SAS approach using the APP functions
data have;
array ct [20] $1 _temporary_ ; /* Changing the size of the array elements, allows you to compare 2,3,.. digits */
call pokelong ("000112010302",addrlong(ct[1]),length("000112010302"));
max=max(of ct{*});
put max=;
run;
Thanks,
Ahmed
Maybe not the shortest, but I haven't seen POKE used in a long time. That was fun! 🙂
How about this:
do i=9 to 0 by -1 while (x=.);
if indexc(k,put(i,z1.)) then x=i ;
end;
223 data have; 224 k="000112010302"; 225 do i=9 to 0 by -1 while (x=.); 226 if indexc(k,put(i,z1.)) then x=i ; 227 end; 228 put k=:$quote. x= ; 229 run; k="000112010302" x=3
Are we allowed to assume we have an autocall library?
608 data want; 609 x=%x(000112010302); 610 put x=; 611 run; x=3
You CAN, but the lines of code in the autocall macro have to count, too... 😄
data have;
input k $12.;
cards;
000112010302
0
1
2
3
4
5
6
7
8
9
0123456789
.
;
data w;
set have;
k1=compress('9876543210',k,'k');
want=char(k1,1);
run;
cleaned further with first function wrapper:
data w;
set have;
want=first(compress('9876543210',k,'k'));
run;
@SASJedi Thank you Sir!
The responses here are great, and I've learned a lot.
I've summarized the best so far in a new blog post, SAS code golf: find the max digit in a string of digits.
Shoutouts to @novinosrin, @hashman, @FreelanceReinh, @AhmedAl_Attar, and @ChanceTGardener.
Nice blog post, Chris. Thanks for the notification.
Yesterday, I was about to edit my initial post once again and delete the useless semicolon from my one-line suggestion. But I thought this minor correction wouldn't justify another edit, because that %SYSFUNC call didn't exactly address the original question (involving a "character var") anyway. Of course, I would have corrected it, had I known that this code would be further disseminated. Now, the "winner, in terms of concision" contains an obviously redundant character ...
So, lesson learned: Edit every bit of posted code until it's perfect.
"The perfect is the enemy of the good."
That's my justification for cranking out large volumes of mediocre-but-functional code (and maybe applies to blog posts too...)
@ChrisHemedinger wrote:
That's my justification for cranking out large volumes of mediocre-but-functional code (and maybe applies to blog posts too...)
Chris, I've just noticed that you didn't copy (or rather type out) my one-liner correctly in your blog: The second argument of FINDC is missing a leading zero! The same mistake happened in what seems to be (but in fact isn't) a quote from @novinosrin's code. In the code section of the "Apprendix" (sic!) both versions of the string are present.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.