Proper divisors: Difference between revisions
Content added Content deleted
m (→{{header|J}}) |
m (→version 2: changed whitespace and comments, added better support for zero.) |
||
Line 1,212: | Line 1,212: | ||
With the (subroutine) optimization, it's over twenty times faster. |
With the (subroutine) optimization, it's over twenty times faster. |
||
<lang rexx>/*REXX |
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; max of #s. */ |
||
parse arg |
parse arg bot top inc range xtra /*get optional args from C.L. */ |
||
top=word(top bot 10,1); bot=word(bot 1,1); inc=word(inc 1,1) /*1st range*/ |
|||
if range=='' then range= |
if range=='' then range=top /*use TOP for the 2nd range.*/ |
||
w=length( |
w=length(top)+1; numeric digits max(9,w) /*'nuff digs for // operation*/ |
||
m=0 |
m=0 |
||
do n= |
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: " q |
say right(n,digits()) 'has' center(#,4) "proper divisors: " q |
||
end /*n*/ /* [↑] process a range of |
end /*n*/ /* [↑] process a range of integers. */ |
||
say; @.='and' |
|||
say |
|||
do r=1 for range; q=Pdivs(r); #=words(q); if #<m then iterate |
|||
@.='and' |
|||
@.#=@.# @. r; m=# |
|||
⚫ | |||
@.#=@.# @. r; m=# |
|||
⚫ | |||
say m 'is the highest number of proper divisors in range 1──►'range", and it's for: " subword(@.m,3) |
say m 'is the highest number of proper divisors in range 1──►'range", and it's for: " subword(@.m,3) |
||
say /* [↓] handle any 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, |
numeric digits max(9,length(n)+1); q=Pdivs(n); #=words(q) |
||
say right(n,digits()) 'has' center(#,4) "proper divisors." |
say right(n,digits()) 'has' center(#,4) "proper divisors." |
||
end /*i*/ /* [↑] support extra given |
end /*i*/ /* [↑] support extra given integers. */ |
||
exit /*stick a fork in it, we're done.*/ |
exit /*stick a fork in it, we're all done. */ |
||
/*──────────────────────────────────PDIVS |
/*──────────────────────────────────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 '' |
||
if x==0 then return ' |
odd=x//2; if x==0 then return '∞' |
||
a=1 /* [↓] |
a=1 /* [↓] process only EVEN│ODD integers.*/ |
||
do j=2+odd by 1+odd while j*j<x |
do j=2+odd by 1+odd while j*j<x /*divide by all integers up to √x. */ |
||
if x//j==0 then do; a=a j; b=x%j b; end /*add |
if x//j==0 then do; a=a j; b=x%j b; end /*add divisors to α&ß lists if ÷*/ |
||
end /*j*/ |
end /*j*/ /* [↑] % is the REXX integer division*/ |
||
/* [↓] adjust for square. _ */ |
/* [↓] adjust for square. _ */ |
||
if j*j==x then return a j b /*Was X a square? If so, add √x.*/ |
if j*j==x then return a j b /*Was X a square? If so, add √x. */ |
||
return a b /*return divisors (both lists). */</lang> |
return a b /*return the divisors (both lists). */</lang> |
||
'''output''' when using the following input: <tt> |
'''output''' when using the following input: <tt> 0 10 1 20000 166320 1441440 11796480000 </tt> |
||
<pre> |
<pre> |
||
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 |