summaryrefslogtreecommitdiffstats
path: root/day2/__init__.py
blob: 19faab956db25d21d8e221374baffc85042d9f98 (plain)
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
# -*- coding: utf-8 -*-
from abc import ABC
from enum import Enum
from typing import Iterator

from aoc import BaseAssignment


class TheirMove(Enum):
    Rock = "A"
    Paper = "B"
    Scissors = "C"


class YourMove(Enum):
    Rock = "X"
    Paper = "Y"
    Scissors = "Z"


class GameOutcome(Enum):
    Lose = "X"
    Draw = "Y"
    Win = "Z"


class Assignment(BaseAssignment, ABC):
    def calculate_score(self, opponent: TheirMove, you: YourMove) -> int:
        game_result_score = {
            TheirMove.Rock: {
                YourMove.Rock: 3,
                YourMove.Paper: 6,
                YourMove.Scissors: 0,
            },
            TheirMove.Paper: {
                YourMove.Rock: 0,
                YourMove.Paper: 3,
                YourMove.Scissors: 6,
            },
            TheirMove.Scissors: {
                YourMove.Rock: 6,
                YourMove.Paper: 0,
                YourMove.Scissors: 3,
            },
        }

        you_thrown_score = {
            YourMove.Rock: 1,
            YourMove.Paper: 2,
            YourMove.Scissors: 3,
        }

        return game_result_score[opponent][you] + you_thrown_score[you]

    def play_game(self, col1: str, col2: str) -> int:
        raise NotImplementedError()

    def run(self, input: Iterator) -> int:
        return sum([self.play_game(*game.split(" ")) for game in input])


class AssignmentOne(Assignment):
    example_result = 15

    def play_game(self, col1: str, col2: str) -> int:
        return self.calculate_score(TheirMove(col1), YourMove(col2))


class AssignmentTwo(Assignment):
    example_result = 12

    def calculate_move(
        self, opponent: TheirMove, game_outcome: GameOutcome
    ) -> YourMove:
        next_move = {
            TheirMove.Rock: {
                GameOutcome.Lose: YourMove.Scissors,
                GameOutcome.Draw: YourMove.Rock,
                GameOutcome.Win: YourMove.Paper,
            },
            TheirMove.Paper: {
                GameOutcome.Lose: YourMove.Rock,
                GameOutcome.Draw: YourMove.Paper,
                GameOutcome.Win: YourMove.Scissors,
            },
            TheirMove.Scissors: {
                GameOutcome.Lose: YourMove.Paper,
                GameOutcome.Draw: YourMove.Scissors,
                GameOutcome.Win: YourMove.Rock,
            },
        }

        return next_move[opponent][game_outcome]

    def play_game(self, col1: str, col2: str) -> int:
        return self.calculate_score(
            TheirMove(col1), self.calculate_move(TheirMove(col1), GameOutcome(col2))
        )