50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
![]() |
# SPDX-License-Identifier: MIT
|
||
|
# Copyright (c) 2021 Akumatic
|
||
|
#
|
||
|
# https://adventofcode.com/2021/day/21
|
||
|
|
||
|
def read_file(filename: str = "input.txt") -> tuple:
|
||
|
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
|
||
|
return [int(line[28:]) for line in f.read().strip().split("\n")]
|
||
|
|
||
|
def game_deterministic(positions: list) -> tuple:
|
||
|
pos = positions[:]
|
||
|
player, rolls, die = 0, 0, 0
|
||
|
scores = [0, 0]
|
||
|
while max(scores) < 1000:
|
||
|
for _ in range(3):
|
||
|
die = (die + 1) % 100 or 100
|
||
|
rolls += 1
|
||
|
pos[player] = (pos[player] + die) % 10 or 10
|
||
|
scores[player] += pos[player]
|
||
|
player = (player + 1) % 2
|
||
|
return rolls, scores
|
||
|
|
||
|
def game_dirac(move_frequency: dict, wins: list, positions: list,
|
||
|
scores: list = [0, 0], player: int = 0, win_mult: int = 1) -> None:
|
||
|
next_player = (player + 1) % 2
|
||
|
for moves in move_frequency:
|
||
|
pos, scr = positions[:], scores[:]
|
||
|
pos[player] = (pos[player] + moves) % 10 or 10
|
||
|
scr[player] += pos[player]
|
||
|
next_mult = move_frequency[moves] * win_mult
|
||
|
if scr[player] < 21:
|
||
|
game_dirac(move_frequency, wins, pos, scr, next_player, next_mult)
|
||
|
else:
|
||
|
wins[player] += next_mult
|
||
|
|
||
|
def part1(start_positions: list) -> int:
|
||
|
rolls, scores = game_deterministic(start_positions)
|
||
|
return rolls * min(scores)
|
||
|
|
||
|
def part2(start_positions: list) -> int:
|
||
|
move_frequency = {3: 1, 4: 3, 5: 6, 6: 7, 7: 6, 8: 3, 9: 1}
|
||
|
wins = [0, 0]
|
||
|
game_dirac(move_frequency, wins, start_positions)
|
||
|
return max(wins)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
vals = read_file()
|
||
|
print(f"Part 1: {part1(vals)}")
|
||
|
print(f"Part 2: {part2(vals)}")
|
||
|
|