def makeCandidates(lst, sieve): ''' Make a list of candidates for this problem. ''' primeSet = set() for p in lst: digits = digitize(p) if len(digits) != 4: continue # Check if at least 3 permutations give primes and add the maximum # value from the permutations to the candidates count = 0 m = 0 for perm in permuteInts(digits): if perm > 1000 and primeSieve[perm]: count += 1 m = max(perm, m) if count >= 3: primeSet.add(m) permList = [] for p in primeSet: tmpLst = [] for perm in permuteInts(digitize(p)): if primeSieve[perm] and perm > 1000: tmpLst.append(perm) permList.append(sorted(tmpLst)) return permList
def solve(): potentialPrimes = [] # Compute potential candidates (could be sped up by removing this) for p in primeList: possibleDigits = possible(p) if possibleDigits: potentialPrimes.append((p, possibleDigits)) # Loop through potential primes for p, digitList in potentialPrimes: digits = digitize(p) for d in digitList: # Count the size of the family familySize = 0 for i in xrange(10): # Replace the desired digits newDigits = listReplace(digits, d, i) newNum = undigitize(newDigits) # Make sure that we are not replacing the leading # number with a 0 if len(digitize(newNum)) < len(digits): continue if primeSieve[newNum]: familySize += 1 if familySize >= FAMILY_SIZE: return p # No answer found... return None
def findTruncatable(): primeCount = 0 primeSum = 0 # Guess at an upper bound primeList, primeSieve = slowPrimes(1000000) for p in primeList[4:]: digits = digitize(p) for i in xrange(1, len(digits)): num = undigitize(digits[i:]) if not primeSieve[num]: break num = undigitize(digits[:-1*i]) if not primeSieve[num]: break else: primeCount += 1 primeSum += p if primeCount == 11: break # Check that we reached 11 primes print(primeCount) return primeSum
def rotate(n): ''' Rotate the number n. e.g. 123 -> 123, 231, 312 This is a generator. ''' digitList = digitize(n) for i in xrange(len(digitList)): yield undigitize(digitList[i:] + digitList[:i])
def multiples(): ''' Find largest pandigital number formed as a concatenated product of an integer with (1, 2, ..., n) with n > 1 ''' maxProd = 918273645 # Check up to 4 digit numbers for i in xrange(9111, 10000): prod = digitize(i) if prod[0] != 9: continue p = 2 while(len(prod) < 9): prod += digitize(p * i) p += 1 if isPandigital(prod): maxProd = max(undigitize(prod), maxProd) return maxProd
def possible(p): # We know this lower bound from the question statement if p < 56000: return False digits = digitize(p) digitCount = Counter(digits) # Possible digits are ones that are repeated a multiple of 3 times possibleDigits = {d for d, c in digitCount.items() if c % 3 == 0} return possibleDigits
def isLychrel(n): ''' Determine if n is a "Lychrel" number. ''' for _ in range(0, 50): digits = euler.digitize(n) revN = euler.undigitize(digits[::-1]) n = revN + n if isPalindrome(n): return False return True
def getAnswer(): answerList = [] for n in xrange(10, 1000, 2): d = digitize(n) if n < 100: d.insert(0, 0) sd = set(d) if len(d) != len(sd): continue compute([17, 13, 11, 7, 5, 3], d, sd, answerList) return sum(answerList)
def dblPal(): ''' Find sum of all double palindromes (base 2 and 10) below 1000000. ''' palSum = 0 # Also do the 1 digit numbers for num in xrange(1, 10, 2): if isPalindrome(bin(num)[2:]): palSum += num # All palindromes that are 2, 3, 4, 5 digits in length for x in xrange(1, 100): digits = digitize(x) if digits[0] % 2 == 0: continue endDigits = digits[::-1] num = undigitize(digits + endDigits) if isPalindrome(bin(num)[2:]): palSum += num for d in xrange(10): num = undigitize(digits + [d] + endDigits) if isPalindrome(bin(num)[2:]): palSum += num # Also do the 6 digit numbers for x in xrange(100, 1000): digits = digitize(x) if digits[0] % 2 == 0: continue endDigits = digits[::-1] num = undigitize(digits + endDigits) if isPalindrome(bin(num)[2:]): palSum += num return palSum
def findCircular(n): ''' Find all circular primes below n. ''' primeList, primeSieve = primes(n) # 2 and 5 will be skipped circleCount = 2 for p in primeList: # If any even nums then at least 1 permutation cannot be prime if any(n % 2 == 0 or n == 5 for n in digitize(p)): continue if all(primeSieve[(r - 3) / 2] for r in rotate(p)): circleCount += 1 return circleCount
def getDigit(n): ''' Retrieve the nth digit from Champernowe's constant. ''' digits = 1 while True: if getDigit.numDigits[digits-1] > n: break n -= getDigit.numDigits[digits-1] digits += 1 pwr = 10**(digits-1) n -= 1 # n is now the number of digits into this we go # Find what number after the power of 10 n belongs to num = n / digits num += pwr return digitize(num)[n % digits]
def isPalindrome(n): ''' Determine if n is a palindrome. ''' digits = euler.digitize(n) return euler.isPalindrome(digits)
from collections import Counter from euler import digitize, undigitize n = 100 while True: digits = digitize(n) digits.insert(0, 1) dCount = Counter(digits) newNum = undigitize(digits) for i in xrange(2, 7): if Counter(digitize(newNum*i)) != dCount: break else: print(newNum) break n += 1