Passed
Push — main ( 950843...c77b04 )
by Yohann
57s
created

main.main()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nop 0
1
from __future__ import annotations
2
3
import pathlib
4
from enum import IntEnum
5
from typing import Tuple, List, Dict
6
7
WIN_SCORE = 6
8
DRAW_SCORE = 3
9
10
11
class PlayMove(IntEnum):
12
    ROCK = 1
13
    PAPER = 2
14
    SCISSORS = 3
15
16
    @property
17
    def win(self) -> PlayMove:
18
        return PlayMove((self + 1) % 4 or 1)
19
20
    @property
21
    def lose(self) -> PlayMove:
22
        return PlayMove((self - 1) or 3)
23
24
25
class Target(IntEnum):
26
    LOSE = 1
27
    DRAW = 2
28
    WIN = 3
29
30
    def score_from_enemy(self, enemy: PlayMove) -> int:
31
        if self == Target.LOSE:
32
            return enemy.lose
33
34
        return (
35
            enemy.win + WIN_SCORE
36
            if self == Target.WIN
37
            else enemy + DRAW_SCORE
38
        )
39
40
41
TRANSLATION_MAP: Dict[str, PlayMove] = {
42
    'A': PlayMove.ROCK,
43
    'B': PlayMove.PAPER,
44
    'C': PlayMove.SCISSORS,
45
46
    'X': PlayMove.ROCK,
47
    'Y': PlayMove.PAPER,
48
    'Z': PlayMove.SCISSORS,
49
}
50
51
52
def get_part_one_score(moves: List[Tuple[PlayMove, ...]]) -> int:
53
    return sum(
54
        (
55
            my_move
56
            + (enemy_move.win == my_move) * WIN_SCORE
57
            + (my_move == enemy_move) * DRAW_SCORE
58
        ) for enemy_move, my_move in moves
59
    )
60
61
62
def get_part_two_score(moves: List[Tuple[PlayMove, ...]]) -> int:
63
    return sum(
64
        Target(target).score_from_enemy(enemy_move)
65
        for enemy_move, target in moves
66
    )
67
68
69
def main():
70
    content = pathlib.Path('./input.txt').read_text()
71
72
    moves: List[Tuple[PlayMove, ...]] = [
73
        tuple(map(TRANSLATION_MAP.get, line.split()))
74
        for line in content.splitlines()
75
    ]
76
77
    print("Part 1:", get_part_one_score(moves))
78
    print("Part 2:", get_part_two_score(moves))
79
80
81
if __name__ == '__main__':
82
    main()
83