Coverage for src\aoc2022\days\day2.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.0.0, created at 2022-12-23 05:19 +0000

1from enum import Enum 

2from typing import Dict, List, Tuple, Union 

3 

4from src.aoc2022.utils import get_raw_data 

5 

6 

7class Move(Enum): 

8 """ 

9 Enum for valid Rock-Paper-Scissors game 

10 """ 

11 

12 ROCK = 1 

13 """ 

14 Value for 'Rock' move. 

15 """ 

16 PAPER = 2 

17 """ 

18 Value for 'Paper' move. 

19 """ 

20 SCISSORS = 3 

21 """ 

22 Value for 'Scissors' move. 

23 """ 

24 

25 

26class Strategy(Enum): 

27 """ 

28 Enum for valid strategies 

29 """ 

30 

31 LOSE = 1 

32 """ 

33 Value for 'Lose' strategy. 

34 """ 

35 DRAW = 2 

36 """ 

37 Value for 'Draw' strategy. 

38 """ 

39 WIN = 3 

40 """ 

41 Value for 'Win' strategy. 

42 """ 

43 

44 

45union_dict_type = Union[Dict[str, Move], Dict[str, Strategy]] 

46 

47 

48def parse_data( 

49 raw_data: str, 

50 l_mapping: Dict[str, Move], 

51 r_mapping: union_dict_type, 

52) -> List[Tuple[int, int]]: 

53 """ 

54 Parses the raw text input into lists of tuples of (Enum, Enum) 

55 

56 :param raw_data: Raw text data to be parsed 

57 :type raw_data: str 

58 

59 :param l_mapping: Mapping to convert string to enum value 

60 :type l_mapping: 

61 

62 :param r_mapping: Mapping to convert string to enum value 

63 :type r_mapping: 

64 

65 :return: List of parsed tuples 

66 :rtype: List[Tuple[Enum, Enum]] 

67 """ 

68 raw_data = raw_data.strip() 

69 rows = raw_data.split("\n") 

70 values = [row.strip().split(" ") for row in rows] 

71 

72 parsed_data = [] 

73 for left_token, right_token in values: 

74 l_val = l_mapping[left_token].value 

75 r_val = r_mapping[right_token].value 

76 parsed_row = (l_val, r_val) 

77 parsed_data.append(parsed_row) 

78 

79 return parsed_data 

80 

81 

82def calculate_points( 

83 rounds: List[Tuple[int, int]], 

84 pts_mapping: Dict[Tuple[int, int], int], 

85) -> int: 

86 """ 

87 Calculates the number of points given a list of rounds and a point mapping 

88 

89 :param rounds: List of tuples for each round 

90 :type rounds: List[Tuple[Enum, Enum]] 

91 

92 :param pts_mapping: Mapping to convert a round to a point count 

93 :type pts_mapping: Dict[str, Enum] 

94 

95 :return: Total score across all rounds 

96 :rtype: int 

97 """ 

98 values: List[int] = [int(pts_mapping[round_]) for round_ in rounds] 

99 return sum(values) 

100 

101 

102if __name__ == "__main__": # pragma: no cover 

103 move_mapping: Dict[str, Move] = { 

104 "A": Move.ROCK, 

105 "B": Move.PAPER, 

106 "C": Move.SCISSORS, 

107 "X": Move.ROCK, 

108 "Y": Move.PAPER, 

109 "Z": Move.SCISSORS, 

110 } 

111 

112 strategy_mapping: Dict[str, Strategy] = { 

113 "X": Strategy.LOSE, 

114 "Y": Strategy.DRAW, 

115 "Z": Strategy.WIN, 

116 } 

117 

118 LOSE_PTS = 0 

119 DRAW_PTS = 3 

120 WIN_PTS = 6 

121 

122 ROCK_PTS = 1 

123 PAPER_PTS = 2 

124 SCISSORS_PTS = 3 

125 

126 point_mappings_part_1: Dict[Tuple[int, int], int] = { 

127 (Move.ROCK.value, Move.ROCK.value): ROCK_PTS + DRAW_PTS, 

128 (Move.PAPER.value, Move.ROCK.value): ROCK_PTS + LOSE_PTS, 

129 (Move.SCISSORS.value, Move.ROCK.value): ROCK_PTS + WIN_PTS, 

130 (Move.ROCK.value, Move.PAPER.value): PAPER_PTS + WIN_PTS, 

131 (Move.PAPER.value, Move.PAPER.value): PAPER_PTS + DRAW_PTS, 

132 (Move.SCISSORS.value, Move.PAPER.value): PAPER_PTS + LOSE_PTS, 

133 (Move.ROCK.value, Move.SCISSORS.value): SCISSORS_PTS + LOSE_PTS, 

134 (Move.PAPER.value, Move.SCISSORS.value): SCISSORS_PTS + WIN_PTS, 

135 (Move.SCISSORS.value, Move.SCISSORS.value): SCISSORS_PTS + DRAW_PTS, 

136 } 

137 

138 point_mappings_part_2: Dict[Tuple[int, int], int] = { 

139 (Move.ROCK.value, Strategy.LOSE.value): SCISSORS_PTS + LOSE_PTS, 

140 (Move.PAPER.value, Strategy.LOSE.value): ROCK_PTS + LOSE_PTS, 

141 (Move.SCISSORS.value, Strategy.LOSE.value): PAPER_PTS + LOSE_PTS, 

142 (Move.ROCK.value, Strategy.DRAW.value): ROCK_PTS + DRAW_PTS, 

143 (Move.PAPER.value, Strategy.DRAW.value): PAPER_PTS + DRAW_PTS, 

144 (Move.SCISSORS.value, Strategy.DRAW.value): SCISSORS_PTS + DRAW_PTS, 

145 (Move.ROCK.value, Strategy.WIN.value): PAPER_PTS + WIN_PTS, 

146 (Move.PAPER.value, Strategy.WIN.value): SCISSORS_PTS + WIN_PTS, 

147 (Move.SCISSORS.value, Strategy.WIN.value): ROCK_PTS + WIN_PTS, 

148 } 

149 

150 raw_data = get_raw_data(file_path="./src/aoc2022/data/day2.txt") 

151 

152 parsed_data = parse_data(raw_data, move_mapping, move_mapping) 

153 total_points = calculate_points(parsed_data, point_mappings_part_1) 

154 

155 print(f"You got {total_points} using the naive strategy.") 

156 

157 parsed_data = parse_data(raw_data, move_mapping, strategy_mapping) 

158 total_points = calculate_points(parsed_data, point_mappings_part_2) 

159 

160 print(f"You got {total_points} using the correct strategy.")