Proper divisors: Difference between revisions

m
Undo revision 272833 by Gerard Schildberger (talk) edited wrong page.
m (→‎version 2: added support for an ace being high --or-- low in a straight.)
m (Undo revision 272833 by Gerard Schildberger (talk) edited wrong page.)
Line 3,634:
 
With the (function) optimization, it's over   '''20'''   times faster.
<lang rexx>/*REXX program analyzesfinds anproper divisors N─card(and count) pokerof hand,integer ranges; and displays what finds the pokermax hand iscount. */
parse arg iFIDbot .;top inc range xtra if iFID=='' | iFID=="," then iFID= 'POKERHAN.DAT' /*obtain optional arguments from the CL*/
if bot=='' | bot=="," then bot= 1 /*Not [↓]specified? read Then use the poker hands dealtdefault. */
if top=='' | do while lines(iFID)\top==0;"," then oxtop= linein(iFID); 10 if/* " " " " " " ox='' then iterate*/
if inc=='' | say right(oxinc=="," max(30, length(ox)then ) ) 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 kinds=digits max(kinds9, _w) /*converthave certainenough pipsdigits tofor // their numberoperator.*/
@.= 'and' end /*i*/ /*a [↑]literal used keep track of N─of─a─kind.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 substr(pips, #, 1) + 1 /*obtain theadjust number of thePdivisors pipfor in handzero. */
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. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
analyzePdivs: procedure; parse arg x ';',mcb; x=abs(x); hand=if translate(x,==1 then return '♥♦♣♠1', "HDCSA,"); flush= 0 /*unity?*/
kinds= 0; suit. odd=x 0// 2; pairs= 0; @.= 0; run= copies(0, 13); pipsif x==0 then return '∞' /*zero run?*/
r=0 /* [↓] ══integer square root══ ___ */
if mc=='' then mc= 5; n= words(hand); if n\==mc then return 'invalid'
q=1; do while q<=z; q=q*4; end /*R: [↓] an PIPinteger canwhich will be 1 or 2√ X characters.*/
do j=1 for n; _=do word(hand,while j)q>1; q=q%4; _=z-r-q; r=r%2; if _>=0 /*obtainthen a carddo; from thez=_; dealt hand. r=r+q; */end
end /*while q>1*/ /* [↑] compute the integer sqrt of X.*/
pip= left(_, length(_) - 1); ws= right(_, 1) /*obtain the card's pip; and the suit.*/
if pip==10 then pipa=1 'T' /*allow an[↓] alternate formuse forall, aor "TEN"only odd #s. ___*/
@._= @._ + 1 do j=2 +odd by 1 +odd to r -(r*r==x) /*divide by some integers up to /*bump the card counter for this hand.X */
#= pos(pip, 123456789TJQK) if x//j==0 then do; a=a j; b=x%j b /*obtainif the÷, pipadd indexboth fordivisors theto cardα & ß. */
return 'high-card'</lang>end
if pos(ws, "♥♣♦♠")==0 then return 'invalid suit in card:' _
if #==0 end /*j*/ then return 'invalid pip in card:' _ /* [↑] % is the REXX integer division*/
/* [↓] adjust for a square. ___*/
if @._\==1 then return 'invalid, duplicate card:' _
suit.ws if j*j==x suit.ws +then 1 return a j b /*Was X a square? /*countIf theso, suitsadd for a possibleX flush.*/
flush= max(flush, suit.ws) return /*count numbera of cards inb /*return the suitsdivisors (both lists). */</lang>
run= overlay(., run, #) /*convert runs to a series of periods. */
_= substr(pips, #, 1) + 1 /*obtain the number of the pip in hand.*/
pips= overlay(_, pips, #) /*convert the pip to legitimate number.*/
kinds= max(kinds, _) /*convert certain pips to their number.*/
end /*i*/ /* [↑] keep track of N─of─a─kind. */
 
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'
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>