diff --git a/22/input.txt b/22/input.txt new file mode 100644 index 0000000..f688022 --- /dev/null +++ b/22/input.txt @@ -0,0 +1,53 @@ +Player 1: +18 +19 +16 +11 +47 +38 +6 +27 +9 +22 +15 +42 +3 +4 +21 +41 +14 +8 +23 +30 +40 +13 +35 +46 +50 + +Player 2: +39 +1 +29 +20 +45 +43 +12 +2 +37 +33 +49 +32 +10 +26 +36 +17 +34 +44 +25 +28 +24 +5 +48 +31 +7 diff --git a/22/main.py b/22/main.py new file mode 100644 index 0000000..fc39548 --- /dev/null +++ b/22/main.py @@ -0,0 +1,68 @@ + + +def read_input(filename: str) -> tuple[list[int], list[int]]: + with open(filename, "r") as f: + player1, player2 = f.read().split("\n\n") + player1_cards = list(int(l) for l in player1.splitlines()[1:]) + player2_cards = list(int(l) for l in player2.splitlines()[1:]) + return (player1_cards, player2_cards) + +def play_combat(player1: list[int], player2: list[int]) -> list[int]: + while len(player1) > 0 and len(player2) > 0: + card1 = player1.pop(0) + card2 = player2.pop(0) + if card1 > card2: + player1.append(card1) + player1.append(card2) + else: + player2.append(card2) + player2.append(card1) + + return max(player1, player2) + +def play_recursive_combat(player1: list[int], player2: list[int]) -> tuple[list[int], bool]: + seen_games = set() + + while len(player1) > 0 and len(player2) > 0: + seen_game_value = (",".join(map(str, player1)), ",".join(map(str, player2))) + if seen_game_value in seen_games: + return player1, True + + seen_games.add(seen_game_value) + + card1 = player1.pop(0) + card2 = player2.pop(0) + + player1_won = None + if len(player1) >= card1 and len(player2) >= card2: + _, player1_won = play_recursive_combat(player1[:card1], player2[:card2]) + else: + player1_won = card1 > card2 + + if player1_won: + player1.append(card1) + player1.append(card2) + else: + player2.append(card2) + player2.append(card1) + + return max(player1, player2), len(player2) == 0 + +def calculate_score(cards: list[int]) -> int: + score = 0 + for i in range(len(cards)): + score += cards[i] * (len(cards)-i) + return score + +def part1(player1: list[int], player2: list[int]) -> int: + winning_cards = play_combat(player1.copy(), player2.copy()) + return calculate_score(winning_cards) + +def part2(player1: list[int], player2: list[int]) -> int: + winning_cards, _ = play_recursive_combat(player1.copy(), player2.copy()) + return calculate_score(winning_cards) + +if __name__ == "__main__": + player1, player2 = read_input("input.txt") + print("part1: ", part1(player1, player2)) + print("part2: ", part2(player1, player2)) diff --git a/22/test.txt b/22/test.txt new file mode 100644 index 0000000..391cd24 --- /dev/null +++ b/22/test.txt @@ -0,0 +1,13 @@ +Player 1: +9 +2 +6 +3 +1 + +Player 2: +5 +8 +4 +7 +10