/ Python / 2016 / 14.py
14.py
 1  from lib import *
 2  
 3  input = read_input(2016, 14).strip()
 4  
 5  
 6  def hash(idx):
 7      return hashlib.md5(f"{input}{idx}".encode()).hexdigest()
 8  
 9  
10  def first(idx):
11      if match := re.match(r"^.*?((.)\2{2}).*$", hash(idx)):
12          return match.group(2)
13  
14  
15  def second(idx, m):
16      for i in range(1, 1001):
17          if m * 5 in hash(idx + i):
18              return True
19  
20      return False
21  
22  
23  idx = 0
24  cnt = 0
25  while True:
26      if (x := first(idx)) and second(idx, x):
27          cnt += 1
28      if cnt == 64:
29          break
30      idx += 1
31  
32  print(idx)
33  
34  
35  dp = {}
36  
37  
38  def hash(idx):
39      if idx in dp:
40          return dp[idx]
41  
42      out = hashlib.md5(f"{input}{idx}".encode()).hexdigest()
43  
44      for _ in range(2016):
45          out = hashlib.md5(out.encode()).hexdigest()
46  
47      dp[idx] = out
48  
49      return out
50  
51  
52  def first(idx):
53      if match := re.match(r"^.*?((.)\2{2}).*$", hash(idx)):
54          return match.group(2)
55  
56  
57  def second(idx, m):
58      for i in range(1, 1001):
59          if m * 5 in hash(idx + i):
60              return True
61  
62      return False
63  
64  
65  idx = 0
66  cnt = 0
67  while True:
68      if (x := first(idx)) and second(idx, x):
69          cnt += 1
70      if cnt == 64:
71          break
72      idx += 1
73  
74  print(idx)