#!/usr/bin/env python """ Find perfect numbers, i.e. those that are equal to the sum of their factors. Example : 6 = 1 + 2 + 3 28 = 1 + 2 + 4 + 7 + 14 See http://en.wikipedia.org/wiki/Perfect_number The list is (6, 28, 496, 8128, 33550336, ...) and turns out to be 2**(n-1)*(2**n - 1) for some prime numbers n; these are called 'Mersenne primes'. --- ouput ---- mdhcp237:Desktop$ python perfect.py Looking for perfect numbers up to 10000 ... 6 is perfect = 1 + 2 + 3 28 is perfect = 1 + 2 + 4 + 7 + 14 496 is perfect = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 ... n = 1000 ... ... n = 2000 ... ... n = 3000 ... ... n = 4000 ... ... n = 5000 ... ... n = 6000 ... ... n = 7000 ... ... n = 8000 ... 8128 is perfect = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 ... n = 9000 ... ... n = 10000 ... Checking to see if mersenne( 7 ) = 8128 is perfect ... 8128 is perfect = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 Checking to see if mersenne( 11 ) = 2096128 is perfect ... nope. Checking to see if mersenne( 13 ) = 33550336 is perfect ... 33550336 is perfect = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8191 + 16382 + 32764 + 65528 + 131056 + 262112 + 524224 + 1048448 + 2096896 + 4193792 + 8387584 + 16775168 mdhcp237:Desktop$ """ def get_factors(n): """ Return a list of the factors of n, including 1 but excluding n. >>> factors(6) [1, 2, 3] """ answer = [] i = 0 while i <= n/2: i = i+1 if n % i == 0: answer.append(i) return answer def print_progress(n): """ Print something to show how big n is every so often. """ interval = 1e3 # How often to show something if n % interval == 0: print " ... n =", n, '...' def string_sum(list): """ Convert a list like [1,2,3] to a string like '1 + 2 + 3'.""" return str(list).replace(', ', ' + ').replace('[','').replace(']','') def check_perfect(n): factors = get_factors(n) if sum(factors) == n: print n, "is perfect = ", string_sum(factors) return True else: return False def check_mersenne(p): n = 2**(p-1)*(2**p-1) print "Checking to see if mersenne(", p, ") = ",n, "is perfect ..." if not check_perfect(n): print 'nope.' def brute_force_search(max_n): n = 1 max_n = int(max_n) print "Looking for perfect numbers up to ", max_n, " ..." while n <= max_n: n = n + 1 print_progress(n) check_perfect(n) brute_force_search(1e4) check_mersenne(7) check_mersenne(11) check_mersenne(13)