use warnings; use strict; my $max = int($ARGV[0]) or die "Usage: $0 \n"; my @divisors; my %amicable; for my $n (1 .. $max) { # 1 is always a divider of any integer push @{$divisors[$n]}, 1; # find the rest of the dividers for (2 .. $max) { push @{$divisors[$n]}, $_ unless ($n % $_); } # check to see if this is a perfect number my $total = unpack "%123d*" , pack( "d*", @{$divisors[$n]}); print "$n is a perfect number\n" if (2*$n == $total); # check to see if this is an amicable pair with an earlier number $amicable{$n} = $total-$n; if ( exists($amicable{$total-$n}) && ($amicable{$total-$n} == $n) && ($n != $total-$n) ) { print "$n and " . ($total-$n) . " are an amicable pair\n"; } }