From a4d31debeb55f450331cb2168689f6ad62007602 Mon Sep 17 00:00:00 2001 From: Philippe Zwietering Date: Tue, 6 Apr 2021 01:16:05 +0200 Subject: [PATCH] Strictly speaking this algorithm has an O(n^2) part in it, but it runs under a second so... --- 51/main.py | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/51/main.py b/51/main.py index 61bc247..1909359 100644 --- a/51/main.py +++ b/51/main.py @@ -8,6 +8,7 @@ Find the smallest prime which, by replacing part of the number (not necessarily import numpy as np import math +import time def sieve(n): assert n > 1 @@ -24,13 +25,52 @@ def sieve(n): return [i for i,val in enumerate(ns) if val][2:] +# Does generate all families that can be made for that number, so that consists of multiple families together +def families(num): + result = [] + variedDigits = set() + digits = [int(d) for d in str(num)] + + for i in range(len(digits)): + if not i in variedDigits: + buddies = [] + + for j in range(len(digits)): + if digits[i] == digits[j]: + buddies.append(j) + variedDigits.add(j) + + r = digits[:] + + for n in range(10): + for bud in buddies: + r[bud] = n + maybeResult = int("".join([str(_r) for _r in r])) + result.append(maybeResult) + + return result + +def findPrimeFamily(length): + primes = sieve(1000000) + primeSet = set(primes) + + for p in primes: + primeFamilies = families(p) + + for i in range(len(primeFamilies) // 10): + counter = 0 + for pf in primeFamilies[10*i:10*i+10]: + if pf in primeSet and len(str(pf)) == len(str(p)): + counter += 1 + if counter >= length: + return [x for x in primeFamilies[10*i:10*i+10] if x in primeSet] + def main(): print("Hello this is Patrick") - primes = sieve(1000000) + t0 = time.time() - # So instead of going past all number families and see if they are prime I think it's better to look for families in the primes - # Quite the combinatorial problem indeed, lots of permutations and I don't immediately see an easy way to fix it + print(findPrimeFamily(8), time.time() - t0) if __name__ == "__main__": main()