1
0
aoc-2020/22/main.py
2022-05-22 13:23:01 +00:00

69 lines
2.2 KiB
Python

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))