from tools.aoc import AOCDay from typing import Any DP = {} def dance(moves: list, sequence: list) -> list: key = str(sequence) if key in DP: return DP[key].copy() for move in moves: if move.startswith("s"): s = int(move[1:]) sequence = sequence[-s:] + sequence[:-s] elif move.startswith("x"): a, b = map(int, move[1:].split("/")) sequence[a], sequence[b] = sequence[b], sequence[a] elif move.startswith("p"): a, b = map(ord, move[1:].split("/")) a, b = sequence.index(a - 97), sequence.index(b - 97) sequence[a], sequence[b] = sequence[b], sequence[a] else: print("Unknown Move:", move) DP[key] = sequence.copy() return sequence class Day(AOCDay): inputs = [ [ ("paedcbfghijklmno", "input16_test"), ("ehdpincaogkblmfj", "input16") ], [ ("bpcekomfgjdlinha", "input16") ] ] def part1(self) -> Any: global DP DP = {} moves = self.getInput().split(",") init = dance(moves, list(range(16))) return "".join([chr(x + 97) for x in init]) def part2(self) -> Any: global DP DP = {} # part1 times 1_000_000_000??? # there must be a better way! moves = self.getInput().split(",") sequence = list(range(16)) for i in range(1_000_000_000): sequence = dance(moves, sequence) return "".join([chr(x + 97) for x in sequence]) if __name__ == '__main__': day = Day(2017, 16) day.run(verbose=True)