2017-12-10 - Knot Hash
(original .ipynb)
puzzle_input_str = "34,88,2,222,254,93,150,0,199,255,39,32,137,136,1,167"
test_input_str = "3,4,1,5"
full_length = 256 # lengths = [0,1,2,3...255]
test_length = 5 # lengths = [0,1,2,3,4]
def rotate_list(lst, pos, length):
sublist = []
wrapped = 0
while length > 0:
if pos < len(lst):
sublist.append(lst.pop(pos))
length -= 1
else:
sublist.append(lst.pop(0))
length -= 1
wrapped += 1
while wrapped > 0:
lst.insert(0, sublist.pop(0))
wrapped -= 1
while len(sublist) > 0:
lst.insert(pos, sublist.pop(0))
return lst
def perform_round(lengths, lst, pos=0, skip=0):
for length in lengths:
lst = rotate_list(lst, pos, length)
pos = (pos + length + skip) % len(lst)
skip += 1
return lst, pos, skip
def part_one(input_str, list_length):
lengths = [int(s) for s in input_str.split(",")]
lst = list(range(0, list_length))
hashed_lst, _, _ = perform_round(lengths, lst, list_length)
return hashed_lst[0] * hashed_lst[1]
assert 12 == part_one(test_input_str, test_length)
print("part one:", part_one(puzzle_input_str, full_length))
part one: 54675
def hash_block(block, sparse_hash):
idx = block*16
values = sparse_hash[idx:idx+16]
hash_block = 0
for value in values:
hash_block ^= value
hex_hash = hex(hash_block)[2:]
if len(hex_hash) == 1:
return "0"+hex_hash
return hex_hash
assert "40" == hash_block(0, [65, 27, 9, 1, 4, 3, 40, 50, 91, 7, 6, 0, 2, 5, 68, 22])
def part_two(input_str):
lengths = [ ord(c) for c in input_str ] + [17, 31, 73, 47, 23]
current_round = 64
skip = 0
pos = 0
sparse_hash = list(range(0, full_length))
while current_round > 0:
current_round -= 1
sparse_hash, pos, skip = perform_round(lengths, sparse_hash, pos, skip)
assert 256 == len(sparse_hash)
block = 0
dense_hash_lst = []
while block < 16:
dense_hash_lst.append(hash_block(block, sparse_hash))
block += 1
return "".join(dense_hash_lst).strip()
assert part_two("") == "a2582a3a0e66e6e86e3812dcb672a272"
assert part_two("AoC 2017") == "33efeb34ea91902bb2f59c9920caa6cd"
assert part_two("1,2,3") == "3efbe78a8d82f29979031a4aa0b16a9d"
assert part_two("1,2,4") == "63960835bcdc130f0b66d7ff4f6a5a8e"
print("part two:", part_two(puzzle_input_str))
part two: a7af2706aa9a09cf5d848c1e6605dd2a