From bbcc9e1bb30e4775f1344ffb97b15aeecbcd41b2 Mon Sep 17 00:00:00 2001 From: kamoshi <18511281+kamoshi@users.noreply.github.com> Date: Tue, 22 Dec 2020 15:54:07 +0100 Subject: [PATCH] Update day22.py --- 2020/Python/day22.py | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/2020/Python/day22.py b/2020/Python/day22.py index 08443fd..32d47a4 100644 --- a/2020/Python/day22.py +++ b/2020/Python/day22.py @@ -39,3 +39,61 @@ def solve_p1(player1: list[int], player2: list[int]) -> int: PLAYER1, PLAYER2 = parse_data() print(solve_p1(PLAYER1, PLAYER2)) + + +def play_game(cache: dict[str, int], player1: list[int], player2: list[int]) -> (int, list[int]): + previous_rounds: set[str] = set() + stack1, stack2 = list(reversed(player1)), list(reversed(player2)) + + def round_snapshot() -> str: + return f"{stack1}|{stack2}" + + def normal_round() -> None: + _number1, _number2 = stack1.pop(), stack2.pop() + if _number1 > _number2: + stack1.insert(0, _number1) + stack1.insert(0, _number2) + else: + stack2.insert(0, _number2) + stack2.insert(0, _number1) + + while len(stack1) > 0 and len(stack2) > 0: + if (snapshot := round_snapshot()) in previous_rounds: + return 1, stack1 + else: + previous_rounds.add(snapshot) + + if len(stack1) > stack1[len(stack1)-1] and len(stack2) > stack2[len(stack2)-1]: + number1, number2 = stack1.pop(), stack2.pop() + sub_deck1, sub_deck2 = stack1[1-number1:], stack2[1-number2:] + + # Check cache for winner + if (sub_snapshot := f"{sub_deck1}|{sub_deck2}") not in cache: + winner, _ = play_game(cache, sub_deck1, sub_deck2) + cache[sub_snapshot] = winner + else: + winner = cache[sub_snapshot] + + if winner == 1: + stack1.insert(0, number1) + stack1.insert(0, number2) + else: + stack2.insert(0, number2) + stack2.insert(0, number1) + else: + normal_round() + + if len(stack1) > 0: + return 1, stack1 + else: + return 2, stack2 + + +# PART 2 is Broken for now +def solve_p2(player1: list[int], player2: list[int]) -> int: + cache: dict[str, int] = {} + winner, winning = play_game(cache, player1, player2) + return sum(x*y for (x, y) in (zip(winning, [x for x in range(1, len(winning)+1)]))) + + +print(solve_p2(PLAYER1, PLAYER2))