-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday02.py
76 lines (57 loc) · 1.61 KB
/
day02.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
import enum
from .shared import Solution
class Outcome(enum.IntEnum):
LOSE = 0
DRAW = 3
WIN = 6
class Move(enum.IntEnum):
ROCK = 1
PAPER = 2
SCISSORS = 3
OUTCOMES = {
"X": Outcome.LOSE,
"Y": Outcome.DRAW,
"Z": Outcome.WIN,
}
MOVES = {
"A": Move.ROCK,
"B": Move.PAPER,
"C": Move.SCISSORS,
"X": Move.ROCK,
"Y": Move.PAPER,
"Z": Move.SCISSORS,
}
def main(input_: list[str]) -> Solution:
solution = Solution()
for line in input_:
moves = line.split(" ")
opponent, you = [MOVES[m] for m in moves]
solution.part1 += score(opponent, you)
you = OUTCOMES[moves[1]]
solution.part2 += score(opponent, you)
return solution
def score(opponent: Move, you: Move | Outcome) -> int:
if isinstance(you, Move):
return you + get_outcome(opponent, you)
else:
return you + get_move(opponent, you)
def get_outcome(opponent: Move, you: Move) -> int:
if opponent == you:
return Outcome.DRAW
# fmt: off
match (opponent, you):
case (Move.ROCK, Move.PAPER) \
| (Move.PAPER, Move.SCISSORS) \
| (Move.SCISSORS, Move.ROCK):
return Outcome.WIN
case _:
return Outcome.LOSE
# fmt: on
def get_move(opponent: Move, outcome: Outcome) -> int:
if outcome == Outcome.DRAW:
return opponent
shift = opponent - 1
if outcome == Outcome.WIN:
return ((shift + 1) % 3) + 1
if outcome == Outcome.LOSE:
return ((shift - 1) % 3) + 1