From ecc905545bf7350023c25bef96575f0d270a55cf Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sun, 12 Jan 2025 09:47:12 +0100 Subject: [PATCH] day21 --- day21.py | 101 ++++++++++++++++++++++++++++++++++++++++++++ inputs/input21 | 100 +++++++++++++++++++++++++++++++++++++++++++ inputs/input21_test | 8 ++++ 3 files changed, 209 insertions(+) create mode 100644 day21.py create mode 100644 inputs/input21 create mode 100644 inputs/input21_test diff --git a/day21.py b/day21.py new file mode 100644 index 0000000..afe608b --- /dev/null +++ b/day21.py @@ -0,0 +1,101 @@ +from enum import Enum +from tools.aoc import AOCDay +from tools.types import String +from typing import Any + + +class OP(int, Enum): + SWAP = 0 + ROTATE = 1 + REVERSE = 2 + MOVE = 3 + + +def scramble(password: String, ops: list[tuple[OP, Any, ...]], reverse: bool = False) -> str: + if reverse: + ops = list(reversed(ops)) + + def get_rotate_num(c: str) -> int: + return 1 + password.index(c) + (password.index(c) >= 4) + + for op in ops: + if op[0] == OP.SWAP: + x, y = op[1], op[2] + if not isinstance(x, int) or not isinstance(y, int): + x, y = password.index(x), password.index(y) + + password = password.swap(x, y) + elif op[0] == OP.ROTATE: + rot = op[1] + if isinstance(rot, int): + if reverse: + rot *= -1 + password = password.rotate(rot) + else: + if not reverse: + rot = get_rotate_num(rot) + password = password.rotate(rot) + else: + rot_count = 0 + while rot_count != get_rotate_num(rot): + rot_count += 1 + password = password.rotate(-1) + elif op[0] == OP.REVERSE: + x, y = op[1], op[2] + password = password.reverse(x, y) + elif op[0] == OP.MOVE: + x, y = op[1], op[2] + if reverse: + x, y = y, x + + to_move = password[x] + password = String(password[:x] + password[x + 1 :]) + password = String(password[:y] + to_move + password[y:]) + + return password + + +class Day(AOCDay): + inputs = [ + [ + ("decab", "input21_test"), + ("gfdhebac", "input21"), + ], + [ + ("dhaegfbc", "input21"), + ], + ] + + def parse_input(self) -> list[tuple[OP, Any, ...]]: + instr = [] + for line in self.getInput(): + parts = line.split() + if parts[0] == "swap": + if parts[1] == "position": + instr.append((OP.SWAP, int(parts[2]), int(parts[5]))) + else: + instr.append((OP.SWAP, parts[2], parts[5])) + elif parts[0] == "rotate": + if parts[1] == "based": + instr.append((OP.ROTATE, parts[6])) + else: + instr.append((OP.ROTATE, int(parts[2]) * (-1 if parts[1] == "left" else 1))) + elif parts[0] == "reverse": + instr.append((OP.REVERSE, int(parts[2]), int(parts[4]))) + else: + instr.append((OP.MOVE, int(parts[2]), int(parts[5]))) + + return instr + + def part1(self) -> Any: + to_scramble = String("abcde") if self.is_test() else String("abcdefgh") + return scramble(to_scramble, self.parse_input()) + + def part2(self) -> Any: + to_unscramble = String("fbgdceah") + return scramble(to_unscramble, self.parse_input(), reverse=True) + + +if __name__ == "__main__": + day = Day(2016, 21) + day.run(verbose=True) diff --git a/inputs/input21 b/inputs/input21 new file mode 100644 index 0000000..b39b884 --- /dev/null +++ b/inputs/input21 @@ -0,0 +1,100 @@ +reverse positions 1 through 6 +rotate based on position of letter a +swap position 4 with position 1 +reverse positions 1 through 5 +move position 5 to position 7 +swap position 4 with position 0 +swap position 4 with position 6 +rotate based on position of letter a +swap position 0 with position 2 +move position 5 to position 2 +move position 7 to position 1 +swap letter d with letter c +swap position 5 with position 3 +reverse positions 3 through 7 +rotate based on position of letter d +swap position 7 with position 5 +rotate based on position of letter f +swap position 4 with position 1 +swap position 3 with position 6 +reverse positions 4 through 7 +rotate based on position of letter c +move position 0 to position 5 +swap position 7 with position 4 +rotate based on position of letter f +reverse positions 1 through 3 +move position 5 to position 3 +rotate based on position of letter g +reverse positions 2 through 5 +rotate right 0 steps +rotate left 0 steps +swap letter f with letter b +rotate based on position of letter h +move position 1 to position 3 +reverse positions 3 through 6 +rotate based on position of letter h +swap position 4 with position 3 +swap letter b with letter h +swap letter a with letter h +reverse positions 1 through 6 +swap position 3 with position 6 +swap letter e with letter d +swap letter e with letter h +swap position 1 with position 5 +rotate based on position of letter a +reverse positions 4 through 5 +swap position 0 with position 4 +reverse positions 0 through 3 +move position 7 to position 2 +swap letter e with letter c +swap position 3 with position 4 +rotate left 3 steps +rotate left 7 steps +rotate based on position of letter e +reverse positions 5 through 6 +move position 1 to position 5 +move position 1 to position 2 +rotate left 1 step +move position 7 to position 6 +rotate left 0 steps +reverse positions 5 through 6 +reverse positions 3 through 7 +swap letter d with letter e +rotate right 3 steps +swap position 2 with position 1 +swap position 5 with position 7 +swap letter h with letter d +swap letter c with letter d +rotate based on position of letter d +swap letter d with letter g +reverse positions 0 through 1 +rotate right 0 steps +swap position 2 with position 3 +rotate left 4 steps +rotate left 5 steps +move position 7 to position 0 +rotate right 1 step +swap letter g with letter f +rotate based on position of letter a +rotate based on position of letter b +swap letter g with letter e +rotate right 4 steps +rotate based on position of letter h +reverse positions 3 through 5 +swap letter h with letter e +swap letter g with letter a +rotate based on position of letter c +reverse positions 0 through 4 +rotate based on position of letter e +reverse positions 4 through 7 +rotate left 4 steps +swap position 0 with position 6 +reverse positions 1 through 6 +rotate left 2 steps +swap position 5 with position 3 +swap letter b with letter d +swap letter b with letter d +rotate based on position of letter d +rotate based on position of letter c +rotate based on position of letter h +move position 4 to position 7 diff --git a/inputs/input21_test b/inputs/input21_test new file mode 100644 index 0000000..2ffba37 --- /dev/null +++ b/inputs/input21_test @@ -0,0 +1,8 @@ +swap position 4 with position 0 +swap letter d with letter b +reverse positions 0 through 4 +rotate left 1 step +move position 1 to position 4 +move position 3 to position 0 +rotate based on position of letter b +rotate based on position of letter d \ No newline at end of file