From a4f9db4828856a4e84b5338340f6c3b42bdc0d72 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Thu, 26 Dec 2024 22:52:47 -0500 Subject: [PATCH] 2019: d22: ex1: add solution --- 2019/d22/ex1/ex1.py | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 2019/d22/ex1/ex1.py diff --git a/2019/d22/ex1/ex1.py b/2019/d22/ex1/ex1.py new file mode 100755 index 0000000..fd7fbc1 --- /dev/null +++ b/2019/d22/ex1/ex1.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import dataclasses +import enum +import sys + + +class Technique(enum.Enum): + DEAL_NEW = enum.auto() + CUT = enum.auto() + DEAL_INCR = enum.auto() + + +@dataclasses.dataclass +class Instruction: + tech: Technique + n: int + + def to_linear(self) -> tuple[int, int]: + if self.tech == Technique.DEAL_NEW: + return (-1, -1) + if self.tech == Technique.CUT: + return (1, -self.n) + if self.tech == Technique.DEAL_INCR: + return (self.n, 0) + assert False # Sanity check + + def apply(self, card_pos: int, deck_size: int) -> int: + a, b = self.to_linear() + return (card_pos * a + b) % deck_size + + +def solve(input: str) -> int: + def parse_instruction(input: str) -> Instruction: + if input == "deal into new stack": + return Instruction(Technique.DEAL_NEW, 0) + n = int(input.split()[-1]) + if input.startswith("cut"): + return Instruction(Technique.CUT, n) + if input.startswith("deal with increment"): + return Instruction(Technique.DEAL_INCR, n) + assert False # Sanity check + + def parse(input: list[str]) -> list[Instruction]: + return [parse_instruction(line) for line in input] + + def find_final_pos( + card_pos: int, deck_size: int, instructions: list[Instruction] + ) -> int: + for instr in instructions: + card_pos = instr.apply(card_pos, deck_size) + return card_pos + + instructions = parse(input.splitlines()) + return find_final_pos(2019, 10007, instructions) + + +def main() -> None: + input = sys.stdin.read() + print(solve(input)) + + +if __name__ == "__main__": + main()