Solve 2016:14 p1-2 "One-Time Pad"
Lost 60 minutes due to misinterpreting this in p2: > *whenever* you generate a hash The code initially only did the 2016 stretching for the triplet hash, not the quintet hash. By doing it to both, pt 2 is solved. Not sure the lru cache actually speeds anything up. Many on the subreddit used the approach to generate the quintet first and look backwards 1000 times for a matching quintet (since quintets are more rare than triplets), this will most likely speed things up. Also, this solution do not store the found keys. Many other solutions do, I believe this is some presumptions.
This commit is contained in:
parent
c113042e17
commit
31bb5b7006
1 changed files with 75 additions and 0 deletions
75
2016-python2/output/day_14.py
Normal file
75
2016-python2/output/day_14.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import functools
|
||||
import re
|
||||
from hashlib import md5
|
||||
|
||||
from output import answer # , matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg
|
||||
|
||||
n = 14
|
||||
title = "One-Time Pad"
|
||||
|
||||
|
||||
@answer(1, "64th key is at index {}")
|
||||
def part_1(presolved):
|
||||
return presolved[0]
|
||||
|
||||
|
||||
@answer(2, "64th key is at index {} using key stretching")
|
||||
def part_2(presolved):
|
||||
return presolved[1]
|
||||
|
||||
|
||||
def solve(s):
|
||||
p1 = run(s)
|
||||
p2 = run(s, p2=True)
|
||||
return p1, p2
|
||||
|
||||
|
||||
def run(s, p2=False):
|
||||
r3 = re.compile(r"(\w)\1{2}")
|
||||
c = 0
|
||||
i = 0
|
||||
H = md5(s.encode())
|
||||
while True:
|
||||
i += 1
|
||||
if p2:
|
||||
a = stretch(f"{s}{i}")
|
||||
else:
|
||||
Ha = H.copy()
|
||||
Ha.update(str(i).encode())
|
||||
a = Ha.hexdigest()
|
||||
if m := re.search(r3, a):
|
||||
x = m.group(1)
|
||||
r5 = re.compile(r"(" + x + r")\1{4}")
|
||||
for j in range(1000):
|
||||
if p2:
|
||||
b = stretch(f"{s}{str(i + 1 + j)}")
|
||||
else:
|
||||
Hb = H.copy()
|
||||
Hb.update(str(i + 1 + j).encode())
|
||||
b = Hb.hexdigest()
|
||||
if re.search(r5, b):
|
||||
c += 1
|
||||
break
|
||||
if c == 64:
|
||||
break
|
||||
return i
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def stretch(s):
|
||||
for _ in range(2017):
|
||||
s = md5(s.encode()).hexdigest()
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("./input/14.txt", "r") as f:
|
||||
inp = f.read().strip()
|
||||
|
||||
inp = solve(inp)
|
||||
|
||||
a = part_1(inp)
|
||||
b = part_2(inp)
|
||||
|
||||
assert a == 18626
|
||||
assert b == 20092
|
||||
Loading…
Add table
Reference in a new issue