From f09f83e0a464cd794b762626c06aa3a1acb53149 Mon Sep 17 00:00:00 2001 From: julien Lengrand-Lambert Date: Tue, 1 May 2012 22:03:10 +0200 Subject: [PATCH] Finally solves problem 35. Problem of . . . definition . --- .pydevproject | 2 +- e_35.py | 115 ++++++++++++++++++++++++++++------------- e_35_2.py | 138 -------------------------------------------------- 3 files changed, 81 insertions(+), 174 deletions(-) delete mode 100644 e_35_2.py diff --git a/.pydevproject b/.pydevproject index 2bf883f..5c1a10e 100644 --- a/.pydevproject +++ b/.pydevproject @@ -3,7 +3,7 @@ -/project_euler +/peuler python 2.7 Default diff --git a/e_35.py b/e_35.py index 06ed339..693db2b 100644 --- a/e_35.py +++ b/e_35.py @@ -13,8 +13,25 @@ """ import pickle +def shift(seq, n): + """ + Shifts a sequence by n rotations + """ + seq = str(seq) + return int(seq[n:]+seq[:n]) + +def all_rotations(seq): + """ + Returns a list of all possible rotations of a number + """ + out = [] + for n in range(len(str(seq))): + out.append(int(shift(str(seq), n))) + + return out + def all_permutations(seq): - """permutate a sequence and return a list of the permutations""" + """permutates a sequence and returns a list of the permutations""" if not seq: return [seq] # is an empty sequence else: @@ -53,47 +70,75 @@ def prime_list(max_val): return plist +def contains_even(val): + """ + Returns True if val contains an even number (ex : 998) + """ + return ((str(2) in str(val)) or (str(4) in str(val)) or (str(6) in str(val)) or (str(8) in str(val))) + +def divisible_by_5(val): + """ + Returns True if any circular permutation of val is divisible by (ex : 907) + """ + return ((str(5) in str(val)) or (str(0) in str(val))) + +def divisible_by_3(val): + """ + Returns True if any circular permutation of val is divisible by 3 (ex : 12) + """ + temp = sum([int(p) for p in str(val)]) + if len(str(temp)) > 1: + divisible_by_3(temp) + else: + return ((temp % 3) == 0) + +def check_easy_out(plist): + """ + Returns the number of circular primes below max_val + + TODO : offer cleaner method + """ + pred = list(plist) + for p in plist: + if p > 11: # my filter does not work for values under 10 + # ugly method + if (contains_even(p) or divisible_by_5(p)): # no prime divisible by 3 . . . + pred.remove(p) + return pred def perm_primes(max_val): """ Returns the number of circular primes below max_val """ - circulars = 0 - circl = [] + plist = prime_list(max_val) + #plist = pickle.load(open("primes_list.dup", "rb")) + p_reduced = check_easy_out(plist) - # to avoid calculating primes - plist = pickle.load(open("primes_list.dup", "rb")) - #plist = prime_list(max_val) - checks_list = [1] * len(plist) # all primes to be tested + p_out = [] - for ii in range(len(plist)): - if (ii % 99 == 0): - print "%d/%d" % ( ii + 1, len(plist)) - - if checks_list[ii]: # if prime still to be checked - prime = plist[ii] - perms = all_permutations(str(prime)) # finds all permutations - - # counts how many permutations are in prime list given one prime - p_cpt = 0 - for perm in perms: - if int(perm) in plist: - p_cpt += 1 - - # if prime is circular - if p_cpt == len(perms): - # updating checks_list - for perm in perms: - if not(int(perm) in circl): # avoiding duplicates - circulars += 1 - circl.append(int(perm)) - checks_list[plist.index(int(perm))] = 0 - - else: - checks_list[ii] = 0 + print len(plist) + print len(p_reduced) - return circulars, circl + print p_reduced + + for p in p_reduced: + perms = all_rotations(p) + perms = list(set(perms)) # removes duplicates + perms = [int(p) for p in perms] + + circl = 0 + for pp in perms: + if pp in p_reduced: # in list of primes + circl += 1 + + if circl == len(perms): + p_out = p_out + perms + + circl = 0 + + p_out = list(set(p_out)) + return len(p_out) if __name__ == '__main__' : - answer, plist = perm_primes(1000000) - print "Answer is : %d" % (answer) \ No newline at end of file + answer = perm_primes(1000000) + print "Answer is : %d" % (answer) \ No newline at end of file diff --git a/e_35_2.py b/e_35_2.py deleted file mode 100644 index 45889bf..0000000 --- a/e_35_2.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -""" - ##--- - # Julien Lengrand-Lambert - #Created on : Thu Jan 19 10:12:06 CET 2012 - # - # DESCRIPTION : Solves problem 35 of Project Euler - The number, 197, is called a circular prime because all rotations of the digits: - 197, 971, and 719, are themselves prime. - There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97. - How many circular primes are there below one million? - ##--- - """ -import pickle - -def all_permutations(seq): - """permutate a sequence and return a list of the permutations""" - if not seq: - return [seq] # is an empty sequence - else: - temp = [] - for k in range(len(seq)): - part = seq[:k] + seq[k+1:] - for m in all_permutations(part): - temp.append(seq[k:k+1] + m) - return temp - -def is_prime(value): - """ - Returns True or False depending whether value is prime or not. - """ - start = 2 - while (start <= value / 2): - if value % start == 0 : - return False - else : - start += 1 - return True - -def prime_list(max_val): - """ - Returns a list of all primes below max_val - """ - plist = [] - cur = 2 - while (cur < max_val): - if (cur % 1000) == 0: - print "%d/%d" % (cur, max_val) - - if (is_prime(cur)): - plist.append(cur) - cur += 1 - - return plist - -def contains_even(val): - """ - Returns True f val contains an even number (ex : 998) - """ - return (str(2) in str(val) or str(4) in str(val) or str(6) in str(val) or str(8) in str(val)) - -def divisible_by_3(val): - """ - Returns True of val is divisible by 3 (ex : 12) - """ - temp = sum([int(p) for p in str(val)]) - if len(str(temp)) > 1: - divisible_by_3(temp) - else: - return ((temp % 3) == 0) - -def check_easy_out(plist): - """ - Returns the number of circular primes below max_val - - TODO : offer cleaner method - """ - pred = list(plist) - for p in plist: - if p > 11: # my filter does not work for values under 10 - # ugly method - #if (contains_even(p) or divisible_by_3(p)): - if (contains_even(p)): # no prime divisible by 3 . . . - # could also test for 3 and 9 - pred.remove(p) - return pred - -def perm_primes(max_val): - """ - Returns the number of circular primes below max_val - """ - circulars = 0 - circl = [] - - #plist = prime_list(max_val) - plist = pickle.load(open("primes_list.dup", "rb")) - p_reduced = check_easy_out(plist) - - print len(plist) - print len(p_reduced) - - print p_reduced - - checks_list = [1] * len(p_reduced) # all primes to be tested - - for ii in range(len(p_reduced)): - if (ii % 99 == 0): - print "%d/%d" % ( ii + 1, len(p_reduced)) - - if checks_list[ii]: # if prime still to be checked - prime = p_reduced[ii] - perms = all_permutations(str(prime)) # finds all permutations - - # counts how many permutations are in prime list given one prime - p_cpt = 0 - for perm in perms: - if int(perm) in p_reduced: - p_cpt += 1 - - # if prime is circular - if p_cpt == len(perms): - # updating checks_list - for perm in perms: - if not(int(perm) in circl): # avoiding duplicates - circulars += 1 - circl.append(int(perm)) - checks_list[p_reduced.index(int(perm))] = 0 - - else: - checks_list[ii] = 0 - - return circulars, circl - - -if __name__ == '__main__' : - #perm_primes(1000000) - answer, plist = perm_primes(1000000) - print "Answer is : %d" % (answer) \ No newline at end of file