from tools.aoc import AOCDay from typing import Any def cycle(sequence: list, sizes: list, index: int = 0, skip_length: int = 0) -> (list, int, int): for size in sizes: for inc in range(size // 2): l, r = (index + inc) % 256, (index + size - inc - 1) % 256 sequence[l], sequence[r] = sequence[r], sequence[l] index = (index + size + skip_length) % 256 skip_length += 1 return sequence, index, skip_length def knot_hash(key: str, rounds: int = 64) -> str: index = 0 skip_length = 0 sequence = list(range(256)) key = [ord(x) for x in key] key += [17, 31, 73, 47, 23] for i in range(rounds): sequence, index, skip_length = cycle(sequence, key, index, skip_length) dense = [] for m in range(16): xor = 0 for i in range(16): xor ^= sequence[m * 16 + i] dense.append(xor) hex_string = "" for v in dense: hex_string += ("%x" % v).rjust(2, '0') return hex_string class Day(AOCDay): inputs = [ [ (62238, "input10") ], [ ("2b0c9cc0449507a0db3babd57ad9e8d8", "input10") ] ] def part1(self) -> Any: sizes = self.getInputAsArraySplit(",", int) sequence, _, _ = cycle(list(range(256)), sizes) return sequence[0] * sequence[1] def part2(self) -> Any: return knot_hash(self.getInput().strip()) if __name__ == '__main__': day = Day(2017, 10) day.run(verbose=True)