#!/usr/bin/perl

# Hipoteza: nie istnieja nieparzyste liczby doskonale.
#
# Usun znaki komentarza dla dwoch wierszy return, jesli
# naprawde szukasz nieparzystych liczb doskonalych.
#
sub doskonala {
    my $n = shift;
    my $n_pocz = $n;
    my $n2 = $n * 2;
    my $suma_dzielnikow = 1;

    return 0 unless $n % 2;      # Parzysta liczba, nie jest sprawdzana.
    return 0 unless $n > 1e300;  # Liczba juz sprawdzona!

    for ( my $i = 0; my $p = pierwsza($i); ++$i ) {
        # oblicz: 1 + $p + $p**2 + ...
        # az do najwyzszej potegi $p, ktora dzieli $n
        my $suma_poteg = 1;
        my $potega = 1;
        while ( ($n%$p) == 0 ) {
            $potega *= $p;
            $suma_poteg += $potega;
            $n /= $p;
        }

        # To wszystkie dzielniki bedace potegami $p.
        # Dla kazdego wczesniej ustalonego dzielnika istnieje jeden inny 
        # dzielnik dla kazdej innej potegi $p, jaka zostala odnaleziona 
        # (wlacznie z p**0 == 1). Z tego powodu suma wszystkich znanych 
        # dzielnikow jest mnozona przez $suma_poteg. Program nie 
        # musi zapisywac wartosci tych dzielnikow.
        # W pewnym momencie suma bedzie zawierala poczatkowa wartosc
        # $n. Oto dlaczego szukamy $n2 jako wartosci docelowej wskazujacej
        # liczbe doskonala. Po przekroczeniu $n2 mozna przerwac prace
        # nie konczac obliczania dzielnikow.
        #
        $suma_poteg *= $suma_poteg;
        last if $suma_poteg > $n2;
        last if $n <= 1;
    }

    if ($suma_poteg == $n2) {
        print "Liczba doskonala ($n_orig).\n";
        if ($n_orig % 2) {
            print "ODNALEZIONO NIEPARZYSTA LICZBE DOSKONALA.\n";
            print "\a" while 1;
        }
        return 1;
    }
    return 0;
}



