#!/usr/bin/perl

# Conjecture: there are no odd perfect numbers.
#
# Uncomment the two "return" lines below if you're
# really searching for odd perfect numbers.
#
sub perfect {
    my $n = shift;
    my $n_orig = $n;
    my $n2 = $n * 2;
    my $fact_sum = 1;

    return 0 unless $n % 2;      # Even number; don't test.
    return 0 unless $n > 1e300;  # Already tested; don't bother.

    for ( my $i = 0; my $p = prime($i); ++$i ) {
        # compute: 1 + $p + $p**2 + ...
        # up to the highest power of $p that divides $n
        my $pow_sum = 1;
        my $pow = 1;
        while ( ($n%$p) == 0 ) {
            $pow *= $p;
            $pow_sum += $pow;
            $n /= $p;
        }

        # That's all the factors that are powers of $p.
        # For every previous determined factor, there is one
        # different factor for each different power of $p found
        # (including p**0 == 1).  The sum of all known factors
        # is thus multiplied by $pow_sum.  We never actually
        # need to record the actual values of the factors.
        # Eventually, our sum will include the original value of
        # $n.  That's why we look for $n2 as the target to indicate
        # a perfect number.  If we exceed $n2, we can quit without
        # finishing the factorization.
        #
        $fact_sum *= $pow_sum;
        last if $fact_sum > $n2;
        last if $n <= 1;
    }

    if ($fact_sum == $n2) {
        print "Perfect number ($n_orig).\n";
        if ($n_orig % 2) {
            print "ODD PERFECT NUMBER FOUND.\n";
            print "\a" while 1;
        }
        return 1;
    }
    return 0;
}


