62 lines
1.3 KiB
Python
62 lines
1.3 KiB
Python
from functools import reduce
|
|
|
|
with open("input/day10.txt") as f:
|
|
size, input = 256, f.read().strip()
|
|
|
|
|
|
def part1(size, input):
|
|
lengths = [int(i) for i in input.split(",")]
|
|
|
|
ring = list(range(size))
|
|
_, _, ring = hash_round(0, 0, ring, lengths)
|
|
|
|
return ring[0] * ring[1]
|
|
|
|
|
|
def hash_round(pos, skip, ring, lengths):
|
|
for length in lengths:
|
|
assert length <= len(ring), "overlap undefined"
|
|
|
|
tail = min(length, len(ring) - pos)
|
|
head = max(length - tail, 0)
|
|
|
|
a = pos + tail
|
|
b = 0 + head
|
|
|
|
prefix = ring[b:pos]
|
|
inside = ring[pos:a] + ring[:b]
|
|
suffix = ring[a:]
|
|
|
|
assert length == len(inside)
|
|
|
|
twisted = inside[::-1]
|
|
|
|
ring = twisted[tail:] + prefix + twisted[:tail] + suffix
|
|
pos = (pos + length + skip) % len(ring)
|
|
skip += 1
|
|
|
|
return pos, skip, ring
|
|
|
|
|
|
def part2(size, input):
|
|
lengths = [ord(c) for c in input] + [17, 31, 73, 47, 23]
|
|
|
|
pos, skip = 0, 0
|
|
ring = list(range(size))
|
|
for _ in range(64):
|
|
pos, skip, ring = hash_round(pos, skip, ring, lengths)
|
|
|
|
dense = [0] * 16
|
|
for i in range(16):
|
|
start = 16 * i
|
|
block = ring[start : start + 16]
|
|
dense[i] = reduce(int.__xor__, block)
|
|
|
|
out = ""
|
|
for d in dense:
|
|
out += f"{d:02x}"
|
|
return out
|
|
|
|
|
|
print(part1(size, input))
|
|
print(part2(size, input))
|