program Amicable; { Problem statement: Two numbers are said to be 'amicable' if they are different and the sum of the divisors of each number (including 1 but excluding the number itself) equals the other number. For example: 2620 is divisible by 1, 2, 4, 5, 10, 20, 131, 262, 524, 655 and 1310; these add up to 2924. 2924 is divisible by 1, 2, 4, 17, 34, 43, 68, 86, 172, 731 and 1462; these add up to 2620. Therefore 2620 and 2924 are amicable. Write a program which inputs two numbers (which will be less than 10,000) and then prints "Amicable" if they are amicable, or "Not amicable" otherwise. Your program should then terminate. Sample run: First number: 2620 Second number: 2924 Amicable } { See copyright notice at the end of this file. } { For Delphi or Turbo Pascal for Windows, include this line } { uses WinCrt; } { otherwise comment it out. } procedure Usage; begin WriteLn('AMICABLE - finds amicable and perfect numbers.'); WriteLn('Copyright (C) 1997 The British Informatics Olympiad'); WriteLn(''); WriteLn('Usage:'); WriteLn(' AMICABLE HELP shows this text'); WriteLn(''); WriteLn(' AMICABLE enters interactive mode'); WriteLn(''); WriteLn(' AMICABLE MIN displays first pair of amicable numbers.'); WriteLn(''); WriteLn(' AMICABLE LIST lists amicable pairs up to 30000'); WriteLn(''); WriteLn(' AMICABLE n tests if n is perfect or amicable'); WriteLn(''); end; function Likes(n: Word): Word; { returns the sum of the divisors of n } var i, x: Word; begin x := 0; for i := 1 to (n - 1) do if (n mod i) = 0 then Inc(x, i); Likes := x; end; procedure Min; var i, j: Word; begin i := 2; while i < 30000 do begin j := Likes(i); if (Likes(j) = i) and (j <> i) then begin WriteLn('The first pair of amicable numbers is ', i:1, ' and ', j:1); i := 30000; end; Inc(i); end; end; procedure List; var i, j: Word; begin WriteLn('Amicable numbers up to 30000:'); for i := 2 to 30000 do begin j := Likes(i); if (Likes(j) = i) and (j > i) then WriteLn(i:6, j:6); end; end; procedure Test(n: Word); begin if Likes(n) = n then WriteLn(n:1, ' is Perfect') else if Likes(Likes(n)) = n then WriteLn(n:1, ' is amicable with ', Likes(n):1) else WriteLn(n:1, ' is neither Perfect nor Amicable.'); end; var c: String; n: Word; e: Integer; procedure Interact; var a, b:Word; begin WriteLn('AMICABLE Tests for amicable numbers'); WriteLn(' type AMICABLE HELP for a list of command-line options'); WriteLn; Write('Enter first number to test:'); ReadLn(a); Write('Enter second number to test:'); ReadLn(b); WriteLn; Test(a); Test(b); WriteLn; if (Likes(a) = b) and (Likes(b) = a) and (a <> b) then WriteLn(a:1, ' and ', b:1,' are amicable.') else WriteLn(a:1, ' and ', b:1,' are not amicable.'); WriteLn; end; begin if ParamCount <> 1 then begin Interact; end else begin c := ParamStr(1); for n := 1 to Length(c) do c[n] := UpCase(c[n]); if c = 'MIN' then Min else if c = 'LIST' then List else begin Val(c, n, e); if e <> 0 then Usage else Test(n); end end; end. { Program copyright (c) 1997 The British Informatics Olympiad (BIO). This program may be freely copied by persons or organisations involved in the British Informatics Olympiad or the International Olympiad in Informatics, on condition that no changes are made and this notice is not altered. Distribution for profit is forbidden unless permission is first obtained in writing from the BIO. This program is for educational purposes only and comes with no warranty, implied or otherwise, as to its fitness for any purpose. Author: Antony Rix Internet: http://www.christs.cam.ac.uk/bio/ E-mail: a.rix@lineone.net S-mail: The British Informatics Olympiad Christ's College Cambridge CB2 3BU United Kingdom }