"""John Borwick, 13 Apr 2005""" import math, operator """constants for problem:""" AGE_SUM=50 NUM_COUSINS=3 class Set(object): """This class ensures [2,3] and [3,2] are only stored once""" def __init__(self, array=None): if array == None: array = [] self._set = [] for i in array: self.add( i) def __iter__(self): """this lets "for x in Set" work""" self._offset = 0 return self def __len__(self): return len(self._set) def __str__(self): """this prints out the Set in a pretty way""" output = "{\n" for i in self._set: output += " %s,\n" % i output += "}" return output def next(self): """used in combination with __iter__. counter in self._offset""" offset = self._offset if offset >= len(self._set): raise StopIteration self._offset +=1 return self._set[ offset ] def add(self, obj): add_obj = obj add_obj.sort() if not add_obj in self._set: self._set.append( add_obj) def pop(self): return self._set.pop() def is_prime(num): """returns whether a given number is prime""" if num < 2: return False for i in range(2, int(math.sqrt(num)+1)): if num % i == 0: return False return True def primes(min, max): """returns all primes in a given range""" primes = [] for i in range(min,max+1): if is_prime(i): primes.append(i) return primes def prime_sum_set(total, num_elements=NUM_COUSINS): """ Two arguments: total: sum required num_elements: how many elements allowed to reach total Returns a Set if there are solutions. Otherwise, returns None. """ # Degenerative case... if num_elements <= 1: if is_prime( total): return Set( [[total]] ) else: return None # sets = Set() for i in primes( 2, total ): # for all the possible primes trial_set = prime_sum_set( total-i, num_elements= num_elements-1) # recursively get the set of solutions # to the other half of the problem ( i + trial_set = total ) if trial_set == None: continue for trial_array in trial_set: # for each solution, add the current prime trial_array.append( i ) sets.add( trial_array ) if len(sets): return sets else: return None if __name__ == '__main__': # where the answers go solution_sets = Set() for john_age in primes( 2, AGE_SUM): # for each possible age for John cousins = prime_sum_set( AGE_SUM-john_age ) # generate all sets st john_age + set is AGE_SUM if cousins == None: pass elif len(cousins) == 1: # if you got exactly one... solution = cousins.pop() print "John age=%d implies cousins aged" % john_age, solution solution.append( john_age) solution_sets.add( solution ) print solution_sets