Digital root/Multiplicative digital root: Difference between revisions
Content added Content deleted
m (→idomatic version: added/changed comments and whitespace, optimized a function, used a template for the output.) |
m (→ultra-fast version: added/changed comments, whitespace, and indentations, optimized a function, used a template for output.) |
||
Line 2,217: | Line 2,217: | ||
===ultra-fast version=== |
===ultra-fast version=== |
||
This fast version can handle a target of five hundred numbers with ease for the 2<sup>nd</sup> part of the task's requirement. |
This fast version can handle a target of five hundred numbers with ease for the 2<sup>nd</sup> part of the task's requirement. |
||
<lang rexx>/*REXX |
<lang rexx>/*REXX program finds the persistence and multiplicative digital root of some numbers.*/ |
||
numeric digits 2000 /*increase the number of |
numeric digits 2000 /*increase the number of decimal digits*/ |
||
parse arg target x |
parse arg target x /*obtain optional arguments from the CL*/ |
||
if |
if \datatype(target, 'W') then target=25 /*Not specified? Then use the default.*/ |
||
⚫ | |||
say center('number',8) ' persistence multiplicative digital root' |
say center('number',8) ' persistence multiplicative digital root' |
||
say copies('─' ,8) ' ─────────── ───────────────────────────' |
say copies('─' ,8) ' ─────────── ───────────────────────────' |
||
/* [↑] title and separator. |
/* [↑] the title and the separator. */ |
||
do j=1 for words(x); n=abs(word(x,j)) |
do j=1 for words(x); n=abs( word(x, j) ) /*process each number in the list. */ |
||
parse value |
parse value MDR(n) with mp mdr /*obtain the persistence and the MDR. */ |
||
say right(n,8) center(mp,13) center(mdr,30) |
say right(n,8) center(mp,13) center(mdr,30) /*display the number, persistence, MDR.*/ |
||
end /*j*/ /* [↑] show MP and MDR for each |
end /*j*/ /* [↑] show MP and MDR for each number.*/ |
||
say /* [↓] show a blank |
say /* [↓] show a blank and the title line.*/ |
||
say 'MDR first ' target " numbers that have a matching MDR" |
say 'MDR first ' target " numbers that have a matching MDR" |
||
say '═══ ' copies("═",(target+(target+1)**2)%2) |
say '═══ ' copies("═",(target+(target+1)**2)%2) /*display a separator line (for title).*/ |
||
do k=0 for 9; hits=0 /*show numbers that have an MDR of K. */ |
|||
_= |
|||
if k==7 then _=@7 /*handle the special case of seven. */ |
|||
else do m=k until hits==target /*find target numbers with an MDR of K.*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
else if MDR(m, 1)\==k then iterate |
|||
⚫ | |||
⚫ | |||
if k==3 then do; o=strip(m, 'T', 1) /*strip trailing ones from M*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
say " "k': ['_"]" /*display the K (MDR) and the list. */ |
|||
if k==3 then @7=translate(_, 7, k) /*save for later, a special "7" case.*/ |
|||
end /*k*/ /* [↑] done with the K MDR list. */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
@.= /* [↓] handle MDR of "9" special. */ |
|||
_=translate(@7, 9, 7) /*translate string for MDR of nine. */ |
|||
@9=translate(_, , ',') /*remove trailing commas from numbers. */ |
|||
@3= /*assign null string before building. */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
do j=1 for words(@9) /*process each number for MDR 9 case.*/ |
|||
_=space( translate( word(@9, j), , 9), 0) /*elide all "9"s using SPACE(x,0).*/ |
|||
L=length(_) + 1 /*use a "fudged" length of the number. */ |
|||
new= /*these are the new numbers (so far). */ |
|||
_=translate(@7,9,7) /*translate a string for MDR 9. */ |
|||
⚫ | |||
⚫ | |||
do j=1 for words(@9) /*process each number for MDR 9. */ |
|||
_=space(translate(word(@9,j),,9),0) /*remove "9"s using SPACE(x,0)*/ |
|||
⚫ | |||
⚫ | |||
do k=0 for L; q=insert(3,_,k) /*insert the 1st "3" into the #*/ |
|||
do i=k to L; z=insert(3,q,i) /* " " 2nd "3" " " "*/ |
|||
if @.z\=='' then iterate /*if already define, ignore the #*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
@3=space(@3 new) /*remove blanks, then add to list*/ |
|||
⚫ | |||
do k=0 for L; q=insert(3, _, k) /*insert the 1st "3" into the number*/ |
|||
do i=k to L; z=insert(3, q, i) /* " " 2nd "3" " " " */ |
|||
if @.z\=='' then iterate /*if already define, ignore the number.*/ |
|||
⚫ | |||
⚫ | |||
end /*i*/ /* [↑] end of 2nd insertion of "3".*/ |
|||
end /*k*/ /* [↑] " " 1st " " " */ |
|||
⚫ | |||
@= |
@3=space(@3 new) /*remove blanks, then add to the list.*/ |
||
end /*j*/ /* [↑] end of insertion of the "3"s. */ |
|||
⚫ | |||
⚫ | |||
/*──────────────────────────────────MDR subroutine──────────────────────*/ |
|||
@= /* [↓] merge two lists, 3s and 9s. */ |
|||
do while a1\=='' & a2\=='' /*process while the lists aren't empty.*/ |
|||
⚫ | |||
⚫ | |||
if x=='' | y=='' then leave /*are X or Y empty? */ |
|||
if x<y then do; @=@ x; a1=delword(a1, 1, 1); end /*add X to the @ list.*/ |
|||
else do; @=@ y; a2=delword(a2, 1, 1); end /* " Y " " " " */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
say " "9': ['@"]" /*display the "9" (MDR) and the list.*/ |
|||
exit /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
MDR: procedure; parse arg y,s; y=abs(y) /*get the number and determine the MDR.*/ |
|||
do p=1 until y<10; parse var y r 2 |
|||
⚫ | |||
end /*k*/ |
|||
y=r |
|||
end /*p*/ /* [↑] wash, rinse, and repeat ··· */ |
|||
if s==1 then return r /*return multiplicative digital root. */ |
|||
return p r /*return the persistence and the MDR. */</lang> |
|||
⚫ | |||
<pre> |
<pre> |
||
number persistence multiplicative digital root |
number persistence multiplicative digital root |