Amicable pairs: Difference between revisions

Add ABC
(→‎{{header|AppleScript}}: Updated primitives)
(Add ABC)
 
(170 intermediate revisions by 58 users not shown)
Line 1:
{{task|Prime Numbers}}
 
Two integers <math>N</math> and <math>M</math> are said to be [[wp:Amicable numbers|amicable pairs]] if <math>N \neq M</math> and the sum of the [[Proper divisors|proper divisors]] of <math>N</math> (<math>\mathrm{sum}(\mathrm{propDivs}(N))</math>) <math>= M</math> as well as <math>\mathrm{sum}(\mathrm{propDivs}(M)) = N</math>.
Line 20:
<br><br>
 
=={{header|ALGOL 6811l}}==
<syntaxhighlight lang="11l">F sum_proper_divisors(n)
<lang algol68># resturns the sum of the proper divisors of n #
# if n =R 1,I 0n or< -1, we return2 {0} E sum((1 .. n I/ 2).filter(it -> (@n % it) == #0))
PROC sum proper divisors = ( INT n )INT:
BEGIN
INT result := 0;
INT abs n = ABS n;
IF abs n > 1 THEN
FOR d FROM ENTIER sqrt( abs n ) BY -1 TO 2 DO
IF abs n MOD d = 0 THEN
# found another divisor #
result +:= d;
IF d * d /= n THEN
# include the other divisor #
result +:= n OVER d
FI
FI
OD;
# 1 is always a proper divisor of numbers > 1 #
result +:= 1
FI;
result
END # sum proper divisors # ;
 
L(n) 1..20000
# construct a table of the sum of the proper divisors of numbers #
V m = sum_proper_divisors(n)
# up to 20 000 #
I m > n & sum_proper_divisors(m) == n
INT max number = 20 000;
print(n"\t"m)</syntaxhighlight>
[ 1 : max number ]INT proper divisor sum;
FOR n TO UPB proper divisor sum DO proper divisor sum[ n ] := sum proper divisors( n ) OD;
 
=={{header|8080 Assembly}}==
# returns TRUE if n1 and n2 are an amicable pair FALSE otherwise #
<syntaxhighlight lang="8080asm"> org 100h
# n1 and n2 are amicable if the sum of the proper diviors #
# n1 = n2 and the sum of the ;;; Calculate proper divisors of n2 = n1 #2..20000
lxi h,pdiv + 4 ; 2 bytes per entry
PROC is an amicable pair = ( INT n1, n2 )BOOL:
lxi d,19999 ; [2 .. 20000] means 19999 entries
( proper divisor sum[ n1 ] = n2 AND proper divisor sum[ n2 ] = n1 );
lxi b,1 ; Initialize each entry to 1
init: mov m,c
inx h
mov m,b
inx h
dcx d
mov a,d
ora e
jnz init
lxi b,1 ; BC = outer loop variable
iouter: inx b
lxi h,-10001 ; Are we there yet?
dad b
jc idone ; If so, we've calculated all of them
mov h,b
mov l,c
dad h
xchg ; DE = inner loop variable
iinner: push d ; save DE
xchg
dad h ; calculate *pdiv[DE]
lxi d,pdiv
dad d
mov e,m ; DE = pdiv[DE]
inx h
mov d,m
xchg ; pdiv[DE] += BC
dad b
xchg ; store it back
mov m,d
dcx h
mov m,e
pop h ; restore DE (into HL)
dad b ; add BC
lxi d,-20001 ; are we there yet?
dad d
jc iouter ; then continue with outer loop
lxi d,20001 ; otherwise continue with inner loop
dad d
xchg
jmp iinner
idone: lxi b,1 ; BC = outer loop variable
touter: inx b
lxi h,-20001 ; Are we there yet?
dad b
rc ; If so, stop
mov d,b ; DE = outer loop variable
mov e,c
tinner: inx d
lxi h,-20001 ; Are we there yet?
dad d
jc touter ; If so continue with outer loop
push d ; Store the variables
push b
mov h,b ; find *pdiv[BC]
mov l,c
dad b
lxi b,pdiv
dad b
mov a,m ; Compare low byte (to E)
cmp e
jnz tnext1 ; Not equal = not amicable
inx h
mov a,m
cmp d ; Compare high byte (to B)
jnz tnext1 ; Not equal = not amicable
pop b ; Restore BC
xchg ; find *pdiv[DE]
dad h
lxi d,pdiv
dad d
mov a,m ; Compare low byte (to C)
cmp c
jnz tnext2 ; Not equal = not amicable
inx h
mov a,m ; Compare high byte (to B)
cmp b
jnz tnext2 ; Not equal = not amicable
pop d ; Restore DE
push d ; Save them both on the stack again
push b
push d
mov h,b ; Print the first number
mov l,c
call prhl
pop h ; And the second number
call prhl
lxi d,nl ; And a newline
mvi c,9
call 5
tnext1: pop b ; Restore B
tnext2: pop d ; Restore D
jmp tinner ; Continue
;;; Print the number in HL
prhl: lxi d,nbuf ; Store buffer pointer on stack
push d
lxi b,-10 ; Divisor
pdgt: lxi d,-1 ; Quotient
pdivlp: inx d
dad b
jc pdivlp
mvi a,'0'+10 ; Make ASCII digit
add l
pop h ; Store in output buffer
dcx h
mov m,a
push h
xchg ; Keep going with rest of number
mov a,h ; if not zero
ora l
jnz pdgt
mvi c,9 ; CP/M call to print string
pop d ; Get buffer pointer
jmp 5
db '*****'
nbuf: db ' $'
nl: db 13,10,'$'
pdiv: equ $ ; base</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|8086 Assembly}}==
# find the amicable pairs up to 20 000 #
<syntaxhighlight lang="asm">LIMIT: equ 20000 ; Maximum value
FOR p1 TO max number DO
cpu 8086
FOR p2 FROM p1 + 1 TO max number DO
org 100h
IF is an amicable pair( p1, p2 ) THEN
section .text
print( ( whole( p1, -6 ), " and ", whole( p2, -6 ), " are a amicable pair", newline ) )
mov ax,final ; Set DS and ES to point just beyond the
mov cl,4 ; program. We're just going to assume MS-DOS
shr ax,cl ; gave us enough memory. (Generally the case,
inc ax ; a .COM gets a 64K segment and we need ~40K.)
mov cx,cs
add ax,cx
mov ds,ax
mov es,ax
calc: mov ax,1 ; Calculate proper divisors for 2..20000
mov di,4 ; Initially, set each entry to 1.
mov cx,LIMIT-1 ; 2 to 20000 inclusive = 19999 entries
rep stosw
mov ax,2 ; AX = outer loop counter
mov cl,2
mov dx,LIMIT*2 ; Keep inner loop limit ready in DX
mov bp,LIMIT/2 ; And outer loop limit in BP
.outer: mov bx,ax ; BX = inner loop counter (multiplied by two)
shl bx,cl ; Each entry is 2 bytes wide
.inner: add [bx],ax ; divsum[BX/2] += AX
add bx,ax ; Advance to next entry
add bx,ax ; Twice, because each entry is 2 bytes wide
cmp bx,dx ; Are we there yet?
jbe .inner ; If not, keep going
inc ax
cmp ax,bp ; Is the outer loop done yet?
jbe .outer ; If not, keep going
show: mov dx,LIMIT ; Keep limit ready in DX
mov ax,2 ; AX = outer loop counter
mov si,4 ; SI = address for outer loop
.outer: mov cx,ax ; CX = inner loop counter
inc cx
mov di,cx ; DI = address for inner loop
shl di,1
mov bx,[si] ; Preload divsum[AX]
.inner: cmp cx,bx ; CX == divsum[AX]?
jne .next ; If not, the pair is not amicable
cmp ax,[di] ; AX == divsum[CX]?
jne .next ; If not, the pair is not amicable
push ax ; Keep the registers
push bx
push cx
push dx
push cx ; And CX twice because we need to print it
call prax ; Print the first number
pop ax
call prax ; And the second number
mov dx,nl ; And a newline
call pstr
pop dx ; Restore the registers
pop cx
pop bx
pop ax
.next: inc di ; Increment inner loop variable and address
inc di ; Address twice because each entry has 2 bytes
inc cx
cmp cx,dx ; Are we done yet?
jbe .inner ; If not, keep going
inc si ; Increment outer loop variable and address
inc si ; Address twice because each entry has 2 bytes
inc ax
cmp ax,dx ; Are we done yet?
jbe .outer ; If not, keep going.
ret
;;; Print the number in AX. Destroys AX, BX, CX, DX.
prax: mov cx,10 ; Divisor
mov bx,nbuf ; Buffer pointer
.digit: xor dx,dx
div cx ; Divide by 10 and extract digit
add dl,'0' ; Add ASCII 0 to digit
dec bx
mov [cs:bx],dl ; Store in string
test ax,ax ; Any more?
jnz .digit ; If so, keep going
mov dx,bx ; If not, print the result
;;; Print string from CS.
pstr: push ds ; Save DS
mov ax,cs ; Set DS to CS
mov ds,ax
mov ah,9 ; Print string using MS-DOS
int 21h
pop ds ; Restore DS
ret
db '*****'
nbuf: db ' $'
nl: db 13,10,'$'
final: equ $</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program amicable64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ NMAXI, 20000
.equ TABMAXI, 100
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz " @ : @\n"
szCarriageReturn: .asciz "\n"
szMessErr1: .asciz "Array too small !!"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
tResult: .skip 8 * TABMAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x3,qNMaxi // load limit
mov x4,#2 // number begin
1:
mov x0,x4 // number
bl decFactor // compute sum factors
cmp x0,x4 // equal ?
beq 2f
mov x2,x0 // factor sum 1
bl decFactor
cmp x0,x4 // equal number ?
bne 2f
mov x0,x4 // yes -> search in array
mov x1,x2 // and store sum
bl searchRes
cmp x0,#0 // find ?
bne 2f // yes
mov x0,x4 // no -> display number ans sum
mov x1,x2
bl displayResult
2:
add x4,x4,#1 // increment number
cmp x4,x3 // end ?
ble 1b
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qNMaxi: .quad NMAXI
/***************************************************/
/* display message number */
/***************************************************/
/* x0 contains number 1 */
/* x1 contains number 2 */
displayResult:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
mov x2,x1
ldr x1,qAdrsZoneConv
bl conversion10 // call décimal conversion
ldr x0,qAdrsMessResult
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
mov x3,x0
mov x0,x2
ldr x1,qAdrsZoneConv
bl conversion10 // call décimal conversion
mov x0,x3
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess // display message
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrsMessResult: .quad sMessResult
qAdrsZoneConv: .quad sZoneConv
/***************************************************/
/* compute factors sum */
/***************************************************/
/* x0 contains the number */
decFactor:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
mov x4,#1 // init sum
mov x1,#2 // start factor -> divisor
1:
udiv x2,x0,x1
msub x3,x2,x1,x0 // remainder
cmp x1,x2 // divisor > quotient ?
bgt 3f
cmp x3,#0 // remainder = 0 ?
bne 2f
add x4,x4,x1 // add divisor to sum
cmp x1,x2 // divisor = quotient ?
beq 3f // yes -> end
add x4,x4,x2 // no -> add quotient to sum
2:
add x1,x1,#1 // increment factor
b 1b // and loop
3:
mov x0,x4 // return sum
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/***************************************************/
/* search and store result in array */
/***************************************************/
/* x0 contains the number */
/* x1 contains factors sum */
/* x0 return 1 if find 0 else -1 if error */
searchRes:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
ldr x4,qAdrtResult // array address
mov x2,#0 // indice begin
1:
ldr x3,[x4,x2,lsl #3] // load one result array
cmp x3,#0 // if 0 store new result
beq 2f
cmp x3,x0 // equal ?
beq 3f // find -> return 1
add x2,x2,#1 // increment indice
cmp x2,#TABMAXI // maxi array ?
blt 1b
ldr x0,qAdrszMessErr1 // error
bl affichageMess
mov x0,#-1
b 100f
2:
str x1,[x4,x2,lsl #3]
mov x0,#0 // not find -> store and retun 0
b 100f
3:
mov x0,#1
100:
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrtResult: .quad tResult
qAdrszMessErr1: .quad szMessErr1
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
220 : 284
1184 : 1210
2620 : 2924
5020 : 5564
6232 : 6368
10744 : 10856
12285 : 14595
17296 : 18416
</pre>
 
=={{header|ABC}}==
<syntaxhighlight lang="abc">HOW TO RETURN proper.divisor.sum.table n:
PUT {} IN propdivs
FOR i IN {1..n}: PUT 1 IN propdivs[i]
FOR i IN {2..floor (n/2)}:
PUT i+i IN j
WHILE j<=n:
PUT propdivs[j] + i IN propdivs[j]
PUT i + j IN j
RETURN propdivs
 
PUT 20000 IN maximum
PUT proper.divisor.sum.table maximum IN propdivs
 
FOR cand IN {1..maximum}:
PUT propdivs[cand] IN other
IF cand<other<maximum AND propdivs[other]=cand:
WRITE cand, other/</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
=={{header|Action!}}==
Calculations on a real Atari 8-bit computer take quite long time. It is recommended to use an emulator capable with increasing speed of Atari CPU.
{{libheader|Action! Sieve of Eratosthenes}}
<syntaxhighlight lang="action!">INCLUDE "H6:SIEVE.ACT"
 
CARD FUNC SumDivisors(CARD x)
CARD i,max,sum
 
sum=1 i=2 max=x
WHILE i<max
DO
IF x MOD i=0 THEN
max=x/i
IF i<max THEN
sum==+i+max
ELSEIF i=max THEN
sum==+i
FI
FI
i==+1
OD
RETURN (sum)
 
PROC Main()
DEFINE MAXNUM="20000"
BYTE ARRAY primes(MAXNUM+1)
CARD m,n
 
Put(125) PutE() ;clear the screen
Sieve(primes,MAXNUM+1)
FOR m=1 TO MAXNUM-1
DO
IF primes(m)=0 THEN
n=SumDivisors(m)
IF n<MAXNUM AND primes(n)=0 AND n>m THEN
IF m=SumDivisors(n) THEN
PrintF("%U %U%E",m,n)
FI
FI
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Amicable_pairs.png Screenshot from Atari 8-bit computer]
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|Ada}}==
 
