Proper divisors: Difference between revisions

m
→‎version 2: added/changed whitespace and comments, changed output alignment and indentation.
m (→‎version 2: added/changed whitespace and comments, changed output alignment and indentation.)
Line 1,431:
 
===version 2===
The following REXX version is an adaptation of the   ''optimized''   version for the REXX language example for   ''Factors of an integer''.
 
This REXX version handles all integers   (negative, zero, positive)   and automatically adjusts the precision (digits).
Line 1,437:
 
With the (subroutine) optimization, it's over twenty times faster.
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; & max of #scount. */
parse arg bot top inc range xtra /*get optional argsarguments from CCL.L. */
top=word(top bot 10,1); bot=word(bot 1,1); inc=word(inc 1,1) /*1st range.*/
if range=='' then range=top /*use TOP for the 2nd range. */
w=length(top)+1; numeric digits max(9,w) /*'nuff digsdigits for // operation*/
m=0
do n=bot to top by inc; q=Pdivs(n); #=words(q); if q=='∞' then #=q
say right(n,max(20,digits())) 'has' center(#,4) "proper divisors: " q
end /*n*/ /* [↑] process a1st range of integers. */
say; @.='and'
do r=1 for range; q=Pdivs(r); #=words(q); if #<m then iterate
@.#=@.# @. r; m=#
end /*r*/ /* [↑] process a2nd range of integers. */
__='is the highest number of proper divisors in range 1──►'range
 
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)
numeric digits max(9,length(n)+1); q=Pdivs(n); #=words(q)
say right(n,max(20,digits())) 'has' center(#,4) "proper divisors."
end /*i*/ /* [↑] support extra givenspecified integers. */
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────PDIVS subroutine──────────────────────────*/
Pdivs: procedure; parse arg x,b; x=abs(x); if x==1 then return ''
odd=x//2; if x==0 then return '∞'
a=1 /* [↓] processdo only EVEN│ODDEVEN integersor ODD #s. ___*/
do j=2+odd by 1+odd while j*j<x /*divide by all the integers up to √x. x */
if x//j==0 then do; a=a j; b=x%j b; end /*if ÷, add both divisors to α&ß lists if ÷*/
end /*j*/ /* [↑] % is the REXX integer division*/
/* [↓] adjust for a square. _ ___*/
if j*j==x then return a j b /*Was X a square? If so, add √x. √ x */
return a b /*return the divisors (both lists). */</lang>
'''output''' 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>
0 has ∞ proper divisors: ∞
1 has 0 proper divisors:
2 has 1 proper divisors: 1
3 has 1 proper divisors: 1
4 has 2 proper divisors: 1 2
5 has 1 proper divisors: 1
6 has 3 proper divisors: 1 2 3
7 has 1 proper divisors: 1
8 has 3 proper divisors: 1 2 4
9 has 2 proper divisors: 1 3
10 has 3 proper divisors: 1 2 5
 
7939 is the highest number of proper divisors in range 1──►200001──►2000, and it's for: 15120 and 184801680
 
166320 has 159 proper divisors.
1441440 has 287 proper divisors.
11796480000 has 329 proper divisors.
</pre>