-
Notifications
You must be signed in to change notification settings - Fork 0
/
day2.py
100 lines (75 loc) Β· 3.42 KB
/
day2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import types
from aocd import get_data
from dataclasses import dataclass, field
from parse import parse
from enum import Enum
class Result(Enum):
Win = 6
Loss = 0
Tie = 3
class PlayerAction(Enum):
Rock = 1
Paper = 2
Scissors = 3
@dataclass
class Score:
Player1Points: int
Player2Points: int
@dataclass
class Game:
Player1: list[Score] = field(default_factory=list)
Player2: list[Score] = field(default_factory=list)
@dataclass
class Round:
Player1Action: str
Player2Action: str
def parse_round(input_line: str) -> Round:
player1, player2 = parse('{} {}', input_line)
return Round(player1, player2)
def player_action(input_round: Round) -> (PlayerAction, PlayerAction):
actions = {'A': PlayerAction.Rock, 'X': PlayerAction.Rock, 'B': PlayerAction.Paper, 'Y': PlayerAction.Paper, 'C': PlayerAction.Scissors, 'Z': PlayerAction.Scissors}
return actions[input_round.Player1Action], actions[input_round.Player2Action]
def player_result(result_round: Round) -> (PlayerAction, PlayerAction):
player1_action = {'A': PlayerAction.Rock, 'B': PlayerAction.Paper, 'C': PlayerAction.Scissors}.get(result_round.Player1Action)
player2_result = {'X': Result.Loss, 'Y': Result.Tie, 'Z': Result.Win}.get(result_round.Player2Action)
player2_action = {
Result.Tie: player1_action,
Result.Win: {
PlayerAction.Rock: PlayerAction.Paper,
PlayerAction.Paper: PlayerAction.Scissors,
PlayerAction.Scissors: PlayerAction.Rock
}.get(player1_action),
Result.Loss: {
PlayerAction.Rock: PlayerAction.Scissors,
PlayerAction.Paper: PlayerAction.Rock,
PlayerAction.Scissors: PlayerAction.Paper
}.get(player1_action)
}.get(player2_result)
return player1_action, player2_action
def play_round_part(player1_action: PlayerAction, player2_action: PlayerAction) -> Score:
if player1_action == player2_action:
return Score(player1_action.value + Result.Tie.value, player2_action.value + Result.Tie.value)
if player1_action == PlayerAction.Rock and player2_action == PlayerAction.Scissors:
return Score(player1_action.value + Result.Win.value, player2_action.value)
if player1_action == PlayerAction.Scissors and player2_action == PlayerAction.Paper:
return Score(player1_action.value + Result.Win.value, player2_action.value)
if player1_action == PlayerAction.Paper and player2_action == PlayerAction.Rock:
return Score(player1_action.value + Result.Win.value, player2_action.value)
else:
return Score(player1_action.value, player2_action.value + Result.Win.value)
def play_game(rounds: list[Round], run_round_fn: types.FunctionType) -> Game:
round_scores = Game()
for current_round in rounds:
player1, player2 = run_round_fn(current_round)
completed_round = play_round_part(player1, player2)
round_scores.Player1.append(completed_round.Player1Points)
round_scores.Player2.append(completed_round.Player2Points)
return round_scores
if __name__ == '__main__':
data = ['A Y', 'B X', 'C Z']
data = get_data(day=2, year=2022).splitlines()
parsed_rounds = [parse_round(input_line) for input_line in data]
part1_game = play_game(parsed_rounds, player_action)
print(f'Part 1: {sum(part1_game.Player2)}')
part2_game = play_game(parsed_rounds, player_result)
print(f'Part 2: {sum(part2_game.Player2)}')