Aliquot sequence classifications: Difference between revisions

→‎{{header|REXX}}: simplified some statements, optimized the DO loop in the CLASSIFY subroutine, add/changed comments and whitespace.
(→‎{{header|Wren}}: Now uses Wren-math module.)
(→‎{{header|REXX}}: simplified some statements, optimized the DO loop in the CLASSIFY subroutine, add/changed comments and whitespace.)
Line 2,932:
Both of the above limitations are imposed by this Rosetta Code task's restriction requirements:   ''For the purposes of this task, ···''.
<lang rexx>/*REXX program classifies various positive integers for types of aliquot sequences. */
parse arg low high $L /*obtain optional arguments from the CL*/
high= word(high low 10,1); low= word(low 1,1) /*obtain the LOW and HIGH (range). */
if $L='' then $L=11 12 28 496 220 1184 12496 1264460 790 909 562 1064 1488 15355717786080
numeric digits 100 /*be able to compute the number: BIG */
big= 2**47; NTlimit= 16 + 1 /*limits for a non─terminating sequence*/
numeric digits max(9, 1 + length(big) ) /*be able to handle big numbers for // */
#.digs=.; digits() #.0=0; #.1=0 /*#. are/*used thefor proper divisor sums.align numbers for the output*/
#.= .; #.0= 0; #.1= 0 /*#. are the proper divisor sums. */
say center('numbers from ' low " to " high, 79, "═")
do n=low to high; call classify n /*call a subroutine to classify number.*/
end /*n*/ /* [↑] process a range of integers. */
say
say center('first numbers for each classification', 79, "═")
class.=0 0 /* [↓] ensure one number of each class*/
do q=1 until class.sociable\==0 /*the only one that has to be counted. */
call classify -q /*minus (-) sign indicates don't tell. */
_= what; upper _; class._= class._ +1 /*bumpobtain counterthe forclass thisand classuppercase sequenceit. */
if class._== class._ + 1 then say right(q, digits()) 'is' center(what, 15) /*bump counter $for this class sequence.*/
end /*q*/ if class._==1 then say right(q, digs) 'is' /*center(what, [↑]digs) only display the 1st occurrence*/$
end /*q*/ /* [↑] only display the 1st occurrence*/
say /* [↑] process until all classes found*/
say center('classifications for specific numbers', 79, "═")
do i=1 for words($L) /*$L: is a list of "special numbers".*/
call classify word($L, i) /*call a subroutine to classify number.*/
end /*i*/ /* [↑] process a list of integers. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
classify: parse arg a 1 aa; a= abs(a) /*obtain number that's to be classified*/
if #.a\==. then s= #.a /*Was this number been summed before?*/
else s= sigma(a) /*No, then classify number the hard way*/
#.a= s; $=s /*define sum of the proper divisors. */
$= s what= 'terminating' /*assumedefine thisthe kindstart of classificationinteger sequence. */
c.=0; c.s=1 what= 'terminating' /*clearassume allthis cyclickind sequences;of classification. set 1st.*/
c.= 0 if $==a then what= 'perfect' /*check for a "perfect" number. /*clear all cyclic sequences (to zero).*/
c.s= 1 else do t=1 while s\==0 /*loop until sum isn't 0 or > big /*set the first cyclic sequence. */
if $==a then mwhat=s 'perfect' /*check for a "perfect" number. /*obtain the last number in sequence. */
else do t=1 while s>0 if #.m==. then s=sigma(m) /*Notloop defined? Thenuntil sum properisn't divisors 0 or > big.*/
m= s else s=#.m /*useobtain the previouslylast foundnumber integerin sequence. */
if #.m==s & m\==0. then do; whats= 'aspiring' ;sigma(m) /*Not defined? leave;Then sum proper enddivisors*/
parse var $ . word2 else s= #.m /*obtainuse the 2ndpreviously found numberinteger. in sequence. */
if word2m==as then if m>=0 then do; what= 'amicableaspiring' ; leave; end
parse var $=$ s . word2 . /*appendobtain athe sum2nd to thenumber integerin sequence. */
if sword2==a & t>3 then do; what= 'sociableamicable' ; leave; end
$= $ if c.s & m\==0 then do; what= 'cyclic' ; leave;/*append a sum endto the integer sequence.*/
if c.s=1 =a then if t>3 then do; what= 'sociable'; /*assign anotherleave; possible cyclic number*/end
if c.s then if m>0 then do; what= 'cyclic' ; leave; end
c.s= 1 /*assign another possible cyclic number*/
/* [↓] Rosetta Code task's limit: >16 */
if t>NTlimit then do; what= 'non-terminatingnon─terminating'; leave; end
if s>big then do; what= 'NON-TERMINATINGNON─TERMINATING'; leave; end
end /*t*/ /* [↑] only permit within reason. */
if aa>0 then say right(a, digits()digs ) 'is' center(what, 15digs) $
return return /* [↑] only display if AA is positive*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
sigma: procedure expose #. !.; parse arg x; if x11<2 then return 0; odd= x // 2
s=1 1 /* [↓] use EVEN or ODD integers. ___*/
do j=2+odd by 1+odd while j*j<x /*divide by all the integers up to √ X */
if x//j==0 then s= s + j + x%j x % j /*add the two divisors to the sum. */
end /*j*/ /* [↓] adjust for square. ___*/
if j*j==x then s= s + j /*Was X a square? If so, add √ X */
#.x= s /*definememoize division sum for argument X.*/
return s /*return " " " " " */</lang>
{{out|output|text=&nbsp; when using the default input:}}
<pre>