Jump to content

Proper divisors: Difference between revisions

m
→‎version 2: added support for an ace being high --or-- low in a straight.
m (→‎version 2: added wording to the REXX section header.)
m (→‎version 2: added support for an ace being high --or-- low in a straight.)
Line 3,634:
 
With the (function) optimization, it's over   '''20'''   times faster.
<lang rexx>/*REXX program findsanalyzes properan divisors (andN─card count) ofpoker integerhand, ranges; findsand displays what the maxpoker counthand is. */
parse arg botiFID top.; inc range xtra if iFID=='' | iFID=="," then iFID= /*obtain optional arguments from the CL*/'POKERHAN.DAT'
if bot=='' | bot=="," then bot= 1 /*Not specified?[↓] read Then use the defaultpoker hands dealt. */
if top=='' | do top while lines(iFID)\==","0; then topox= linein(iFID); 10 /* " " " " " "if ox='' then */iterate
if inc=='' | say inc=="right(ox," max(30, thenlength(ox) ) ) inc= 1 ' ◄─── /* " " " " " ' " */analyze(ox)
if range=='' | range=="," then end range=20000 /*while*/ /* " " " " " /* [↑] " analyze/validate the poker hand*/
w=1+max(length(top), length(bot), length(range)) /*determine the biggest number of these*/
numeric digits max(9, w) /*have enough digits for // operator.*/
@.= 'and' /*a literal used to separate #s in list*/
do n=bot to top by inc /*process the first range specified. */
q=Pdivs(n); #=words(q) /*get proper divs; get number of Pdivs.*/
if q=='∞' then #=q /*adjust number of Pdivisors for zero. */
say right(n, max(20, w) ) 'has' center(#, 4) "proper divisors: " q
end /*n*/
say /* [↑] process 1st range of integers.*/
m=0 /*M ≡ maximum number of Pdivs (so far).*/
do r=1 for range /*process the second range specified. */
q=Pdivs(r); #=words(q) /*get proper divs; get number of Pdivs.*/
if #<m then iterate /*Less then max? Then ignore this #. */
@.#=@.# @. r; m=# /*add this Pdiv to max list; set new M.*/
end /*r*/ /* [↑] process 2nd range of integers.*/
 
say m ' is the highest number of proper divisors in range 1──►'range,
", and it's for: " subword(@.m, 3)
say /* [↓] handle any given extra numbers.*/
do i=1 for words(xtra); n=word(xtra, i) /*obtain an extra number from XTRA list*/
w=max(w, 1 + length(n) ) /*use maximum width for aligned output.*/
numeric digits max(9, 1 + length(n) ) /*have enough digits for // operator.*/
q=Pdivs(n); #=words(q) /*get proper divs; get number of Pdivs.*/
say right(n, max(20, w) ) 'has' center(#, 4) "proper divisors."
end /*i*/ /* [↑] support extra specified integers*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Pdivsanalyze: procedure; parse arg x ';',bmc; x=abs(x); ifhand= translate(x==1 then return, '♥♦♣♠1', "HDCSA,"); flush= /*unity?*/0
kinds= 0; oddsuit.=x // 20; pairs= 0; @.= 0; run= copies(0, 13); if xpips==0 then return '∞' /*zero ?*/run
if mc=='' then mc= 5; n= words(hand); if n\==mc then return 'invalid'
r=0 /* [↓] ══integer square root══ ___ */
q=1; do while q<=z; q=q*4; end /*R: [↓] an integerPIP which willcan be 1 or √ X2 characters.*/
do j=1 for n; do_= whileword(hand, q>1;j) q=q%4; _=z-r-q; r=r%2; if _>=0 then/*obtain a do;card from z=_;the dealt hand. r=r+q; end*/
pip= left(_, length(_) - 1); ws= right(_, 1) /*obtain the card's pip; and the suit.*/
end /*while q>1*/ /* [↑] compute the integer sqrt of X.*/
if pip==10 then apip=1 'T' /*allow [↓]an alternate useform all,for ora only odd #s"TEN". ___*/
@._= @._ + 1 do j=2 +odd by 1 +odd to r -(r*r==x) /*divide by some integers up to X /*bump the card counter for this hand. */
#= pos(pip, 123456789TJQK) if x//j==0 then do; a=a j; b=x%j b /*ifobtain ÷,the addpip bothindex divisorsfor tothe α & ßcard. */
if pos(ws, "♥♣♦♠")==0 then return 'invalid suit in card:' _
end
if #==0 end /*j*/ then return 'invalid pip in card:' /* [↑] % is the REXX integer division*/_
if @._\==1 then return 'invalid, duplicate card:' _
/* [↓] adjust for a square. ___*/
if j*j=suit.ws=x suit.ws then+ 1 return a j b /*Was X a square? If/*count so,the addsuits for a Xpossible flush.*/
flush= max(flush, suit.ws) return /*count anumber of cards b /*returnin the divisors (both lists)suits. */</lang>
run= overlay(., run, #) /*convert runs to a series of periods. */
if q=='∞' then #_=q substr(pips, #, 1) + 1 /*adjustobtain the number of Pdivisorsthe forpip zero.in hand.*/
pips= overlay(_, pips, #) /*convert the pip to legitimate number.*/
numeric digits kinds= max(9kinds, w_) /*haveconvert enoughcertain digitspips for //to their operatornumber.*/
@.= 'and' end /*i*/ /*a literal[↑] used tokeep track of N─of─a─kind. separate #s in list*/
 
run= run || left(run, 1) /*An ace can be high ─or─ low. */
pairs= countstr(2, pips) /*count number of pairs (2s in PIPS).*/
straight= pos(....., run || left(run, 1) ) \== 0 /*does the RUN contains a straight? */
if flush==5 & straight then return 'straight-flush'
if kinds==4 then return 'four-of-a-kind'
if kinds==3 & pairs==1 then return 'full-house'
if flush==5 then return 'flush'
if straight then return 'straight'
if kinds==3 then return 'three-of-a-kind'
if kinds==2 & pairs==2 then return 'two-pair'
if kinds==2 then return 'one-pair'
end return 'high-card'</lang>
{{out|output|text=&nbsp; when using the following input: &nbsp; <tt> 0 &nbsp; 10 &nbsp; 1 &nbsp; &nbsp; &nbsp; 20000 &nbsp; &nbsp; &nbsp; 166320 &nbsp; 1441440 &nbsp; 11796480000 </tt>}}
<pre>
Cookies help us deliver our services. By using our services, you agree to our use of cookies.