This solution uses the package ''Generic_Divisors'' from the Proper Divisors task
[[http://rosettacode.org/wiki/Proper_divisors#Ada]].
 
<syntaxhighlight lang="ada">with Ada.Text_IO, Generic_Divisors; use Ada.Text_IO;
procedure Amicable_Pairs is
function Same(P: Positive) return Positive is (P);
package Divisor_Sum is new Generic_Divisors
(Result_Type => Natural, None => 0, One => Same, Add => "+");
Num2 : Integer;
begin
for Num1 in 4 .. 20_000 loop
Num2 := Divisor_Sum.Process(Num1);
if Num1 < Num2 then
if Num1 = Divisor_Sum.Process(Num2) then
Put_Line(Integer'Image(Num1) & "," & Integer'Image(Num2));
end if;
end if;
end loop;
end Amicable_Pairs;</syntaxhighlight>
{{Out}}
<pre>
220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416
</pre>
 
=={{header|ALGOL 60}}==
{{works with|A60}}
<syntaxhighlight lang="algol60">
begin
 
comment - return n mod m;
integer procedure mod(n, m);
value n, m; integer n, m;
begin
mod := n - m * entier(n / m);
end;
 
comment - return sum of the proper divisors of n;
integer procedure sumf(n);
value n; integer n;
begin
integer sum, f1, f2;
sum := 1;
f1 := 2;
for f1 := f1 while (f1 * f1) <= n do
begin
if mod(n, f1) = 0 then
begin
sum := sum + f1;
f2 := n / f1;
if f2 > f1 then sum := sum + f2;
end;
f1 := f1 + 1;
end;
sumf := sum;
end;
 
comment - main program begins here;
integer a, b, found;
outstring(1,"Searching up to 20000 for amicable pairs\n");
found := 0;
for a := 2 step 1 until 20000 do
begin
b := sumf(a);
if b > a then
begin
if a = sumf(b) then
begin
found := found + 1;
outinteger(1,a);
outinteger(1,b);
outstring(1,"\n");
end;
end;
end;
outinteger(1,found);
outstring(1,"pairs were found");
 
end
</syntaxhighlight>
{{out}}
<pre>
Searching up to 20000 for amicable pairs
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
8 pairs were found
</pre>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">
BEGIN # find amicable pairs p1, p2 where each is equal to the other's proper divisor sum #
[ 1 : 20 000 ]INT pd sum; # table of proper divisors #
FOR n TO UPB pd sum DO pd sum[ n ] := 1 OD;
FOR i FROM 2 TO UPB pd sum
DO FOR j FROM i + i BY i TO UPB pd sum DO
pd sum[ j ] +:= i
OD
OD;
# find the amicable pairs up to 20 000 #
FOR p1 TO UPB pd sum - 1 DO
INT pd sum p1 = pd sum[ p1 ];
IF pd sum p1 > p1 AND pd sum p1 <= UPB pd sum THEN
IF pd sum[ pd sum p1 ] = p1 THEN
print( ( whole( p1, -6 ), " and ", whole( pd sum p1, -6 ), " are an amicable pair", newline ) )
FI
FI
OD
END
OD</lang>
</syntaxhighlight>
{{out}}
<pre>
220 and 284 are aan amicable pair
1184 and 1210 are aan amicable pair
2620 and 2924 are aan amicable pair
5020 and 5564 are aan amicable pair
6232 and 6368 are aan amicable pair
10744 and 10856 are aan amicable pair
12285 and 14595 are aan amicable pair
17296 and 18416 are aan amicable pair
</pre>
=={{header|ANSI Standard BASIC}}==
 
=={{Transheader|GFAALGOL BasicW}}==
{{Trans|ALGOL 68}}
<syntaxhighlight lang="algolw">
begin % find amicable pairs p1, p2 where each is equal to the other's %
% proper divisor sum %
 
integer MAX_NUMBER;
<lang ANSI Standard BASIC>100 DECLARE EXTERNAL FUNCTION sum_proper_divisors
MAX_NUMBER := 20000;
110 CLEAR
120 !
130 DIM f(20001) ! sum of proper factors for each n
140 FOR i=1 TO 20000
150 LET f(i)=sum_proper_divisors(i)
160 NEXT i
170 ! look for pairs
180 FOR i=1 TO 20000
190 FOR j=i+1 TO 20000
200 IF f(i)=j AND i=f(j) THEN
210 PRINT "Amicable pair ";i;" ";j
220 END IF
230 NEXT j
240 NEXT i
250 !
260 PRINT
270 PRINT "-- found all amicable pairs"
280 END
290 !
300 ! Compute the sum of proper divisors of given number
310 !
320 EXTERNAL FUNCTION sum_proper_divisors(n)
330 !
340 IF n>1 THEN ! n must be 2 or larger
350 LET sum=1 ! start with 1
360 LET root=SQR(n) ! note that root is an integer
370 ! check possible factors, up to sqrt
380 FOR i=2 TO root
390 IF MOD(n,i)=0 THEN
400 LET sum=sum+i ! i is a factor
410 IF i*i<>n THEN ! check i is not actual square root of n
420 LET sum=sum+n/i ! so n/i will also be a factor
430 END IF
440 END IF
450 NEXT i
460 END IF
470 LET sum_proper_divisors = sum
480 END FUNCTION</lang>
 
begin
=={{header|AppleScript}}==
integer array pdSum( 1 :: MAX_NUMBER ); % table of proper divisors %
for i := 1 until MAX_NUMBER do pdSum( i ) := 1;
for i := 2 until MAX_NUMBER do begin
for j := i + i step i until MAX_NUMBER do pdSum( j ) := pdSum( j ) + i
end for_i ;
 
% find the amicable pairs up to 20 000 %
for p1 := 1 until MAX_NUMBER - 1 do begin
integer pdSumP1;
pdSumP1 := pdSum( p1 );
if pdSumP1 > p1 and pdSumP1 <= MAX_NUMBER and pdSum( pdSumP1 ) = p1 then begin
write( i_w := 5, s_w := 0, p1, " and ", pdSumP1, " are an amicable pair" )
end if_pdSumP1_gt_p1_and_le_MAX_NUMBER
end for_p1
end
end.
</syntaxhighlight>
{{out}}
<pre>
220 and 284 are an amicable pair
1184 and 1210 are an amicable pair
2620 and 2924 are an amicable pair
5020 and 5564 are an amicable pair
6232 and 6368 are an amicable pair
10744 and 10856 are an amicable pair
12285 and 14595 are an amicable pair
17296 and 18416 are an amicable pair
</pre>
 
=={{header|AppleScript}}==
===Functional===
{{Trans|JavaScript}}
 
<langsyntaxhighlight AppleScriptlang="applescript">-- AMICABLE PAIRS ------------------------------------------------------------
 
-- amicablePairsUpTo :: Int -> Int
Line 265 ⟶ 845:
end script
end if
end mReturn</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight AppleScriptlang="applescript">{{220, 284}, {1184, 1210}, {2620, 2924}, {5020, 5564},
{6232, 6368}, {10744, 10856}, {12285, 14595}, {17296, 18416}}</langsyntaxhighlight>
----
===Straightforward===
… and about 55 times as fast as the above.
<syntaxhighlight lang="applescript">on properDivisors(n)
set output to {}
if (n > 1) then
set sqrt to n ^ 0.5
set limit to sqrt div 1
if (limit = sqrt) then
set end of output to limit
set limit to limit - 1
end if
repeat with i from limit to 2 by -1
if (n mod i is 0) then
set beginning of output to i
set end of output to n div i
end if
end repeat
set beginning of output to 1
end if
return output
end properDivisors
 
on sumList(listOfNumbers)
script o
property l : listOfNumbers
end script
set sum to 0
repeat with n in o's l
set sum to sum + n
end repeat
return sum
end sumList
 
on amicablePairsBelow(limitPlus1)
script o
property pdSums : {missing value} -- Sums of proper divisors. (Dummy item for 1's.)
end script
set limit to limitPlus1 - 1
repeat with n from 2 to limit
set end of o's pdSums to sumList(properDivisors(n))
end repeat
set output to {}
repeat with n1 from 2 to (limit - 1)
set n2 to o's pdSums's item n1
if ((n1 < n2) and (n2 < limitPlus1) and (o's pdSums's item n2 = n1)) then ¬
set end of output to {n1, n2}
end repeat
return output
end amicablePairsBelow
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
on task()
set output to amicablePairsBelow(20000)
repeat with thisPair in output
set thisPair's contents to join(thisPair, " & ")
end repeat
return join(output, linefeed)
end task
 
task()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"220 & 284
1184 & 1210
2620 & 2924
5020 & 5564
6232 & 6368
10744 & 10856
12285 & 14595
17296 & 18416"</syntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI or android with termux */
/* program amicable.s */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ NMAXI, 20000
.equ TABMAXI, 100
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz " @ : @\n"
szCarriageReturn: .asciz "\n"
szMessErr1: .asciz "Array too small !!"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
tResult: .skip 4 * TABMAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r3,iNMaxi @ load limit
mov r4,#2 @ number begin
1:
mov r0,r4 @ number
bl decFactor @ compute sum factors
cmp r0,r4 @ equal ?
beq 2f
mov r2,r0 @ factor sum 1
bl decFactor
cmp r0,r4 @ equal number ?
bne 2f
mov r0,r4 @ yes -> search in array
mov r1,r2 @ and store sum
bl searchRes
cmp r0,#0 @ find ?
bne 2f @ yes
mov r0,r4 @ no -> display number ans sum
mov r1,r2
bl displayResult
2:
add r4,#1 @ increment number
cmp r4,r3 @ end ?
ble 1b
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iNMaxi: .int NMAXI
/***************************************************/
/* display message number */
/***************************************************/
/* r0 contains number 1 */
/* r1 contains number 2 */
displayResult:
push {r1-r3,lr} @ save registers
mov r2,r1
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
ldr r0,iAdrsMessResult
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
mov r3,r0
mov r0,r2
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
mov r0,r3
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess @ display message
pop {r1-r3,pc} @ restaur des registres
iAdrsMessResult: .int sMessResult
iAdrsZoneConv: .int sZoneConv
/***************************************************/
/* compute factors sum */
/***************************************************/
/* r0 contains the number */
decFactor:
push {r1-r5,lr} @ save registers
mov r5,#1 @ init sum
mov r4,r0 @ save number
mov r1,#2 @ start factor -> divisor
1:
mov r0,r4 @ dividende
bl division
cmp r1,r2 @ divisor > quotient ?
bgt 3f
cmp r3,#0 @ remainder = 0 ?
bne 2f
add r5,r5,r1 @ add divisor to sum
cmp r1,r2 @ divisor = quotient ?
beq 3f @ yes -> end
add r5,r5,r2 @ no -> add quotient to sum
2:
add r1,r1,#1 @ increment factor
b 1b @ and loop
3:
mov r0,r5 @ return sum
pop {r1-r5,pc} @ restaur registers
/***************************************************/
/* search and store result in array */
/***************************************************/
/* r0 contains the number */
/* r1 contains factors sum */
/* r0 return 1 if find 0 else -1 if error */
searchRes:
push {r1-r4,lr} @ save registers
ldr r4,iAdrtResult @ array address
mov r2,#0 @ indice begin
1:
ldr r3,[r4,r2,lsl #2] @ load one result array
cmp r3,#0 @ if 0 store new result
beq 2f
cmp r3,r0 @ equal ?
moveq r0,#1 @ find -> return 1
beq 100f
add r2,r2,#1 @ increment indice
cmp r2,#TABMAXI @ maxi array ?
blt 1b
ldr r0,iAdrszMessErr1 @ error
bl affichageMess
mov r0,#-1
b 100f
2:
str r1,[r4,r2,lsl #2]
mov r0,#0 @ not find -> store and retun 0
100:
pop {r1-r4,pc} @ restaur registers
iAdrtResult: .int tResult
iAdrszMessErr1: .int szMessErr1
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
220 : 284
1184 : 1210
2620 : 2924
5020 : 5564
6232 : 6368
10744 : 10856
12285 : 14595
17296 : 18416
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">properDivs: function [x] ->
(factors x) -- x
 
amicable: function [x][
y: sum properDivs x
if and? x = sum properDivs y
x <> y
-> return @[x,y]
return ø
]
 
amicables: []
 
loop 1..20000 'n [
am: amicable n
if am <> ø
-> 'amicables ++ @[sort am]
]
 
print unique amicables</syntaxhighlight>
 
{{out}}
 
<pre>[220 284] [1184 1210] [2620 2924] [5020 5564] [6232 6368] [10744 10856] [12285 14595] [17296 18416]</pre>
 
=={{header|ATS}}==
<syntaxhighlight lang="ats">
<lang ATS>
(* ****** ****** *)
//
Line 376 ⟶ 1,230:
 
(* ****** ****** *)
</syntaxhighlight>
</lang>
 
{{out}}
Line 391 ⟶ 1,245:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight lang="d">SetBatchLines -1
Loop, 20000
{
Line 443 ⟶ 1,297:
}
MsgBox % final
ExitApp</langsyntaxhighlight>
{{out}}
<pre>
Line 457 ⟶ 1,311:
 
=={{header|AWK}}==
<langsyntaxhighlight lang="awk">
#!/bin/awk -f
function sumprop(num, i,sum,root) {
Line 485 ⟶ 1,339:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 499 ⟶ 1,353:
17296 18416
</pre>
 
 
=={{header|BASIC}}==
==={{header|ANSI BASIC}}===
{{trans|GFA Basic}}
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">100 DECLARE EXTERNAL FUNCTION sum_proper_divisors
110 CLEAR
120 !
130 DIM f(20001) ! sum of proper factors for each n
140 FOR i=1 TO 20000
150 LET f(i)=sum_proper_divisors(i)
160 NEXT i
170 ! look for pairs
180 FOR i=1 TO 20000
190 FOR j=i+1 TO 20000
200 IF f(i)=j AND i=f(j) THEN
210 PRINT "Amicable pair ";i;" ";j
220 END IF
230 NEXT j
240 NEXT i
250 !
260 PRINT
270 PRINT "-- found all amicable pairs"
280 END
290 !
300 ! Compute the sum of proper divisors of given number
310 !
320 EXTERNAL FUNCTION sum_proper_divisors(n)
330 !
340 IF n>1 THEN ! n must be 2 or larger
350 LET sum=1 ! start with 1
360 LET root=SQR(n) ! note that root is an integer
370 ! check possible factors, up to sqrt
380 FOR i=2 TO root
390 IF MOD(n,i)=0 THEN
400 LET sum=sum+i ! i is a factor
410 IF i*i<>n THEN ! check i is not actual square root of n
420 LET sum=sum+n/i ! so n/i will also be a factor
430 END IF
440 END IF
450 NEXT i
460 END IF
470 LET sum_proper_divisors = sum
480 END FUNCTION</syntaxhighlight>
{{out}}
<pre>
Amicable pair 220 284
Amicable pair 1184 1210
Amicable pair 2620 2924
Amicable pair 5020 5564
Amicable pair 6232 6368
Amicable pair 10744 10856
Amicable pair 12285 14595
Amicable pair 17296 18416
 
-- found all amicable pairs
</pre>
 
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">function SumProperDivisors(number)
if number < 2 then return 0
sum = 0
for i = 1 to number \ 2
if number mod i = 0 then sum += i
next i
return sum
end function
 
dim sum(20000)
for n = 1 to 19999
sum[n] = SumProperDivisors(n)
next n
 
print "The pairs of amicable numbers below 20,000 are :"
print
 
for n = 1 to 19998
f = sum[n]
if f <= n or f < 1 or f > 19999 then continue for
if f = sum[n] and n = sum[f] then
print rjust(string(n), 5); " and "; sum[n]
end if
next n
end</syntaxhighlight>
{{out}}
<pre>The pairs of amicable numbers below 20,000 are :
 
220 and 284
1184 and 1210
2620 and 2924
5020 and 5564
6232 and 6368
10744 and 10856
12285 and 14595
17296 and 18416</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="qbasic">100 cls : rem 10 HOME for Applesoft BASIC
110 print "The pairs of amicable numbers below 20,000 are :"
120 print
130 size = 18500
140 for n = 1 to size
150 m = amicable(n)
160 if m > n and amicable(m) = n then
170 print using "#####";n;
180 print " and ";
190 print using "#####";m
200 endif
210 next
220 end
230 function amicable(nr)
240 suma = 1
250 for d = 2 to sqr(nr)
260 if nr mod d = 0 then suma = suma+d+nr/d
270 next
280 amicable = suma
290 end function</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public sum[19999] As Integer
 
Public Sub Main()
Dim n As Integer, f As Integer
For n = 0 To 19998
sum[n] = SumProperDivisors(n)
Next
Print "The pairs of amicable numbers below 20,000 are :\n"
For n = 0 To 19998
' f = SumProperDivisors(n)
f = sum[n]
If f <= n Or f < 1 Or f > 19999 Then Continue
If f = sum[n] And n = sum[f] Then
Print Format$(Str$(n), "#####"); " And "; Format$(Str$(sum[n]), "#####")
End If
Next
End
 
Function SumProperDivisors(number As Integer) As Integer
If number < 2 Then Return 0
Dim sum As Integer = 0
For i As Integer = 1 To number \ 2
If number Mod i = 0 Then sum += i
Next
Return sum
End Function</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">FUNCTION amicable (nr)
suma = 1
FOR d = 2 TO SQR(nr)
IF nr MOD d = 0 THEN suma = suma + d + nr / d
NEXT
amicable = suma
END FUNCTION
 
PRINT "The pairs of amicable numbers below 20,000 are :"
PRINT
 
size = 18500
FOR n = 1 TO size
m = amicable(n)
IF m > n AND amicable(m) = n THEN
PRINT USING "##### and #####"; n; m
END IF
NEXT
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">FUNCTION amicable(nr)
LET suma = 1
FOR d = 2 TO SQR(nr)
IF REMAINDER(nr, d) = 0 THEN
LET suma = suma + d + nr / d
END IF
NEXT d
LET amicable = suma
END FUNCTION
 
PRINT "The pairs of amicable numbers below 20,000 are :"
PRINT
 
LET size = 18500
FOR n = 1 TO size
LET m = amicable(n)
IF m > n AND amicable(m) = n THEN PRINT USING "##### and #####": n, m
NEXT n
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
manifest $(
MAXIMUM = 20000
$)
 
// Calculate proper divisors for 1..N
let propDivSums(n) = valof
$( let v = getvec(n)
for i = 1 to n do v!i := 1
for i = 2 to n/2 do
$( let j = i*2
while j < n do
$( v!j := v!j + i
j := j + i
$)
$)
resultis v
$)
 
// Are A and B an amicable pair, given the list of sums of proper divisors?
let amicable(pdiv, a, b) = a = pdiv!b & b = pdiv!a
 
let start() be
$( let pds = propDivSums(MAXIMUM)
for x = 1 to MAXIMUM do
for y = x+1 to MAXIMUM do
if amicable(pds, x, y) do
writef("%N, %N*N", x, y)
$)</syntaxhighlight>
 
{{out}}
<pre>220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|Befunge}}==
 
<syntaxhighlight lang="befunge">v_@#-*8*:"2":$_:#!2#*8#g*#6:#0*#!:#-*#<v>*/.55+,
1>$$:28*:*:*%\28*:*:*/`06p28*:*:*/\2v %%^:*:<>*v
+|!:-1g60/*:*:*82::+**:*:<<>:#**#8:#<*^>.28*^8 :
:v>>*:*%/\28*:*:*%+\v>8+#$^#_+#`\:#0<:\`1/*:*2#<
2v^:*82\/*:*:*82:::_v#!%%*:*:*82\/*:*:*82::<_^#<
>>06p:28*:*:**1+01-\>1+::28*:*:*/\28*:*:*%:*\`!^</syntaxhighlight>
 
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|C}}==
Line 505 ⟶ 1,628:
 
The program will overflow and error in all sorts of ways when given a commandline argument >= UINT_MAX/2 (generally 2^31)
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 560 ⟶ 1,683:
printf("\nTop %u count : %u\n",top,cnt);
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 586 ⟶ 1,709:
real 0m16.285s
user 0m16.156s
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
 
namespace RosettaCode.AmicablePairs
{
internal static class Program {
private const int Limit = 20000;
 
private static void Main()
{
foreach (var pair in GetPairs(Limit))
{
Console.WriteLine("{0} {1}", pair.Item1, pair.Item2);
}
}
 
private static IEnumerable<Tuple<int, int>> GetPairs(int max)
{
List<int> divsums =
Enumerable.Range(0, max + 1).Select(i => ProperDivisors(i).Sum()).ToList();
for(int i=1; i<divsums.Count; i++) {
int sum = divsums[i];
if(i < sum && sum <= divsums.Count && divsums[sum] == i) {
yield return new Tuple<int, int>(i, sum);
}
}
}
 
private static IEnumerable<int> ProperDivisors(int number)
{
return
Enumerable.Range(1, number / 2)
.Where(divisor => number % divisor == 0);
}
}
}</syntaxhighlight>
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <vector>
#include <unordered_map>
Line 638 ⟶ 1,811:
std::cout << count << " amicable pairs discovered" << std::endl;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 650 ⟶ 1,823:
[17296, 18416]
8 amicable pairs discovered
</pre>
 
=={{header|C sharp}}==
<lang csharp>using System;
using System.Collections.Generic;
using System.Linq;
 
namespace RosettaCode.AmicablePairs
{
internal static class Program {
private const int Limit = 20000;
 
private static void Main()
{
foreach (var pair in GetPairs(Limit))
{
Console.WriteLine("{0} {1}", pair.Item1, pair.Item2);
}
}
 
private static IEnumerable<Tuple<int, int>> GetPairs(int max)
{
List<int> divsums =
Enumerable.Range(0, max + 1).Select(i => ProperDivisors(i).Sum()).ToList();
for(int i=1; i<divsums.Count; i++) {
int sum = divsums[i];
if(i < sum && sum <= divsums.Count && divsums[sum] == i) {
yield return new Tuple<int, int>(i, sum);
}
}
}
 
private static IEnumerable<int> ProperDivisors(int number)
{
return
Enumerable.Range(1, number / 2)
.Where(divisor => number % divisor == 0);
}
}
}</lang>
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="lisp">
(ns example
(:gen-class))
Line 727 ⟶ 1,850:
(doseq [q find-pairs]
(println q))
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 739 ⟶ 1,862:
#{10744 10856}
</pre>
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Generate proper divisors from 1 to max
proper_divisors = proc (max: int) returns (array[int])
divs: array[int] := array[int]$fill(1, max, 0)
for i: int in int$from_to(1, max/2) do
for j: int in int$from_to_by(i*2, max, i) do
divs[j] := divs[j] + i
end
end
return(divs)
end proper_divisors
 
% Are A and B and amicable pair, given the proper divisors?
amicable = proc (divs: array[int], a, b: int) returns (bool)
return(divs[a] = b & divs[b] = a)
end amicable
 
% Find all amicable pairs up to 20 000
start_up = proc ()
max = 20000
po: stream := stream$primary_output()
divs: array[int] := proper_divisors(max)
for a: int in int$from_to(1, max) do
for b: int in int$from_to(a+1, max) do
if amicable(divs, a, b) then
stream$putl(po, int$unparse(a) || ", " || int$unparse(b))
end
end
end
end start_up</syntaxhighlight>
{{out}}
<pre>220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(let ((cache (make-hash-table)))
(defun sum-proper-divisors (n)
(or (gethash n cache)
Line 755 ⟶ 1,919:
collect (list x sum-divs)))
 
(amicable-pairs-up-to 20000)</langsyntaxhighlight>
{{out}}
<pre>((220 284) (1184 1210) (2620 2924) (5020 5564) (6232 6368) (10744 10856)
(12285 14595) (17296 18416))</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
const LIMIT := 20000;
 
# Calculate sums of proper divisors
var divSum: uint16[LIMIT + 1];
var i: @indexof divSum;
var j: @indexof divSum;
 
i := 2;
while i <= LIMIT loop
divSum[i] := 1;
i := i + 1;
end loop;
 
i := 2;
while i <= LIMIT/2 loop
j := i * 2;
while j <= LIMIT loop
divSum[j] := divSum[j] + i;
j := j + i;
end loop;
i := i + 1;
end loop;
 
# Test each pair
i := 2;
while i <= LIMIT loop
j := i + 1;
while j <= LIMIT loop
if divSum[i] == j and divSum[j] == i then
print_i32(i as uint32);
print(", ");
print_i32(j as uint32);
print_nl();
end if;
j := j + 1;
end loop;
i := i + 1;
end loop;</syntaxhighlight>
{{out}}
<pre>220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|Crystal}}==
<syntaxhighlight lang="crystal">
<lang Crystal>
MX = 524_000_000
N = Math.sqrt(MX).to_u32
Line 782 ⟶ 1,997:
end
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 802 ⟶ 2,017:
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">void main() @safe /*@nogc*/ {
import std.stdio, std.algorithm, std.range, std.typecons, std.array;
 
Line 815 ⟶ 2,030:
writefln("Amicable pair: %d and %d with proper divisors:\n %s\n %s",
n, divSum, properDivs(n), properDivs(divSum));
}</langsyntaxhighlight>
{{out}}
<pre>Amicable pair: 220 and 284 with proper divisors:
Line 841 ⟶ 2,056:
[1, 2, 4, 8, 16, 23, 46, 47, 92, 94, 184, 188, 368, 376, 752, 1081, 2162, 4324, 8648]
[1, 2, 4, 8, 16, 1151, 2302, 4604, 9208]</pre>
 
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Amicable_pairs#Pascal Pascal].
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">/* Fill a given array such that for each N,
* P[n] is the sum of proper divisors of N */
proc nonrec propdivs([*] word p) void:
word i, j, max;
max := dim(p,1)-1;
for i from 0 upto max do p[i] := 0 od;
for i from 1 upto max/2 do
for j from i*2 by i upto max do
p[j] := p[j] + i
od
od
corp
 
/* Find all amicable pairs between 0 and 20,000 */
proc nonrec main() void:
word MAX = 20000;
word i, j;
[MAX] word p;
propdivs(p);
for i from 1 upto MAX-1 do
for j from i+1 upto MAX-1 do
if p[i]=j and p[j]=i then
writeln(i:5, ", ", j:5)
fi
od
od
corp</syntaxhighlight>
{{out}}
<pre> 220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight lang="easylang">
func sumdivs n .
sum = 1
for d = 2 to sqrt n
if n mod d = 0
sum += d + n div d
.
.
return sum
.
for n = 1 to 20000
m = sumdivs n
if m > n
if sumdivs m = n
print n & " " & m
.
.
.
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; using (sum-divisors) from math.lib
 
Line 862 ⟶ 2,141:
→ (... (802725 . 863835) (879712 . 901424) (898216 . 980984) (947835 . 1125765) (998104 . 1043096))
 
</syntaxhighlight>
</lang>
 
=={{header|Ela}}==
{{trans|Haskell}}
<langsyntaxhighlight lang="ela">open monad io number list
 
divisors n = filter ((0 ==) << (n `mod`)) [1..(n `div` 2)]
Line 873 ⟶ 2,152:
pairs = [(n, m) \\ (n, nd) <- divs, (m, md) <- divs | n < m && nd == m && md == n]
 
do putLn pairs ::: IO</langsyntaxhighlight>
 
{{out}}
<pre>
[(220,284),(1184,1210),(2620,2924),(5020,5564),(6232,6368),(10744,10856),(12285,14595),(17296,18416)]</pre>
 
=={{header|Elena}}==
{{trans|C#}}
ELENA 6.x :
<syntaxhighlight lang="elena">import extensions;
import system'routines;
const int N = 20000;
extension op
{
ProperDivisors
= Range.new(1,self / 2).filterBy::(n => self.mod(n) == 0);
get AmicablePairs()
{
var divsums := Range
.new(0, self + 1)
.selectBy::(i => i.ProperDivisors.summarize(Integer.new()))
.toArray();
^ 1.repeatTill(divsums.Length)
.filterBy::(i)
{
var ii := i;
var sum := divsums[i];
^ (i < sum) && (sum < divsums.Length) && (divsums[sum] == i)
}
.selectBy::(i => new { Item1 = i; Item2 = divsums[i]; })
}
}
public program()
{
N.AmicablePairs.forEach::(pair)
{
console.printLine(pair.Item1, " ", pair.Item2)
}
}</syntaxhighlight>
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
=== Alternative variant using strong-typed closures ===
<syntaxhighlight lang="elena">import extensions;
import system'routines'stex;
import system'collections;
const int N = 20000;
extension op : IntNumber
{
Enumerator<int> ProperDivisors
= new Range(1,self / 2).filterBy::(int n => self.mod(n) == 0);
get AmicablePairs()
{
auto divsums := new List<int>(
cast Enumerator<int>(
new Range(0, self).selectBy::(int i => i.ProperDivisors.summarize(0))));
^ new Range(0, divsums.Length)
.filterBy::(int i)
{
auto sum := divsums[i];
^ (i < sum) && (sum < divsums.Length) && (divsums[sum] == i)
}
.selectBy::(int i => new Tuple<int,int>(i,divsums[i]));
}
}
public program()
{
N.AmicablePairs.forEach::(var Tuple<int,int> pair)
{
console.printLine(pair.Item1, " ", pair.Item2)
}
}</syntaxhighlight>
 
=== Alternative variant using yield enumerator ===
<syntaxhighlight lang="elena">import extensions;
import system'routines'stex;
import system'collections;
const int Limit = 20000;
 
singleton ProperDivisors
{
Enumerator<int> function(int number)
= Range.new(1, number / 2).filterBy::(int n => number.mod(n) == 0);
}
public sealed AmicablePairs
{
int max;
constructor(int max)
{
this max := max
}
yieldable Tuple<int, int> next()
{
List<int> divsums := Range.new(0, max + 1).selectBy::(int i => ProperDivisors(i).summarize(0));
for (int i := 1; i < divsums.Length; i += 1)
{
int sum := divsums[i];
if(i < sum && sum <= divsums.Length && divsums[sum] == i) {
$yield new Tuple<int, int>(i, sum);
}
};
^ nil
}
}
public program()
{
auto e := new AmicablePairs(Limit);
for(auto pair := e.next(); pair != nil)
{
console.printLine(pair.Item1, " ", pair.Item2)
}
}</syntaxhighlight>
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|Elixir}}==
{{works with|Elixir|1.2}}
With [[proper_divisors#Elixir]] in place:
<langsyntaxhighlight lang="elixir">defmodule Proper do
def divisors(1), do: []
def divisors(n), do: [1 | divisors(2,n,:math.sqrt(n))] |> Enum.sort
Line 895 ⟶ 2,318:
Enum.filter(map, fn {n,sum} -> map[sum] == n and n < sum end)
|> Enum.sort
|> Enum.each(fn {i,j} -> IO.puts "#{i} and #{j}" end)</langsyntaxhighlight>
 
{{out}}
Line 913 ⟶ 2,336:
Very slow solution. Same functions by and large as in proper divisors and co.
 
<langsyntaxhighlight lang="erlang">
-module(properdivs).
-export([amicable/1,divs/1,sumdivs/1]).
Line 949 ⟶ 2,372:
sumdivs(N) -> lists:sum(divs(N)).
</langsyntaxhighlight>
{{out}}
<pre>
Line 985 ⟶ 2,408:
[See the talk section &nbsp; '''amicable pairs, out of order''' &nbsp; for this Rosetta Code task.]
 
<langsyntaxhighlight lang="erlang">
friendly(Limit) ->
List = [{X,properdivs:sumdivs(X)} || X <- lists:seq(3,Limit)],
Line 994 ⟶ 2,417:
io:format("L: ~w~n", [Final]).
 
</syntaxhighlight>
</lang>
{{output}}
 
Line 1,004 ⟶ 2,427:
 
We might answer a challenge by saying:
<langsyntaxhighlight lang="erlang">
friendly(Limit) ->
List = [{X,properdivs:sumdivs(X)} || X <- lists:seq(3,Limit)],
Line 1,025 ⟶ 2,448:
end.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,042 ⟶ 2,465:
 
=={{header|ERRE}}==
<langsyntaxhighlight ERRElang="erre">PROGRAM AMICABLE
 
CONST LIMIT=20000
Line 1,069 ⟶ 2,492:
IF (N=M2 AND N<M1) THEN PRINT(N,M1)
END FOR
END PROGRAM</langsyntaxhighlight>
{{out}}
<pre>Amicable pairs < 20000
Line 1,081 ⟶ 2,504:
17296 18416
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
[2..20000 - 1]
|> List.map (fun n-> n, ([1..n/2] |> List.filter (fun x->n % x = 0) |> List.sum))
|> List.map (fun (a,b) ->if a<b then (a,b) else (b,a))
|> List.groupBy id
|> List.map snd
|> List.filter (List.length >> ((=) 2))
|> List.map List.head
|> List.iter (printfn "%A")
</syntaxhighlight>
{{out}}
<pre>
(220, 284)
(1184, 1210)
(2620, 2924)
(5020, 5564)
(6232, 6368)
(10744, 10856)
(12285, 14595)
(17296, 18416)
</pre>
 
=={{header|Factor}}==
This solution focuses on the language's namesake: factoring code into small words which are subsequently composed to form more powerful — yet just as simple — words. Using this approach, the final word naturally arrives at the solution. This is often referred to as the bottom-up approach, which is a way in which Factor (and other concatenative languages) commonly differs from other languages.
 
<syntaxhighlight lang="factor">
USING: grouping math.primes.factors math.ranges ;
 
: pdivs ( n -- seq ) divisors but-last ;
: dsum ( n -- sum ) pdivs sum ;
: dsum= ( n m -- ? ) dsum = ;
: both-dsum= ( n m -- ? ) [ dsum= ] [ swap dsum= ] 2bi and ;
: amicable? ( n m -- ? ) [ both-dsum= ] [ = not ] 2bi and ;
: drange ( -- seq ) 2 20000 [a,b) ;
: dsums ( -- seq ) drange [ dsum ] map ;
: is-am?-seq ( -- seq ) dsums drange [ amicable? ] 2map ;
: am-nums ( -- seq ) t is-am?-seq indices ;
: am-nums-c ( -- seq ) am-nums [ 2 + ] map ;
: am-pairs ( -- seq ) am-nums-c 2 group ;
: print-am ( -- ) am-pairs [ >array . ] each ;
 
print-am
</syntaxhighlight>
{{out}}
<pre>
{ 220 284 }
{ 1184 1210 }
{ 2620 2924 }
{ 5020 5564 }
{ 6232 6368 }
{ 10744 10856 }
{ 12285 14595 }
{ 17296 18416 }
</pre>
 
=={{header|Forth}}==
 
{{works with|gforth|0.7.3}}
 
===Direct approach===
Calculate many times the divisors.
 
<syntaxhighlight lang="forth">: proper-divisors ( n -- 1..n )
dup 2 / 1+ 1 ?do
dup i mod 0= if i swap then
loop drop ;
 
: divisors-sum ( 1..n -- n )
dup 1 = if exit then
begin over + swap
1 = until ;
 
: pair ( n -- n )
dup 1 = if exit then
proper-divisors divisors-sum ;
 
: ?paired ( n -- t | f )
dup pair 2dup pair
= >r < r> and ;
 
: amicable-list
1+ 1 do
i ?paired if cr i . i pair . then
loop ;
 
20000 amicable-list</syntaxhighlight>
 
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416 ok</pre>
 
===Storage approach===
Use memory to store sum of divisors, a little quicker.
 
<syntaxhighlight lang="forth">variable amicable-table
 
: proper-divisors ( n -- 1..n )
dup 1 = if exit then ( not really but useful )
dup 2 / 1+ 1 ?do
dup i mod 0= if i swap then
loop drop ;
 
: divisors-sum ( 1..n -- n )
dup 1 = if exit then
begin over + swap
1 = until ;
 
: build-amicable-table
here amicable-table !
1+ dup ,
1 do
i proper-divisors divisors-sum ,
loop ;
 
: paired cells amicable-table @ + @ ;
 
: .amicables
amicable-table @ @ 1 do
i paired paired i =
i paired i > and
if cr i . i paired . then
loop ;
 
: amicable-list
build-amicable-table .amicables ;
 
20000 amicable-list</syntaxhighlight>
 
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416 ok</pre>
 
=={{header|Fortran}}==
Line 1,099 ⟶ 2,667:
Amicable! 17296 18416
 
<syntaxhighlight lang="fortran">
<lang FORTRAN>
MODULE FACTORSTUFF !This protocol evades the need for multiple parameters, or COMMON, or one shapeless main line...
Concocted by R.N.McLean, MMXV.
Line 1,166 ⟶ 2,734:
END DO !On to the next.
END !Done.
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
===using Mod===
<langsyntaxhighlight lang="freebasic">
' FreeBASIC v1.05.0 win64
 
Line 1,206 ⟶ 2,774:
Sleep
End
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,222 ⟶ 2,790:
</pre>
===using "Sieve of Erathosthenes" style===
<langsyntaxhighlight lang="freebasic">' version 04-10-2016
' compile with: fbc -s console
' replaced the function with 2 FOR NEXT loops
Line 1,259 ⟶ 2,827:
Print : Print : Print " Hit any key to end program"
Sleep
End</langsyntaxhighlight>
<pre>
The pairs of amicable numbers below 20,000 are :
Line 1,271 ⟶ 2,839:
12285 and 14595
17296 and 18416</pre>
 
=={{header|Frink}}==
This example uses Frink's built-in efficient factorization algorithms. It can work for arbitrarily large numbers.
<syntaxhighlight lang="frink">
n = 1
seen = new set
 
do
{
n = n + 1
if seen.contains[n]
next
 
sum = sum[allFactors[n, true, false, false]]
if sum != n and sum[allFactors[sum, true, false, false]] == n
{
println["$n, $sum"]
seen.put[sum]
}
} while n <= 20000
</syntaxhighlight>
{{out}}
<pre>
220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416
</pre>
 
=={{header|Futhark}}==
 
{{output?}}
 
This program is much too parallel and manifests all the pairs, which requires a giant amount of memory.
 
<syntaxhighlight lang="text">
fun divisors(n: int): []int =
filter (fn x => n%x == 0) (map (1+) (iota (n/2)))
Line 1,293 ⟶ 2,895:
let amicable = filter amicable (map (getPair divs) (iota (upper*upper)))
in map (fn (np,mp) => [#1 np, #1 mp]) amicable
</syntaxhighlight>
</lang>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn Sigma( n as long ) as long
long i, root, sum = 1
if n == 1 then exit fn = 0
root = sqr(n)
for i = 2 to root
if ( n mod i == 0 ) then sum += i + n/i
next
if root * root == n then sum -= root
end fn = sum
 
void local fn CalculateAmicablePairs( limit as long )
long i, m
printf @"\nAmicable pairs through %ld are:\n", limit
for i = 2 to limit
m = fn Sigma(i)
if ( m > i )
if ( fn Sigma(m) == i ) then printf @"%6ld and %ld", i, m
end if
next
end fn
 
CFTimeInterval t
t = fn CACurrentMediaTime
fn CalculateAmicablePairs( 20000 )
printf @"\nCompute time: %.3f ms",(fn CACurrentMediaTime-t)*1000
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Amicable pairs through 20000 are:
 
220 and 284
1184 and 1210
2620 and 2924
5020 and 5564
6232 and 6368
10744 and 10856
12285 and 14595
17296 and 18416
 
Compute time: 28.701 ms
</pre>
 
 
=={{header|GFA Basic}}==
 
<syntaxhighlight lang="text">
OPENW 1
CLEARW 1
Line 1,339 ⟶ 2,991:
RETURN sum%
ENDFUNC
</syntaxhighlight>
</lang>
 
Output is:
Line 1,354 ⟶ 3,006:
-- found all amicable pairs
</pre>
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
<lang Go>
 
package main
import "fmt"
 
import "math"
func mainpfacSum(i int) int {
sum := 0
var i int
for p := 1; p <= i/2; p++ {
var a [200001]int
if i%p == 0 {
a[0]=0
sum += p
for i=1;i<=20000;i++{
}
a[i]=pfac_sum(i)
}
}
return sum
fmt.Println("The amicable pairs are:")
for i=1;i<=20000;i++{
if (i==a[a[i]])&&(i<a[i]){
fmt.Printf("%d , %d\n",i,a[i])
}
}
}
 
func pfac_sum(i int) int {
func main() {
var p,sum=1,0
var a[20000]int
for pi := 1;p<= i/2 < 20000;p i++ {
x : a[i] = float64pfacSum(i)
}
y := float64(p)
fmt.Println("The amicable pairs below 20,000 are:")
if math.Mod(x,y)==0{
for n := 2; n < 19999; n++ {
sum= sum+p
m := a[n]
}
if m > n && m < 20000 && n == a[m] {
}
fmt.Printf(" %5d and %5d\n", n, m)
return sum
}
}
}
</lang>
}</syntaxhighlight>
Output:
 
{{output}}
<pre>
The amicable pairs below 20,000 are:
220 ,and 284
1184 ,and 1210
2620 ,and 2924
5020 ,and 5564
6232 ,and 6368
10744 ,and 10856
12285 ,and 14595
17296 ,and 18416
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">divisors :: (Integral a) => a -> [a]
divisors n = filter ((0 ==) . (n `mod`)) [1 .. (n `div` 2)]
 
Line 1,408 ⟶ 3,059:
pairs = [(n, m) | (n, nd) <- divs, (m, md) <- divs,
n < m, nd == m, md == n]
print pairs</langsyntaxhighlight>
{{out}}
<pre>[(220,284),(1184,1210),(2620,2924),(5020,5564),(6232,6368),(10744,10856),(12285,14595),(17296,18416)]</pre>
 
 
Or, deriving proper divisors above the square root fromas those belowcofactors (for better performance)
 
<syntaxhighlight lang="haskell">import Data.Bool (bool)
<lang Haskell>amicablePairsUpTo :: Int -> [(Int, Int)]
 
amicablePairsUpTo :: Int -> [(Int, Int)]
amicablePairsUpTo n =
let sigma = sum . properDivisors
foldl
in [1 (\a.. xn] ->>=
(\x let y = sigma x->
in if (x <let y) &&= (sigma y == x)
in bool then a ++[] [(x, y)] (x < y && x == sigma y))
else a)
[]
[1 .. n]
 
properDivisors
sigma :: Int -> Int
:: Integral a
sigma = sum . propDivs
=> a -> [a]
where
properDivisors n =
propDivs :: Int -> [Int]
let root = (floor . sqrt) (fromIntegral n :: Double)
propDivs n
|lows n= <filter 2((0 ==) . rem n) [1 .. root]
in init $
| otherwise =
lows ++ drop (bool 0 1 (root * root == n)) (reverse (quot n <$> lows))
lows ++
drop
(if isPerfect
then 1
else 0)
(reverse (quot n <$> tail lows))
where
iRoot = floor (sqrt $ fromIntegral n)
isPerfect = iRoot * iRoot == n
lows = filter ((== 0) . rem n) [1 .. iRoot]
 
main :: IO ()
main = mapM_ print $ amicablePairsUpTo 20000</langsyntaxhighlight>
 
{{Out}}
<pre>(220,284)
Line 1,461 ⟶ 3,101:
[[Proper divisors#J|Proper Divisor implementation]]:
 
<langsyntaxhighlight Jlang="j">factors=: [: /:~@, */&>@{@((^ i.@>:)&.>/)@q:~&__
properDivisors=: factors -. -.&1</langsyntaxhighlight>
 
(properDivisors is all factors except "the number itself when that number is greater than 1".)
 
Amicable pairs:
 
<langsyntaxhighlight Jlang="j"> 1 + 0 20000($ #: I. @,) (</~@i.@# * (* |:))(=/ +/@properDivisors@>) 1 + i.20000
220 284
1184 1210
Line 1,474 ⟶ 3,116:
10744 10856
12285 14595
17296 18416</langsyntaxhighlight>
 
Explanation: We generate sequence of positive integers, starting from 1, and compare each of them to the sum of proper divisors of each of them. Then we fold this comparison diagonally, keeping only the values where the comparison was equal both ways and the smaller value appears before the larger value. Finally, indices into true values give us our amicable pairs.
 
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
Line 1,504 ⟶ 3,148:
return LongStream.rangeClosed(1, (n + 1) / 2).filter(i -> n % i == 0).sum();
}
}</langsyntaxhighlight>
 
<pre>220 284
Line 1,519 ⟶ 3,163:
===ES5===
 
<langsyntaxhighlight JavaScriptlang="javascript">(function (max) {
// Proper divisors
Line 1,579 ⟶ 3,223:
) + '\n\n' + JSON.stringify(pairs);
})(20000);</langsyntaxhighlight>
 
{{out}}
Line 1,604 ⟶ 3,248:
|}
 
<langsyntaxhighlight JavaScriptlang="javascript">[[220,284],[1184,1210],[2620,2924],[5020,5564],
[6232,6368],[10744,10856],[12285,14595],[17296,18416]]</langsyntaxhighlight>
 
===ES6===
 
<langsyntaxhighlight JavaScriptlang="javascript">(max() => {
'use strict';
 
// amicablePairsUpTo :: Int -> [(Int, Int)]
letconst amicablePairsUpTo = maxn => {
rangeconst sigma = compose(1sum, maxproperDivisors);
return enumFromTo(1)(n).mapflatMap(x => properDivisors(x){
.reduce((a,const b)y => a + b, 0)sigma(x);
.reduce((a, m, i, lst) return x < y && x =>== {sigma(y) ? ([
let n = i +[x, 1;y]
]) : [];
});
};
 
// properDivisors :: Int -> [Int]
return (m > n) && lst[m - 1] === n ?
const properDivisors = n => {
a.concat([[n, m]]) : a;
}, []),const
rRoot = Math.sqrt(n),
intRoot = Math.floor(rRoot),
lows = enumFromTo(1)(intRoot)
.filter(x => 0 === (n % x));
return lows.concat(lows.map(x => n / x)
.reverse()
.slice((rRoot === intRoot) | 0, -1));
};
 
 
// TEST -----------------------------------------------
// properDivisors :: Int -> [Int]
properDivisors = n => {
if (n < 2) return [];
else {
let rRoot = Math.sqrt(n),
intRoot = Math.floor(rRoot),
blnPerfectSquare = rRoot === intRoot,
 
// main :: IO ()
lows = range(1, intRoot)
const .filter(xmain => (n % x) === 0);>
console.log(unlines(
amicablePairsUpTo(20000).map(JSON.stringify)
));
 
return lows.concat(lows.slice(1)
.map(x => n / x)
.reverse()
.slice(blnPerfectSquare | 0));
}
},
 
// GENERIC FUNCTIONS ----------------------------------
// Int -> Int -> Maybe Int -> [Int]
range = (m, n, step) => {
let d = (step || 1) * (n >= m ? 1 : -1);
 
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
return Array.from({
const compose = (...fs) =>
length: Math.floor((n - m) / d) + 1
x => }, fs.reduceRight(_(a, if) => m + f(ia), * d)x);
}
 
 
// enumFromTo :: Int -> Int -> [Int]
return amicablePairsUpTo(max);
const enumFromTo = m => n =>
Array.from({
length: 1 + n - m
}, (_, i) => m + i);
 
})(20000);</lang>
 
// sum :: [Num] -> Num
const sum = xs => xs.reduce((a, x) => a + x, 0);
 
 
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>[220,284]
<lang JavaScript>[[220, 284], [1184, 1210], [2620, 2924], [5020, 5564],
[1184,1210]
[6232, 6368], [10744, 10856], [12285, 14595], [17296, 18416]]</lang>
[2620,2924]
[5020,5564]
[6232,6368]
[10744,10856]
[12285,14595]
[17296,18416]</pre>
 
=={{header|jq}}==
<langsyntaxhighlight lang="jq"># unordered
def proper_divisors:
. as $n
Line 1,686 ⟶ 3,350:
end ;
 
task(20000)</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -c -n -f amicable_pairs.jq
220 and 284 are amicable
1184 and 1210 are amicable
Line 1,696 ⟶ 3,360:
10744 and 10856 are amicable
12285 and 14595 are amicable
17296 and 18416 are amicable</langsyntaxhighlight>
 
=={{header|Julia}}==
Given <code>factor</code>, it is not necessary to calculate the individual divisors to compute their sum. See [[Abundant,_deficient_and_perfect_number_classifications#Julia|Abundant, deficient and perfect number classifications]] for the details.
It is safe to exclude primes from consideration; their proper divisor sum is always 1. This code also uses a minor trick to ensure that none of the numbers identified are above the limit. All numbers in the range are checked for an amicable partner, but the pair is cataloged only when the greater member is reached.
<syntaxhighlight lang="julia">using Primes, Printf
 
'''Functions'''
<lang Julia>
function pcontrib(p::Int64, a::Int64)
n = one(p)
Line 1,720 ⟶ 3,384:
dsum -= n
end
</lang>
<code>pcontrib</code> is a good candidate for [[Memoization]] should the performance of <code>divisorsum</code> become an issue.
 
function amicables(L = 2*10^7)
'''Main'''
acnt = 0
 
println("Amicable pairs not greater than ", L)
It is safe to exclude primes from consideration; their proper divisor sum is always 1. Also, this code uses a minor trick to ensure that none of the numbers identified are above the limit. All numbers in the range are checked for an amicable partner, but the pair is cataloged only when the greater member is reached.
for i in 2:L
<lang Julia>
!isprime(i) || continue
const L = 2*10^4
j = divisorsum(i)
acnt = 0
j < i && divisorsum(j) == i || continue
 
acnt += 1
println("Amicable pairs not greater than ", L)
println(@sprintf("%4d", acnt), " => ", j, ", ", i)
 
for i in 2:L end
!isprime(i) || continue
j = divisorsum(i)
j < i && divisorsum(j) == i || continue
acnt += 1
println(@sprintf("%4d", acnt), " => ", j, ", ", i)
end
 
</lang>
amicables()
</syntaxhighlight>
 
{{out}}
Note, the output is ''not'' ordered by the first figure, see e.g. counters 11, 15, ..., 139, 141, etc.
<pre>
Amicable pairs not greater than 2000020000000
1 => 220, 284
2 => 1184, 1210
Line 1,752 ⟶ 3,412:
7 => 12285, 14595
8 => 17296, 18416
9 => 66928, 66992
10 => 67095, 71145
11 => 63020, 76084
12 => 69615, 87633
13 => 79750, 88730
14 => 122368, 123152
15 => 100485, 124155
16 => 122265, 139815
[...]
138 => 18655744, 19154336
139 => 16871582, 19325698
140 => 17844255, 19895265
141 => 17754165, 19985355
</pre>
 
 
===Alternative===
 
Using the <code>factor()</code> function from the <code>Primes</code> package allows for a quicker calculation, especially when it comes to big numbers. Here we use a busy one-liner with an iterator. The following code prints the amicable pairs in ''ascending order'' and also prints the sum of the amicable pair and the cumulative sum of all pairs found so far; this allows to check results, when solving [https://projecteuler.net/problem=21 Project Euler problem #21].
 
<syntaxhighlight lang="julia">
using Primes
 
function amicable_numbers(max::Integer = 200_000_000)
 
function sum_proper_divisors(n::Integer)
sum(vec(map(prod, Iterators.product((p.^(0:m) for (p, m) in factor(n))...)))) - n
end
 
count = 0
cumsum = 0
 
println("count, a, b, a+b, Sum(a+b)")
 
for a in 2:max
isprime(a) && continue
b = sum_proper_divisors(a)
if a < b && sum_proper_divisors(b) == a
count += 1
sumab = a + b
cumsum += sumab
println("$count, $a, $b, $sumab, $cumsum")
end
end
end
 
amicable_numbers()
</syntaxhighlight>
 
{{out}}
<pre>
count, a, b, a+b, Sum(a+b)
1, 220, 284, 504, 504
2, 1184, 1210, 2394, 2898
3, 2620, 2924, 5544, 8442
4, 5020, 5564, 10584, 19026
5, 6232, 6368, 12600, 31626
6, 10744, 10856, 21600, 53226
7, 12285, 14595, 26880, 80106
8, 17296, 18416, 35712, 115818
9, 63020, 76084, 139104, 254922
10, 66928, 66992, 133920, 388842
11, 67095, 71145, 138240, 527082
12, 69615, 87633, 157248, 684330
13, 79750, 88730, 168480, 852810
14, 100485, 124155, 224640, 1077450
15, 122265, 139815, 262080, 1339530
16, 122368, 123152, 245520, 1585050
[...]
300, 189406984, 203592056, 392999040, 31530421032
301, 190888155, 194594085, 385482240, 31915903272
302, 195857415, 196214265, 392071680, 32307974952
303, 196421715, 224703405, 421125120, 32729100072
304, 199432948, 213484172, 412917120, 33142017192
</pre>
 
=={{header|K}}==
<syntaxhighlight lang="k">
<lang k>
propdivs:{1+&0=x!'1+!x%2}
(8,2)#v@&{(x=+/propdivs[a])&~x=a:+/propdivs[x]}' v:1+!20000
Line 1,766 ⟶ 3,500:
12285 14595
17296 18416)
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1
 
fun sumProperDivisors(n: Int): Int {
Line 1,785 ⟶ 3,519:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,802 ⟶ 3,536:
 
=={{header|Lua}}==
Avoids unnecessary divisor sum calculations.<br>
0.02 of a second in 16 lines of code.
Runs in around 0.11 seconds on TIO.RUN.
The vital trick is to just set m to the sum of n's proper divisors each time. That way you only have to test the reverse, dividing your run time by half the loop limit (ie. 10,000)!
 
<lang lua>function sumDivs (n)
<syntaxhighlight lang="lua">function sumDivs (n)
local sum = 1
for d = 2, math.sqrt(n) do
Line 1,820 ⟶ 3,555:
if sumDivs(m) == n then print(n, m) end
end
end</langsyntaxhighlight>
 
{{out}}<pre>
Line 1,832 ⟶ 3,567:
17296 18416
</pre>
 
Alternative version using a table of proper divisors, constructed without division/modulo.<br>
Runs is around 0.02 seconds on TIO.RUN.
<syntaxhighlight lang="lua">
MAX_NUMBER = 20000
sumDivs = {} -- table of proper divisors
for i = 1, MAX_NUMBER do sumDivs[ i ] = 1 end
for i = 2, MAX_NUMBER do
for j = i + i, MAX_NUMBER, i do
sumDivs[ j ] = sumDivs[ j ] + i
end
end
 
for n = 2, MAX_NUMBER do
m = sumDivs[n]
if m > n then
if sumDivs[m] == n then print(n, m) end
end
end
</syntaxhighlight>
 
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|MiniScript}}==
{{Trans|ALGOL W}}
<syntaxhighlight lang="miniscript">
// find amicable pairs p1, p2 where each is equal to the other's proper divisor sum
 
MAX_NUMBER = 20000
pdSum = [1] * ( MAX_NUMBER + 1 ) // table of proper divisors
for i in range( 2, MAX_NUMBER )
for j in range( i + i, MAX_NUMBER, i )
pdSum[ j ] += i
end for
end for
// find the amicable pairs up to 20 000
ap = []
for p1 in range( 1, MAX_NUMBER - 1 )
pdSumP1 = pdSum[ p1 ]
if pdSumP1 > p1 and pdSumP1 <= MAX_NUMBER and pdSum[ pdSumP1 ] == p1 then
print str( p1 ) + " and " + str( pdSumP1 ) + " are an amicable pair"
end if
end for
</syntaxhighlight>
{{out}}
<pre>
220 and 284 are an amicable pair
1184 and 1210 are an amicable pair
2620 and 2924 are an amicable pair
5020 and 5564 are an amicable pair
6232 and 6368 are an amicable pair
10744 and 10856 are an amicable pair
12285 and 14595 are an amicable pair
17296 and 18416 are an amicable pair
</pre>
 
=={{header|MAD}}==
 
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER
DIMENSION DIVS(20000)
PRINT COMMENT $ AMICABLE PAIRS$
R CALCULATE SUM OF DIVISORS OF N
INTERNAL FUNCTION(N)
ENTRY TO DIVSUM.
DS = 0
THROUGH SUMMAT, FOR DIVC=1, 1, DIVC.GE.N
SUMMAT WHENEVER N/DIVC*DIVC.E.N, DS = DS+DIVC
FUNCTION RETURN DS
END OF FUNCTION
R CALCULATE SUM OF DIVISORS FOR ALL NUMBERS 1..20000
THROUGH MEMO, FOR I=1, 1, I.GE.20000
MEMO DIVS(I) = DIVSUM.(I)
 
R FIND ALL MATCHING PAIRS
THROUGH CHECK, FOR I=1, 1, I.GE.20000
THROUGH CHECK, FOR J=1, 1, J.GE.I
CHECK WHENEVER DIVS(I).E.J .AND. DIVS(J).E.I,
0 PRINT FORMAT AMI,I,J
VECTOR VALUES AMI = $I6,I6*$
END OF PROGRAM</syntaxhighlight>
 
{{out}}
 
<pre>AMICABLE PAIRS
284 220
1210 1184
2924 2620
5564 5020
6368 6232
10856 10744
14595 12285
18416 17296
</pre>
 
 
=={{header|Maple}}==
 
<lang Maple>
{{output?}}
 
<syntaxhighlight lang="maple">
with(NumberTheory):
pairs:=[];
Line 1,848 ⟶ 3,693:
end do;
pairs;
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">amicableQ[n_] :=
Module[{sum = Total[Most@Divisors@n]},
sum != n && n == Total[Most@Divisors@sum]]
 
Grid@Partition[Cases[Range[4, 20000], _?(amicableQ@# &)], 2]</langsyntaxhighlight>
 
{{out}}<pre>
Line 1,867 ⟶ 3,712:
17296 18416
</pre>
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">function amicable
tic
N=2:1:20000; aN=[];
N(isprime(N))=[]; %erase prime numbers
I=1;
a=N(1); b=sum(pd(a));
while length(N)>1
if a==b %erase perfect numbers;
N(N==a)=[]; a=N(1); b=sum(pd(a));
elseif b<a %the first member of an amicable pair is abundant not defective
N(N==a)=[]; a=N(1); b=sum(pd(a));
elseif ~ismember(b,N) %the other member was previously erased
N(N==a)=[]; a=N(1); b=sum(pd(a));
else
c=sum(pd(b));
if a==c
aN(I,:)=[I a b]; I=I+1;
N(N==b)=[];
else
if ~ismember(c,N) %the other member was previously erased
N(N==b)=[];
end
end
N(N==a)=[]; a=N(1); b=sum(pd(a));
clear c
end
end
disp(array2table(aN,'Variablenames',{'N','Amicable1','Amicable2'}))
toc
end
 
function D=pd(x)
K=1:ceil(x/2);
D=K(~(rem(x, K)));
end</syntaxhighlight>
 
{{out}}
<pre>
N Amicable1 Amicable2
_ _________ _________
 
1 220 284
2 1184 1210
3 2620 2924
4 5020 5564
5 6232 6368
6 10744 10856
7 12285 14595
8 17296 18416
 
Elapsed time is 8.958720 seconds.
</pre>
 
=={{header|Nim}}==
Being a novice, I submitted my code to the Nim community for review and received much feedback and advice.
They were instrumental in fine-tuning this code for style and readability, I can't thank them enough.
<syntaxhighlight lang="nim">
<lang Nim>
from math import sqrt
 
Line 1,889 ⟶ 3,789:
if m != 0 and n == sumProperDivisors(m, false):
echo $n, " ", $m
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,909 ⟶ 3,809:
Here's a second version that uses a large amount of memory but runs in 2m32seconds.
Again, thanks to the Nim community
<syntaxhighlight lang="nim">
<lang Nim>
from math import sqrt
 
Line 1,927 ⟶ 3,827:
if n < m and n != 0 and m == x[n] + 1:
echo n, " ", m
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,946 ⟶ 3,846:
 
=={{header|Oberon-2}}==
<syntaxhighlight lang="oberon2">
<lang Oberon2>
MODULE AmicablePairs;
IMPORT
Line 1,985 ⟶ 3,885:
END
END AmicablePairs.
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,002 ⟶ 3,902:
Using properDivs implementation tasks without optimization (calculating proper divisors sum without returning a list for instance) :
 
<syntaxhighlight lang="oforth">import: mapping
<lang Oforth>Integer method: properDivs self 2 / seq filter(#[ self swap mod 0 == ]) ;
 
Integer method: properDivs -- []
#[ self swap mod 0 == ] self 2 / seq filter ;
: amicables
| i j |
ListBufferArray new
20000 loop: i [
i properDivs sum dup ->j i <= ifTrue: [if continue ]then
j properDivs sum i <> ifTrue: [if continue ]then
[ i, j ] over add
] ;</lang>
;</syntaxhighlight>
 
{{out}}
Line 2,018 ⟶ 3,922:
[[220, 284], [1184, 1210], [2620, 2924], [5020, 5564], [6232, 6368], [10744, 10856], [12285, 14595], [17296, 18416]]
</pre>
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let rec isqrt n =
if n = 1 then 1
else let _n = isqrt (n - 1) in
(_n + (n / _n)) / 2
 
let sum_divs n =
let sum = ref 1 in
for d = 2 to isqrt n do
if (n mod d) = 0 then sum := !sum + (n / d + d);
done;
!sum
let () =
for n = 2 to 20000 do
let m = sum_divs n in
if (m > n) then
if (sum_divs m) = n then Printf.printf "%d %d\n" n m;
done
</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">for(x=1,20000,my(y=sigma(x)-x); if(y>x && x == sigma(y)-y,print(x" "y)))</langsyntaxhighlight>
{{out}}
<pre>220 284
Line 2,053 ⟶ 3,987:
Amicable! 17296,18416,
 
Source file:<langsyntaxhighlight lang="pascal">
Program SumOfFactors; uses crt; {Perpetrated by R.N.McLean, December MCMXCV}
//{$DEFINE ShowOverflow}
Line 2,142 ⟶ 4,076:
end;
Close (outf);
END.</langsyntaxhighlight>
 
===More expansive.===
a "normal" Version. Nearly fast as perl using nTheory.
<langsyntaxhighlight lang="pascal">program AmicablePairs;
{$IFDEF FPC}
{$MODE DELPHI}
Line 2,175 ⟶ 4,109:
// sieve of erathosthenes without multiples of 2
type
tSieve = array[0..(65536-1) div 2] of charansichar;
var
ESieve : ^tSieve;
Line 2,377 ⟶ 4,311:
writeln('Time to find amicable pairs ',FormatDateTime('HH:NN:SS.ZZZ' ,T2-T1));
{$IFNDEF UNIX} readln;{$ENDIF}
end.</langsyntaxhighlight>
Output
<pre> 1 220 284 ratio 1.2909091
Line 2,403 ⟶ 4,337:
17296 [2^4*23*47*17296]
18416 [2^4*18416]</pre>
 
===Alternative===
about 25-times faster.
Line 2,433 ⟶ 4,368:
Using "Sieve of Erathosthenes"-style
 
<langsyntaxhighlight lang="pascal">program AmicPair;
{find amicable pairs in a limited region 2..MAX
beware that >both< numbers must be smaller than MAX
Line 2,673 ⟶ 4,608:
readln;
{$ENDIF}
end.</langsyntaxhighlight>
output
<pre>
Line 2,724 ⟶ 4,659:
Not particularly clever, but instant for this example, and does up to 20 million in 11 seconds.
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use ntheory qw/divisor_sum/;
for my $x (1..20000) {
my $y = divisor_sum($x)-$x;
say "$x $y" if $y > $x && $x == divisor_sum($y)-$y;
}</langsyntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|Perl 6}}==
{{Works with|rakudo|2015-10-31}}
<lang perl6>sub propdivsum (\x) {
my @l = x > 1, gather for 2 .. x.sqrt.floor -> \d {
my \y = x div d;
if y * d == x { take d; take y unless y == d }
}
[+] gather @l.deepmap(*.take);
}
 
for 1..20000 -> $i {
my $j = propdivsum($i);
say "$i $j" if $j > $i and $i == propdivsum($j);
}</lang>
{{out}}
<pre>220 284
Line 2,764 ⟶ 4,675:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>integer n
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for m=1 to 20000 do
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">20000</span> <span style="color: #008080;">do</span>
n = sum(factors(m,-1))
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
if m<n and m=sum(factors(n,-1)) then ?{m,n} end if
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;"><</span><span style="color: #000000;">n</span> <span style="color: #008080;">and</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,779 ⟶ 4,692:
{12285,14595}
{17296,18416}
</pre>
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">def sumDivs
var n
1 var sum n sqrt
2 swap 2 tolist
for
var d
n d mod not if
sum d + n d / + var sum
endif
endfor
sum
enddef
 
2 20000 2 tolist for
var i
i sumDivs var m
m i > if
m sumDivs i == if i print "\t" print m print nl endif
endif
endfor
 
nl msec print " s" print</syntaxhighlight>
 
=={{header|PHP}}==
 
<syntaxhighlight lang="php"><?php
 
function sumDivs ($n) {
$sum = 1;
for ($d = 2; $d <= sqrt($n); $d++) {
if ($n % $d == 0) $sum += $n / $d + $d;
}
return $sum;
}
for ($n = 2; $n < 20000; $n++) {
$m = sumDivs($n);
if ($m > $n) {
if (sumDivs($m) == $n) echo $n."&ensp;".$m."<br />";
}
}
 
?></syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|Picat}}==
Different approaches to solve this task:
 
* foreach loop (two variants)
* list comprehension
* while loop.
 
Also, the calculation of the sum of divisors is tabled (the table is cleared between each run).
<syntaxhighlight lang="picat">go =>
N = 20000,
 
println(amicable1),
time(amicable1(N)),
 
% initialize_table is needed to clear the table cache
% of sum_divisors/1 between each run.
initialize_table,
println(amicable2),
time(amicable2(N)),
 
initialize_table,
println(amicable3),
time(amicable3(N)),
 
initialize_table,
println(amicable4),
time(amicable4(N)),
nl.
 
 
% Foreach loop and a map (hash table)
amicable1(N) =>
Pairs = new_map(),
foreach(A in 1..N)
B = sum_divisors(A),
C = sum_divisors(B),
if A != B, A == C then
Pairs.put([A,B].sort(),1)
end
end,
println(Pairs.keys().sort()).
 
 
% List comprehension
amicable2(N) =>
println([[A,B].sort() : A in 1..N,
B = sum_divisors(A),
C = sum_divisors(B),
A != B, A == C].remove_dups()).
 
 
% While loop
amicable3(N) =>
A = 1,
while(A <= N)
B = sum_divisors(A),
if A < B, A == sum_divisors(B) then
print([A,B]), print(" ")
end,
A := A + 1
end,
nl.
 
% Foreach loop, everything in the condition
amicable4(N) =>
foreach(A in 1..N, B = sum_divisors(A), A < B, A == sum_divisors(B))
print([A,B]), print(" ")
end,
nl.
 
%
% Sum of divisors of N
%
table
sum_divisors(N) = Sum =>
sum_divisors(2,N,1,Sum).
 
% Base case: exceeding the limit
sum_divisors(I,N,Sum0,Sum), I > floor(sqrt(N)) =>
Sum = Sum0.
 
% I is a divisor of N
sum_divisors(I,N,Sum0,Sum), N mod I == 0 =>
Sum1 = Sum0 + I,
(I != N div I ->
Sum2 = Sum1 + N div I
;
Sum2 = Sum1
),
sum_divisors(I+1,N,Sum2,Sum).
 
% I is not a divisor of N.
sum_divisors(I,N,Sum0,Sum) =>
sum_divisors(I+1,N,Sum0,Sum).
</syntaxhighlight>
 
{{out}}
<pre>
amicable1
[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]
CPU time 0.114 seconds.
 
amicable2
[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]
CPU time 0.106 seconds.
 
amicable3
[220,284] [1184,1210] [2620,2924] [5020,5564] [6232,6368] [10744,10856] [12285,14595] [17296,18416]
CPU time 0.111 seconds.
 
amicable4
[220,284] [1184,1210] [2620,2924] [5020,5564] [6232,6368] [10744,10856] [12285,14595] [17296,18416]
CPU time 0.107 seconds.
 
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de accud (Var Key)
(if (assoc Key (val Var))
(con @ (inc (cdr @)))
(push Var (cons Key 1)) )
Key )
(de **sum (L)
(let S 1
(for I (cdr L)
(inc 'S (** (car L) I)) )
S ) )
(de factor-sum (N)
(if (=1 N)
Line 2,804 ⟶ 4,893:
(accud 'R N1)
(for I R
(onesetq S (* S (**sum I))) D)
(one M)
(for J (cdr I)
(setq M (* M (car I)))
(inc 'D M) )
(setq S (* S D)) )
(- S N) ) ) )
(bench
Line 2,817 ⟶ 4,901:
(< I X)
(= I (factor-sum X))
(println I X) ) ) ) )</langsyntaxhighlight>
{{output}}
<pre>
Line 2,828 ⟶ 4,912:
12285 14595
17296 18416
0.734101 sec
</pre>
 
=={{header|PL/I}}==
{{trans|REXX}}
<langsyntaxhighlight lang="pli">*process source xref;
ami: Proc Options(main);
p9a=time();
Line 2,892 ⟶ 4,976:
Return((p9c-p9b)/1000);
End;
End;</langsyntaxhighlight>
{{out}}
<pre> sum(pd) computed in 0.510 seconds elapsed
Line 2,904 ⟶ 4,988:
17296 18416 found after 2.240 seconds
2.250 seconds total search time</pre>
 
==={{header|PL/I-80}}===
====Computing the divisor sum on the fly====
Rather than populating an array with the sum of the proper divisors and then searching, the approach here calculates them on the fly as needed, saving memory, and avoiding a noticeable lag on program startup on the ancient systems that hosted PL/I-80.
<syntaxhighlight lang="pl/i">
amicable: procedure options (main);
 
%replace
search_limit by 20000;
 
dcl (a, b, found) fixed bin;
 
put skip list ('Searching for amicable pairs up to ');
put edit (search_limit) (f(5));
found = 0;
do a = 2 to search_limit;
b = sumf(a);
if (b > a) then
do;
if (sumf(b) = a) then
do;
found = found + 1;
put skip edit (a,b) (f(7));
end;
end;
end;
put skip list (found, ' pairs were found');
stop;
 
 
/* return sum of the proper divisors of n */
sumf:
procedure(n) returns (fixed bin);
dcl (n, sum, f1, f2) fixed bin;
 
sum = 1; /* 1 is a proper divisor of every number */
f1 = 2;
do while ((f1 * f1) < n);
if mod(n, f1) = 0 then
do;
sum = sum + f1;
f2 = n / f1;
/* don't double count identical co-factors! */
if f2 > f1 then sum = sum + f2;
end;
f1 = f1 + 1;
end;
return (sum);
end sumf;
 
end amicable;
</syntaxhighlight>
{{out}}
<pre>
Searching for amicable pairs up to 20000
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
8 pairs were found
</pre>
 
====Without using division/modulo====
 
<syntaxhighlight lang="pl/i">
amicable: procedure options (main);
 
%replace
search_limit by 20000;
 
dcl sumf( 1 : search_limit ) fixed bin;
dcl (a, b, found) fixed bin;
 
put skip list ('Searching for amicable pairs up to ');
put edit (search_limit) (f(5));
 
do a = 1 to search_limit; sumf( a ) = 1; end;
do a = 2 to search_limit;
do b = a + a to search_limit by a;
sumf( b ) = sumf( b ) + a;
end;
end;
 
found = 0;
do a = 2 to search_limit;
b = sumf(a);
if (b > a) then
do;
if (sumf(b) = a) then
do;
found = found + 1;
put skip edit (a,b) (f(7));
end;
end;
end;
put skip list (found, ' pairs were found');
stop;
 
end amicable;
</syntaxhighlight>
 
{{out}}
Same as the other PLI-80 sample.
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
/* CP/M CALLS */
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;
 
/* PRINT A NUMBER */
PRINT$NUMBER: PROCEDURE (N);
DECLARE S (6) BYTE INITIAL ('.....$');
DECLARE (N, P) ADDRESS, C BASED P BYTE;
P = .S(5);
DIGIT:
P = P - 1;
C = N MOD 10 + '0';
N = N / 10;
IF N > 0 THEN GO TO DIGIT;
CALL PRINT(P);
END PRINT$NUMBER;
 
/* CALCULATE SUMS OF PROPER DIVISORS */
DECLARE DIV$SUM (20$001) ADDRESS;
DECLARE (I, J) ADDRESS;
 
DO I=2 TO 20$000; DIV$SUM(I) = 1; END;
DO I=2 TO 10$000;
DO J = I*2 TO 20$000 BY I;
DIV$SUM(J) = DIV$SUM(J) + I;
END;
END;
 
/* TEST EACH PAIR */
DO I=2 TO 20$000;
J = DIVSUM(I);
IF J > I AND J <= 20$000 THEN DO;
IF DIV$SUM(J) = I THEN DO;
CALL PRINT$NUMBER(I);
CALL PRINT(.', $');
CALL PRINT$NUMBER(J);
CALL PRINT(.(13,10,'$'));
END;
END;
END;
 
CALL EXIT;
EOF</syntaxhighlight>
{{out}}
<pre>220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|PowerShell}}==
{{works with|PowerShell|2}}
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Get-ProperDivisorSum ( [int]$N )
{
Line 2,937 ⟶ 5,185:
 
Get-AmicablePairs 20000
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,956 ⟶ 5,204:
With some guidance from other solutions here:
 
<langsyntaxhighlight lang="prolog">divisor(N, Divisor) :-
UpperBound is round(sqrt(N)),
between(1, UpperBound, D),
Line 2,988 ⟶ 5,236:
amicable_pairs_under_20000(Pairs) :-
assoc_num_divsSum_in_range(1,20000, Assoc),
findall(P, get_amicable_pair(Assoc, P), Pairs).</langsyntaxhighlight>
 
Output:
 
<langsyntaxhighlight lang="prolog">?- amicable_pairs_under_20000(R).
R = [220-284, 1184-1210, 2620-2924, 5020-5564, 6232-6368, 10744-10856, 12285-14595, 17296-18416].</langsyntaxhighlight>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">
<lang PureBasic>
EnableExplicit
 
Line 3,031 ⟶ 5,279:
CloseConsole()
EndIf
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,049 ⟶ 5,297:
=={{header|Python}}==
Importing [[Proper_divisors#Python:_From_prime_factors|Proper divisors from prime factors]]:
<langsyntaxhighlight lang="python">from proper_divisors import proper_divs
 
def amicable(rangemax=20000):
Line 3,060 ⟶ 5,308:
for num, divsum in amicable():
print('Amicable pair: %i and %i With proper divisors:\n %r\n %r'
% (num, divsum, sorted(proper_divs(num)), sorted(proper_divs(divsum))))</langsyntaxhighlight>
 
{{out}}
Line 3,087 ⟶ 5,335:
[1, 2, 4, 8, 16, 23, 46, 47, 92, 94, 184, 188, 368, 376, 752, 1081, 2162, 4324, 8648]
[1, 2, 4, 8, 16, 1151, 2302, 4604, 9208]</pre>
 
 
Or, supplying our own '''properDivisors''' function, and defining the harvest in terms of a generic '''concatMap''':
 
<syntaxhighlight lang="python">'''Amicable pairs'''
 
from itertools import chain
from math import sqrt
 
 
# amicablePairsUpTo :: Int -> [(Int, Int)]
def amicablePairsUpTo(n):
'''List of all amicable pairs
of integers below n.
'''
sigma = compose(sum)(properDivisors)
 
def amicable(x):
y = sigma(x)
return [(x, y)] if (x < y and x == sigma(y)) else []
 
return concatMap(amicable)(
enumFromTo(1)(n)
)
 
 
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Amicable pairs of integers up to 20000'''
 
for x in amicablePairsUpTo(20000):
print(x)
 
 
# GENERIC -------------------------------------------------
 
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
 
 
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list or string over which a function f
has been mapped.
The list monad can be derived by using an (a -> [b])
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
return lambda xs: (''.join if isinstance(xs, str) else list)(
chain.from_iterable(map(f, xs))
)
 
 
# enumFromTo :: Int -> Int -> [Int]
def enumFromTo(m):
'''Enumeration of integer values [m..n]'''
def go(n):
return list(range(m, 1 + n))
return lambda n: go(n)
 
 
# properDivisors :: Int -> [Int]
def properDivisors(n):
'''Positive divisors of n, excluding n itself'''
root_ = sqrt(n)
intRoot = int(root_)
blnSqr = root_ == intRoot
lows = [x for x in range(1, 1 + intRoot) if 0 == n % x]
return lows + [
n // x for x in reversed(
lows[1:-1] if blnSqr else lows[1:]
)
]
 
 
# MAIN ---
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>(220, 284)
(1184, 1210)
(2620, 2924)
(5020, 5564)
(6232, 6368)
(10744, 10856)
(12285, 14595)
(17296, 18416)</pre>
 
=={{header|Quackery}}==
 
<code>properdivisors</code> is defined at [[Proper divisors#Quackery]].
 
<syntaxhighlight lang="quackery"> [ properdivisors
dup size 0 = iff
[ drop 0 ] done
behead swap witheach + ] is spd ( n --> n )
[ dup dup spd dup spd
rot = unrot > and ] is largeamicable ( n --> b )
[ [] swap times
[ i^ largeamicable if
[ i^ dup spd
swap join
nested join ] ] ] is amicables ( n --> [ )
20000 amicables witheach [ witheach [ echo sp ] cr ]</syntaxhighlight>
 
{{out}}
 
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
 
=={{header|R}}==
 
<syntaxhighlight lang="r">
divisors <- function (n) {
Filter( function (m) 0 == n %% m, 1:(n/2) )
}
 
table = sapply(1:19999, function (n) sum(divisors(n)) )
 
for (n in 1:19999) {
m = table[n]
if ((m > n) && (m < 20000) && (n == table[m]))
cat(n, " ", m, "\n")
}
</syntaxhighlight>
 
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|Racket}}==
With [[Proper_divisors#Racket]] in place:
<langsyntaxhighlight lang="racket">#lang racket
(require "proper-divisors.rkt")
(define SCOPE 20000)
Line 3,121 ⟶ 5,520:
EOS
n m n (proper-divisors n) m (proper-divisors m)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,156 ⟶ 5,555:
17296: divisors: (1 2 4 8 16 23 46 47 92 94 184 188 368 376 752 1081 2162 4324 8648)
 
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|Rakudo|2019.03.1}}
<syntaxhighlight lang="raku" line>sub propdivsum (\x) {
my @l = 1 if x > 1;
(2 .. x.sqrt.floor).map: -> \d {
unless x % d { @l.push: d; my \y = x div d; @l.push: y if y != d }
}
sum @l
}
 
(1..20000).race.map: -> $i {
my $j = propdivsum($i);
say "$i $j" if $j > $i and $i == propdivsum($j);
}</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|REBOL}}==
<syntaxhighlight lang="rebol">;- based on Lua code ;-)
 
sum-of-divisors: func[n /local sum][
sum: 1
; using `to-integer` for compatibility with Rebol2
for d 2 (to-integer square-root n) 1 [
if 0 = remainder n d [ sum: n / d + sum + d ]
]
sum
]
for n 2 20000 1 [
if n < m: sum-of-divisors n [
if n = sum-of-divisors m [ print [n tab m] ]
]
]</syntaxhighlight>
 
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let isqrt = (v) => {
Belt.Float.toInt(
sqrt(Belt.Int.toFloat(v)))
}
 
let sum_divs = (n) => {
let sum = ref(1)
for d in 2 to isqrt(n) {
if mod(n, d) == 0 {
sum.contents = sum.contents + (n / d + d)
}
}
sum.contents
}
 
{
for n in 2 to 20000 {
let m = sum_divs(n)
if (m > n) {
if sum_divs(m) == n {
Printf.printf("%d %d\n", n, m)
}
}
}
}
</syntaxhighlight>
{{output}}
<pre>
$ bsc ampairs.res > ampairs.bs.js
$ node ampairs.bs.js
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|REXX}}==
===version 1, with factoring===
<syntaxhighlight lang ="rexx">Call time 'R'
/*REXX*/
 
Call time 'R'
Do x=1 To 20000
pd=proper_divisors(x)
Line 3,198 ⟶ 5,696:
sum=sum+word(list,i)
End
Return sum</langsyntaxhighlight>
{{out}}
<pre>sum(pd) computed in 48.502000 seconds
Line 3,211 ⟶ 5,709:
188.836000 seconds total search time </pre>
 
===version 2, using SIGMA function===
This REXX version allows the specification of the upper limit (for the searching of amicable pairs).
 
Line 3,219 ⟶ 5,717:
Other optimizations were incorporated which took advantage of several well-known generalizations about amicable pairs.
 
The generation/summation is about fifty&nbsp; '''5,000%''' &nbsp; times faster than the 1<sup>st</sup> REXX version; &nbsp; searching is about two&nbsp; orders'''10,000%''' of&nbsp; magnitudetimes faster.
 
TimeCPU time consumption note: &nbsp; for every doubling of &nbsp; '''H''' &nbsp; (the upper limit for searches), &nbsp; the CPU time consumed triples.
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays all amicable pairs up to a given number. */
parse arg H .; if H=='' | H=="," then H= 20000 /*get optional arguments (high limit).*/
w= length(H) ; low= 220 /*W: used for columnar output alignment*/
@.=. /* [↑] LOW is lowest amicable number. */
do k=low for H-low; _= sigma(k) /*generate sigma sums for a range of #s*/
if _>=low then @.k=_ _ /*only keep the pertinent sigma sums. */
end /*k*/ /* [↑] process a range of integers. */
#=0 0 /*number of amicable pairs found so far*/
do m=low to H; n= @.m /*start the search at the lowest number*/
if m==@.n then do /*If equal, might be an amicable number*/
if m==n then iterate /*Is this a perfect number? Then skip.*/
#= # +1 1 /*bump the amicable pair counter. */
say right(m,w) ' and ' right(n,w) " are an amicable pair."
m=n n /*start M (DO index) from N. */
end
end /*m*/
say
say # ' amicable pairs found up to ' H H /*display count of the amicable pairs. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sigma: procedure; parse arg x; od= x //2 2 /*use either EVEN or ODD integers. */
s=1 1 /*set initial sigma sum to unity. ___*/
do j=2+od by 1+od while j*j<x /*divide by all integers up to the √ xX */
if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */
end /*j*/ /* [↑] % is REXX integer division. */
return s /*return the sum of the divisors. ___ */</lang>
if j*j==x then return s + j /*Was X a square? If so, add √ X */
'''output''' &nbsp; when using the default input:
return s /*return (sigma) sum of the divisors. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
220 and 284 are an amicable pair.
Line 3,259 ⟶ 5,759:
17296 and 18416 are an amicable pair.
 
8 amicable pairs found up to 20000
</pre>
 
===version 3, SIGMA with limited searches===
This REXX version is optimized to take advantage of the lowest ending-single-digit amicable number, &nbsp; and
<br>also incorporates the search of amicable numbers into the generation of the sigmas of the integers.
 
The optimization makes it about <u>another</u> &nbsp; '''30%''' &nbsp; faster when searching for amicable numbers up to one million.
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays all amicable pairs up to a given number. */
parse arg H .; if H=='' | H=="," then H=20000 /*get optional arguments (high limit).*/
w=length(H) ; low=220 /*W: used for columnar output alignment*/
x= 220 34765731 6232 87633 284 12285 10856 36939357 6368 5684679 /*S minimums. */
do i=0 for 10; $.i= word(x, i + 1); end /*i*/end /*minimum amicable #s for last dec dig.*/
#=0 /*number of amicable pairs found so far*/
@.= /* [↑] LOW is lowest amicable number. */
#= 0 /*number of amicable pairs found so far*/
do k=low for H-low /*generate sigma sums for a range of #s*/
parse var k '' -1 D /*obtain last decimal digit of K. */
if k<$.D then iterate /*if no need to compute, then skip it. */
_= sigma(k) /*generate sigma sum for the number K.*/
@.k=_ _ /*only keep the pertinent sigma sums. */
if k==@._ then do /*is it a possible amicable number ? */
if _==k then iterate /*Is it a perfect number? Then skip it*/
#= # +1 1 /*bump the amicable pair counter. */
say right(_, w) ' and ' right(k, w) " are an amicable pair."
end
end /*k*/ /* [↑] process a range of integers. */
Line 3,289 ⟶ 5,789:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sigma: procedure; parse arg x; od= x //2 2 /*use either EVEN or ODD integers. */
s=1 1 /*set initial sigma sum to unity. ___*/
do j=2+od by 1+od while j*j<x /*divide by all integers up to the √ x */
if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */
end /*j*/ /* [↑] % is REXX integer division. */
return s /*return the sum of the divisors. ___ */</lang>
if j*j==x then return s + j /*Was X a square? If so, add √ X */
'''output''' &nbsp; is the same as the 2<sup>nd</sup> REXX version.
return s /*return (sigma) sum of the divisors. */</syntaxhighlight>
{{out|output|text=&nbsp; is identical to the 2<sup>nd</sup> REXX version.}} <br><br>
 
===version 4, SIGMA using integer SQRT===
This REXX version is optimized to use the &nbsp; ''integer square root of X'' &nbsp; in the &nbsp; '''sigma''' &nbsp; function &nbsp; (instead of
<br>computing the square of &nbsp; '''J''' &nbsp; to see if that value exceeds &nbsp; '''X''').
 
The optimization makes it about <u>another</u> &nbsp; '''20%''' &nbsp; faster when searching for amicable numbers up to one million.
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays all amicable pairs up to a given number. */
parse arg H .; if H=='' | H=="," then H=20000 /*get optional arguments (high limit).*/
w= length(H) ; low=220 220 /*W: used for columnar output alignment*/
x= 220 34765731 6232 87633 284 12285 10856 36939357 6368 5684679 /*S minimums. */
do i=0 for 10; $.i= word(x, i + 1); end /*i*/end /*minimum amicable #s for last dec dig.*/
#=0 /*number of amicable pairs found so far*/
@.= /* [↑] LOW is lowest amicable number. */
#= 0 /*number of amicable pairs found so far*/
do k=low for H-low /*generate sigma sums for a range of #s*/
parse var k '' -1 D /*obtain last decimal digit of K. */
if k<$.D then iterate /*if no need to compute, then skip it. */
_= sigma(k) /*generate sigma sum for the number K.*/
@.k=_ _ /*only keep the pertinent sigma sums. */
if k==@._ then do /*is it a possible amicable number ? */
if _==k then iterate /*Is it a perfect number? Then skip it*/
#= # +1 1 /*bump the amicable pair counter. */
say right(_, w) ' and ' right(k, w) " are an amicable pair."
end
end /*k*/ /* [↑] process a range of integers. */
Line 3,324 ⟶ 5,826:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
iSqrt: procedure; parse arg x; r= 0; q= 1; do while q<=x; q= q * 4; end
do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end
return r
/*──────────────────────────────────────────────────────────────────────────────────────*/
sigma: procedure; parse arg x; od= x //2 2 /*use either EVEN or ODD integers. */
s=1 1 /*set initial sigma sum to unity. ___*/
do j=2+od by 1+od to iSqrt(x) /*divide by all integers up to the √ x */
if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */
end /*j*/ /* [↑] % is the REXX integer division.*/
return s /*return the sum of the divisors. ___ */</lang>
if j*j==x then return s + j /*Was X a square? If so, add √ X */
'''output''' &nbsp; is the same as the 2<sup>nd</sup> REXX version.
return s /*return (sigma) sum of the divisors. */</syntaxhighlight>
{{out|output|text=&nbsp; is identical to the 2<sup>nd</sup> REXX version.}} <br><br>
 
===version 5, SIGMA (in-line code)===
This REXX version is optimized by bringing the functions in-line &nbsp; (which minimizes the overhead of invoking two
<br>internal functions), &nbsp; and it also pre-computes the powers of four &nbsp; (for the integer square root code).
Line 3,342 ⟶ 5,846:
This method of coding has the disadvantage in that the code (logic) is less idiomatic and therefore less readable.
 
The optimization makes it about <u>another</u> &nbsp; '''15%''' &nbsp; faster when searching for amicable numbers up to one million.
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays all amicable pairs up to a given number. */
parse arg H .; if H=='' | H=="," then H=20000 /*get optional arguments (high limit).*/
w= length(H) ; low=220 220 /*W: used for columnar output alignment*/
x= 220 34765731 6232 87633 284 12285 10856 36939357 6368 5684679 /*S minimums.*/
do i=0 for 10; $.i= word(x, i + 1); end /*i*/end /*minimum amicable #s for last dec dig.*/
f.=0; do p=0 until f.p>10**digits(); f.p=4**p; end /*p*/ /*calc. pows of 4*/
#=0 /*number of amicable pairs found so far*/
@.= /* [↑] LOW is lowest amicable number. */
#= 0 do k=low for H-low+1 /*generate sigma sums for a range /*number of #samicable pairs found so far*/
do k=low for H-low /*generate sigma sums for a range of #s*/
parse var k '' -1 D /*obtain last decimal digit of K. */
if k<$.D then iterate /*if no need to compute, then skip it. */
od=k//2 _= sigma(k) /*OD:generate sigma sum setfor to unity ifthe number K is odd.*/
@.k= _ /*only keep the pertinent sigma sums. */
z=k; q=1; do p=0 while f.p<=z; q=f.p; end /*R will end up being the iSqrt of Z.*/
if k==@._ then do /*is it a possible amicable number ? */
r=0; do while q>1; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end; end
s=1 if _==k then iterate /*setIs initialit sigmaa sumperfect tonumber? unity. Then skip ___it*/
do j #=2+od # by+ 1+od to r /*dividebump bythe allamicable integerspair counter. up to the K */
if k//j==0 then s=s+ j + k%j say right(_, w) /*add' theand two' divisors to the sum.right(k, w) */" are an amicable pair."
end /*j*/ /* [↑] % is REXX integer division. */
@.k=s /*only keep the pertinent sigma sums. */
if k==@.s then do /*is it a possible amicable number ? */
if s==k then iterate /*Is it a perfect number? Then skip it*/
#=#+1 /*bump the amicable pair counter. */
say right(s,w) ' and ' right(k,w) " are an amicable pair."
end
end /*k*/ /* [↑] process a range of integers. */
say
say /*stick a fork in it, we're all done. */
say # 'amicable pairs found up to' H /*display the count of amicable pairs. */</lang>
exit /*stick a fork in it, we're all done. */
'''output''' &nbsp; is the same as the 2<sup>nd</sup> REXX version. <br><br>
/*──────────────────────────────────────────────────────────────────────────────────────*/
iSqrt: procedure; parse arg x; r= 0; q= 1; do while q<=x; q= q * 4; end
do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end
return r
/*──────────────────────────────────────────────────────────────────────────────────────*/
sigma: procedure; parse arg x; od= x // 2 /*use either EVEN or ODD integers. */
s= 1 /*set initial sigma sum to unity. ___*/
do j=2+od by 1+od to iSqrt(x) /*divide by all integers up to the √ x */
if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */
end /*j*/ /* [↑] % is the REXX integer division.*/
/* ___ */
if j*j==x then return s + j /*Was X a square? If so, add √ X */
return s /*return (sigma) sum of the divisors. */</syntaxhighlight>
{{out|output|text=&nbsp; is identical to the 2<sup>nd</sup> REXX version.}} <br><br>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
size = 18500
for n = 1 to size
Line 3,390 ⟶ 5,901:
next
return sum
</syntaxhighlight>
</lang>
 
=={{header|RPL}}==
{{works with|HP|49}}
≪ {}
2 ROT '''FOR''' j
'''IF''' DUP j POS NOT '''THEN''' <span style="color:grey">@ avoiding duplicates</span>
j DIVIS ∑LIST j - DUP
'''IF''' DUP 1 ≠ OVER j ≠ AND '''THEN'''
'''IF''' DUP DIVIS ∑LIST SWAP - j == '''THEN'''
+ j +
'''ELSE''' DROP '''END'''
'''ELSE''' DROP2 '''END'''
'''END'''
'''NEXT'''
{}
1 3 PICK SIZE '''FOR''' j <span style="color:grey">@ formatting the list for output</span>
OVER j DUP 1 + SUB REVLIST 1 →LIST +
2 '''STEP''' NIP
≫ '<span style="color:blue">TASK</span>' STO
 
200000 <span style="color:blue">TASK</span>
{{out}}
<pre>
1: {{220 284} {1184 1210} {2620 2924} {5020 5564} {6232 6368} {10744 10856} {12285 14595} {17296 18416}}
</pre>
 
=={{header|Ruby}}==
With [[proper_divisors#Ruby]] in place:
<langsyntaxhighlight lang="ruby">h = {}
(1..20_000).each{|n| h[n] = n.proper_divisors.inject(:+)sum }
h.select{|k,v| h[v] == k && k < v}.each do |key,val| # k<v filters out doubles and perfects
puts "#{key} and #{val}"
end
</syntaxhighlight>
</lang>
{{out}}<pre>
220 and 284
Line 3,412 ⟶ 5,948:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight Runbasiclang="runbasic">size = 18500
for n = 1 to size
m = amicable(n)
Line 3,423 ⟶ 5,959:
if nr mod d = 0 then amicable = amicable + d + nr / d
next
end function</langsyntaxhighlight>
<pre>
220 and 284
Line 3,437 ⟶ 5,973:
=={{header|Rust}}==
 
<syntaxhighlight lang="rust">
<lang rust>fn sum_of_divisors(val: u32) -> u32 {
fn sum_of_divisors(val: u32) -> u32 {
(1..val/2+1).filter(|n| val % n == 0)
.fold(0, |sum, n| sum + n)
Line 3,451 ⟶ 5,988:
}
}
}</langsyntaxhighlight>
 
{{out}}
<pre>
Line 3,462 ⟶ 6,000:
14595 12285
18416 17296
</pre>
 
{{trans|Python}}
 
<syntaxhighlight lang="rust">
fn main() {
const RANGE_MAX: u32 = 20_000;
let proper_divs = |n: u32| -> Vec<u32> {
(1..=(n + 1) / 2).filter(|&x| n % x == 0).collect()
};
let n2d: Vec<u32> = (1..=RANGE_MAX).map(|n| proper_divs(n).iter().sum()).collect();
for (n, &div_sum) in n2d.iter().enumerate() {
let n = n as u32 + 1;
if n < div_sum && div_sum <= RANGE_MAX && n2d[div_sum as usize - 1] == n {
println!("Amicable pair: {} and {} with proper divisors:", n, div_sum);
println!(" {:?}", proper_divs(n));
println!(" {:?}", proper_divs(div_sum));
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
Amicable pair: 220 and 284 with proper divisors:
[1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110]
[1, 2, 4, 71, 142]
Amicable pair: 1184 and 1210 with proper divisors:
[1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592]
[1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605]
Amicable pair: 2620 and 2924 with proper divisors:
[1, 2, 4, 5, 10, 20, 131, 262, 524, 655, 1310]
[1, 2, 4, 17, 34, 43, 68, 86, 172, 731, 1462]
Amicable pair: 5020 and 5564 with proper divisors:
[1, 2, 4, 5, 10, 20, 251, 502, 1004, 1255, 2510]
[1, 2, 4, 13, 26, 52, 107, 214, 428, 1391, 2782]
Amicable pair: 6232 and 6368 with proper divisors:
[1, 2, 4, 8, 19, 38, 41, 76, 82, 152, 164, 328, 779, 1558, 3116]
[1, 2, 4, 8, 16, 32, 199, 398, 796, 1592, 3184]
Amicable pair: 10744 and 10856 with proper divisors:
[1, 2, 4, 8, 17, 34, 68, 79, 136, 158, 316, 632, 1343, 2686, 5372]
[1, 2, 4, 8, 23, 46, 59, 92, 118, 184, 236, 472, 1357, 2714, 5428]
Amicable pair: 12285 and 14595 with proper divisors:
[1, 3, 5, 7, 9, 13, 15, 21, 27, 35, 39, 45, 63, 65, 91, 105, 117, 135, 189, 195, 273, 315, 351, 455, 585, 819, 945, 1365, 1755, 2457, 4095]
[1, 3, 5, 7, 15, 21, 35, 105, 139, 417, 695, 973, 2085, 2919, 4865]
Amicable pair: 17296 and 18416 with proper divisors:
[1, 2, 4, 8, 16, 23, 46, 47, 92, 94, 184, 188, 368, 376, 752, 1081, 2162, 4324, 8648]
[1, 2, 4, 8, 16, 1151, 2302, 4604, 9208]
</pre>
 
=={{header|Sage}}==
<syntaxhighlight lang="Sage">
# Define the sum of proper divisors function
def sum_of_proper_divisors(n):
return sum(divisors(n)) - n
 
# Iterate over the desired range
for x in range(1, 20001):
y = sum_of_proper_divisors(x)
if y > x:
if x == sum_of_proper_divisors(y):
print(f"{x} {y}")
</syntaxhighlight>
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|S-BASIC}}==
<syntaxhighlight lang = "BASIC">
$lines
 
$constant search_limit = 20000
 
var a, b, count = integer
dim integer sumf(search_limit)
 
print "Searching up to"; search_limit; " for amicable pairs:"
 
rem - set up the table of proper divisor sums
 
for a = 1 to search_limit
sumf(a) = 1
next a
 
for a = 2 to search_limit
b = a + a
while (b > 0) and (b <= search_limit) do
begin
sumf(b) = sumf(b) + a
b = b + a
end
next a
 
rem - search for pairs using the table
 
count = 0
for a = 2 to search_limit
b = sumf(a)
if (b > a) and (b < search_limit) then
if a = sumf(b) then
begin
print using "##### #####"; a; b
count = count + 1
end
next a
print count; " pairs were found"
 
end
</syntaxhighlight>
{{out}}
<pre>
Searching up to 20000 for amicable pairs:
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
8 pairs were found
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">def properDivisors(n: Int) = (1 to n/2).filter(i => n % i == 0)
val divisorsSum = (1 to 20000).map(i => i -> properDivisors(i).sum).toMap
val result = divisorsSum.filter(v => v._1 < v._2 && divisorsSum.get(v._2) == Some(v._1))
 
println( result mkString ", " )</langsyntaxhighlight>
{{out}}
<pre>5020 -> 5564, 220 -> 284, 6232 -> 6368, 17296 -> 18416, 2620 -> 2924, 10744 -> 10856, 12285 -> 14595, 1184 -> 1210</pre>
Line 3,475 ⟶ 6,146:
=={{header|Scheme}}==
 
<langsyntaxhighlight lang="scheme">
(import (scheme base)
(scheme inexact)
Line 3,525 ⟶ 6,196:
(loop-j (+ 1 j))))
(loop-i (+ 1 i))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,538 ⟶ 6,209:
Amicable pair: 17296 18416
</pre>
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program amicable_pairs;
p := propDivSums(20000);
 
loop for [n,m] in p | n = p(p(n)) and n<m do
print([n,m]);
end loop;
 
proc propDivSums(n);
divs := {};
loop for i in [1..n] do
loop for j in [i*2, i*3..n] do
divs(j) +:= i;
end loop;
end loop;
return divs;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>[220 284]
[1184 1210]
[2620 2924]
[5020 5564]
[6232 6368]
[10744 10856]
[12285 14595]
[17296 18416]</pre>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func propdivsum(n) {
{{trans|Perl 6}}
n.sigma - n
<lang ruby>func propdivsum(x) {
gather {
for d in (2 .. x.isqrt) {
if (d.divides(x)) {
take(d, x/d)
}
}
}.uniq.sum(x > 0 ? 1 : 0)
}
 
for i in (1..20000) {
var j = propdivsum(i)
say "#{i} #{j}" if (j>i && i==propdivsum(j))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,568 ⟶ 6,260:
 
=={{header|Swift}}==
<langsyntaxhighlight Swiftlang="swift">import func Darwin.sqrt
 
func sqrt(x:Int) -> Int { return Int(sqrt(Double(x))) }
Line 3,621 ⟶ 6,313:
}
}
}</langsyntaxhighlight>
===Alternative===
about 800 times faster.<langsyntaxhighlight Swiftlang="swift">import func Darwin.sqrt
 
func sqrt(x:Int) -> Int { return Int(sqrt(Double(x))) }
Line 3,666 ⟶ 6,358:
}
 
amicables(20_000)</langsyntaxhighlight>
{{out}}
<pre>(220, 284)
Line 3,676 ⟶ 6,368:
(12285, 14595)
(17296, 18416)
</pre>
 
=={{header|tbas}}==
<syntaxhighlight lang="vb">
dim sums(20000)
 
sub sum_proper_divisors(n)
dim sum = 0
dim i
if n > 1 then
for i = 1 to (n \ 2)
if n %% i = 0 then
sum = sum + i
end if
next
end if
return sum
end sub
 
dim i, j
for i = 1 to 20000
sums(i) = sum_proper_divisors(i)
for j = i-1 to 2 by -1
if sums(i) = j and sums(j) = i then
print "Amicable pair:";sums(i);"-";sums(j)
exit for
end if
next
next
</syntaxhighlight>
<pre>
>tbas amicable_pairs.bas
Amicable pair: 220 - 284
Amicable pair: 1184 - 1210
Amicable pair: 2620 - 2924
Amicable pair: 5020 - 5564
Amicable pair: 6232 - 6368
Amicable pair: 10744 - 10856
Amicable pair: 12285 - 14595
Amicable pair: 17296 - 18416
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc properDivisors {n} {
if {$n == 1} return
set divs 1
Line 3,719 ⟶ 6,451:
puts "\t$m : $md"
puts "\t$n : $nd"
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,746 ⟶ 6,478:
17296 : 1 2 4 8 16 23 46 47 92 94 184 188 368 376 752 1081 2162 4324 8648
18416 : 1 2 4 8 16 1151 2302 4604 9208
</pre>
 
=={{header|Transd}}==
<syntaxhighlight lang="scheme">
#lang transd
 
MainModule : {
_start: (lambda
(with sum 0 d 0 f Filter( from: 1 to: 20000 apply: (lambda
(= sum 1)
(for i in Range(2 (to-Int (sqrt @it))) do
(if (not (mod @it i))
(= d (/ @it i)) (+= sum i)
(if (neq d i) (+= sum d))))
(ret sum)))
(with v (to-vector f)
(for i in v do
(if (and (< i (size v))
(eq (+ @idx 1) (get v (- i 1)))
(< i (get v (- i 1))))
(textout (+ @idx 1) ", " i "\n")
)))))
}</syntaxhighlight>{{out}}
<pre>
284, 220
1210, 1184
2924, 2620
5564, 5020
6368, 6232
10856, 10744
14595, 12285
18416, 17296
</pre>
 
=={{header|uBasic/4tH}}==
<syntaxhighlight lang="text">Input "Limit: ";l
Print "Amicable pairs < ";l
 
Line 3,797 ⟶ 6,561:
 
If (b@ > 1) c@ = c@ * (b@+1)
Return (c@)</langsyntaxhighlight>
{{Out}}
<pre>Limit: 20000
Line 3,811 ⟶ 6,575:
 
0 OK, 0:238</pre>
 
=={{header|UTFool}}==
<syntaxhighlight lang="utfool">
···
http://rosettacode.org/wiki/Amicable_pairs
···
■ AmicablePairs
§ static
▶ main
• args⦂ String[]
∀ n ∈ 1…20000
m⦂ int: sumPropDivs n
if m < n = sumPropDivs m
System.out.println "⸨m⸩ ; ⸨n⸩"
 
▶ sumPropDivs⦂ int
• n⦂ int
m⦂ int: 1
∀ i ∈ √n ⋯> 1
m +: n \ i = 0 ? i + (i = n / i ? 0 ! n / i) ! 0
⏎ m
</syntaxhighlight>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Option Explicit
Public Sub AmicablePairs()
Dim a(2 To 20000) As Long, c As New Collection, i As Long, j As Long, t#
t = Timer
For i = LBound(a) To UBound(a)
'collect the sum of the proper divisors
'of each numbers between 2 and 20000
a(i) = S(i)
Next
'Double Loops to test the amicable
For i = LBound(a) To UBound(a)
For j = i + 1 To UBound(a)
If i = a(j) Then
If a(i) = j Then
On Error Resume Next
c.Add i & " : " & j, CStr(i * j)
On Error GoTo 0
Exit For
End If
End If
Next
Next
'End. Return :
Debug.Print "Execution Time : " & Timer - t & " seconds."
Debug.Print "Amicable pairs below 20 000 are : "
For i = 1 To c.Count
Debug.Print c.Item(i)
Next i
End Sub
Private Function S(n As Long) As Long
'returns the sum of the proper divisors of n
Dim j As Long
For j = 1 To n \ 2
If n Mod j = 0 Then S = j + S
Next
End Function</syntaxhighlight>
{{out}}
<pre>Execution Time : 7,95703125 seconds.
Amicable pairs below 20 000 are :
220 : 284
1184 : 1210
2620 : 2924
5020 : 5564
6232 : 6368
10744 : 10856
12285 : 14595
17296 : 18416</pre>
 
=={{header|VBScript}}==
Not at all optimal. :-(
<langsyntaxhighlight VBScriptlang="vbscript">start = Now
Set nlookup = CreateObject("Scripting.Dictionary")
Set uniquepair = CreateObject("Scripting.Dictionary")
Line 3,848 ⟶ 6,686:
Next
 
WScript.Echo "Execution Time: " & DateDiff("s",Start,Now) & " seconds"</langsyntaxhighlight>
{{out}}
<pre>220:284
Line 3,859 ⟶ 6,697:
17296:18416
Execution Time: 162 seconds</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="Go">
fn pfac_sum(i int) int {
mut sum := 0
for p := 1; p <= i / 2; p++{
if i % p == 0 {
sum += p
}
}
return sum
}
 
fn main(){
a := []int{len: 20000, init:pfac_sum(it)}
println('The amicable pairs below 20,000 are:')
for n in 2 .. a.len {
m := a[n]
if m > n && m < 20000 && n == a[m] {
println('${n:5} and ${m:5}')
}
}
}
</syntaxhighlight>
 
{{output}}
<pre>
The amicable pairs below 20,000 are:
220 and 284
1184 and 1210
2620 and 2924
5020 and 5564
6232 and 6368
10744 and 10856
12285 and 14595
17296 and 18416
</pre>
 
=={{header|VTL-2}}==
<syntaxhighlight lang="vtl2">10 M=20000
20 I=1
30 :I)=1
40 I=I+1
50 #=M>I*30
60 I=2
70 J=I+I
80 :J)=:J)+I
90 J=J+I
100 #=M>J*80
110 I=I+1
120 #=(M/2)>I*70
130 I=1
140 J=:I)
150 #=(I<J)*I=:J)*190
160 I=I+1
170 #=M>I*140
180 #=999
190 ?=I
200 $=9
210 ?=J
220 ?=""
230 #=!</syntaxhighlight>
{{out}}
<pre>220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-math}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./math" for Int, Nums
 
var a = List.filled(20000, 0)
for (i in 1...20000) a[i] = Nums.sum(Int.properDivisors(i))
System.print("The amicable pairs below 20,000 are:")
for (n in 2...19999) {
var m = a[n]
if (m > n && m < 20000 && n == a[m]) {
Fmt.print(" $5d and $5d", n, m)
}
}</syntaxhighlight>
 
{{out}}
<pre>
The amicable pairs below 20,000 are:
220 and 284
1184 and 1210
2620 and 2924
5020 and 5564
6232 and 6368
10744 and 10856
12285 and 14595
17296 and 18416
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">func SumDiv(Num); \Return sum of proper divisors of Num
int Num, Div, Sum, Quot;
[Div:= 2;
Sum:= 0;
loop [Quot:= Num/Div;
if Div > Quot then quit;
if rem(0) = 0 then
[Sum:= Sum + Div;
if Div # Quot then Sum:= Sum + Quot;
];
Div:= Div+1;
];
return Sum+1;
];
 
def Limit = 20000;
int Tbl(Limit), N, M;
[for N:= 0 to Limit-1 do
Tbl(N):= SumDiv(N);
for N:= 1 to Limit-1 do
[M:= Tbl(N);
if M<Limit & N=Tbl(M) & M>N then
[IntOut(0, N); ChOut(0, 9\tab\);
IntOut(0, M); CrLf(0);
];
];
]</syntaxhighlight>
 
{{out}}
<pre>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
</pre>
 
=={{header|Yabasic}}==
{{trans|Lua}}
<syntaxhighlight lang="yabasic">sub sumDivs(n)
local sum, d
sum = 1
for d = 2 to sqrt(n)
if not mod(n, d) then
sum = sum + d
sum = sum + n / d
end if
next
return sum
end sub
 
for n = 2 to 20000
m = sumDivs(n)
if m > n then
if sumDivs(m) = n print n, "\t", m
end if
next
 
print : print peek("millisrunning"), " ms"</syntaxhighlight>
 
=={{header|Zig}}==
<syntaxhighlight lang="zig">const MAXIMUM: u32 = 20_000;
 
// Fill up a given array with arr[n] = sum(propDivs(n))
pub fn calcPropDivs(divs: []u32) void {
for (divs) |*d| d.* = 1;
var i: u32 = 2;
while (i <= divs.len/2) : (i += 1) {
var j = i * 2;
while (j < divs.len) : (j += i)
divs[j] += i;
}
}
 
// Are (A, B) an amicable pair?
pub fn amicable(divs: []const u32, a: u32, b: u32) bool {
return divs[a] == b and a == divs[b];
}
 
pub fn main() !void {
const stdout = @import("std").io.getStdOut().writer();
 
var divs: [MAXIMUM + 1]u32 = undefined;
calcPropDivs(divs[0..]);
var a: u32 = 1;
while (a < divs.len) : (a += 1) {
var b = a+1;
while (b < divs.len) : (b += 1) {
if (amicable(divs[0..], a, b))
try stdout.print("{d}, {d}\n", .{a, b});
}
}
}</syntaxhighlight>
{{out}}
<pre>220, 284
1184, 1210
2620, 2924
5020, 5564
6232, 6368
10744, 10856
12285, 14595
17296, 18416</pre>
 
=={{header|zkl}}==
Slooooow
<langsyntaxhighlight lang="zkl">fcn properDivs(n){ [1.. (n + 1)/2 + 1].filter('wrap(x){ n%x==0 and n!=x }) }
const N=20000;
sums:=[1..N].pump(T(-1),fcn(n){ properDivs(n).sum(0) });
[0..].zip(sums).filter('wrap([(n,s)]){ (n<s<=N) and sums[s]==n }).println();</langsyntaxhighlight>
{{out}}
<pre>
Line 3,873 ⟶ 6,922:
=={{header|ZX Spectrum Basic}}==
{{trans|AWK}}
<langsyntaxhighlight lang="zxbasic">10 LET limit=20000
20 PRINT "Amicable pairs < ";limit
30 FOR n=1 TO limit
Line 3,891 ⟶ 6,940:
1070 IF num/root=INT (num/root) THEN LET sum=sum+root
1080 LET num=sum
1090 RETURN</langsyntaxhighlight>
{{out}}
<pre>Amicable pairs < 20000
2,114

edits