Advertisement
Sp3000

Hexdigit product pangrams

May 7th, 2016
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.43 KB | None | 0 0
  1. from collections import Counter
  2. import itertools
  3. import string
  4. import sys
  5. import time
  6.  
  7. from sympy import factorint
  8.  
  9. start_time = time.time()
  10. # Lowercase because hex returns lowercase
  11. HEX_DIGITS = "fedcba9876543210"
  12.  
  13. factorisations = {}
  14.  
  15. for num_str in itertools.chain(itertools.permutations(HEX_DIGITS, 3),
  16.                                itertools.permutations(HEX_DIGITS, 5)):
  17.     num_str = ''.join(num_str)
  18.     factorisations[num_str] = factorint(int(num_str, 16))
  19.  
  20. count = 0
  21. last = None
  22. solutions = set()
  23.  
  24. numbers_seen = 0
  25. total_factorisations_seen = 0
  26.  
  27. for digits in itertools.permutations(HEX_DIGITS, 8):
  28.     # Print progress because it's fun to watch progress
  29.     if digits[:5] != last:
  30.         print(digits[:5], last and total_factorisations_seen/numbers_seen, flush=True, file=sys.stderr)
  31.         last = digits[:5]
  32.         numbers_seen = 0
  33.         total_factorisations_seen = 0
  34.  
  35.     a_str = ''.join(digits[:3])
  36.     b_str = ''.join(digits[3:])
  37.     a = int(a_str, 16)
  38.     b = int(b_str, 16)
  39.     n = a*b
  40.  
  41.     numbers_seen += 1
  42.  
  43.     a_factors = factorisations[a_str]
  44.     b_factors = factorisations[b_str]
  45.  
  46.     combined = Counter(a_factors)
  47.     combined.update(b_factors)
  48.  
  49.     primes = sorted(combined)
  50.     search_stack = [[1, {p:0 for p in primes}]]
  51.     seen = set()
  52.  
  53.     while search_stack:
  54.         total_factorisations_seen += 1
  55.         num, num_factorisation = search_stack.pop()
  56.         seen.add(tuple(num_factorisation[p] for p in primes))
  57.  
  58.         if num > a:
  59.             continue
  60.  
  61.         c_str = hex(num)[2:].zfill(3)
  62.         d_str = hex(n//num)[2:].zfill(5)
  63.  
  64.         if len(c_str) == 3 and len(d_str) == 5 and len(set(c_str+d_str+''.join(digits))) == 16:
  65.             t = (a,b,num,n//num)
  66.             t = tuple(sorted(t))
  67.  
  68.             if t not in solutions:
  69.                 print("0x{} * 0x{} == 0x{} * 0x{}".format(a_str, b_str, c_str, d_str), flush=True)
  70.                 solutions.add(t)
  71.                 count += 1
  72.  
  73.         for i,p in enumerate(primes):
  74.             if num_factorisation[p] < combined[p]:
  75.                 new_num_factorisation = num_factorisation.copy()
  76.                 new_num_factorisation[p] += 1
  77.  
  78.                 if tuple(new_num_factorisation[p] for p in primes) in seen:
  79.                     continue
  80.                
  81.                 new_num = num*p
  82.  
  83.                 search_stack.append([new_num, new_num_factorisation])
  84.  
  85. print(count)
  86. print(time.time() - start_time)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement