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