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

54 statements  

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

1from typing import List 

2 

3from src.aoc2022.utils import get_raw_data 

4 

5 

6def item_priority(char: str) -> int: 

7 """Get the priority value for a character 

8 

9 :param char: the character to convert to a priority value 

10 :type char: str 

11 

12 :return: Priority value 

13 :rtype: int 

14 """ 

15 if char.isupper(): 

16 return (ord(char) - 65) + 27 

17 else: 

18 return (ord(char) - 97) + 1 

19 

20 

21def parse_data_to_array(raw_data: str) -> List[List[int]]: 

22 """ 

23 Parses the raw text input into lists of priority values 

24 

25 :param raw_data: Raw text data to be parsed 

26 :type raw_data: str 

27 

28 :return: Parsed list of lists values 

29 :rtype: List[List[int]] 

30 """ 

31 lines = raw_data.replace(" ", "").strip().split("\n") 

32 

33 parsed_data = [] 

34 for line in lines: 

35 priority_values = [item_priority(c) for c in line] 

36 

37 parsed_data.append(priority_values) 

38 

39 return parsed_data 

40 

41 

42def get_shared_element(left_list: List[int], right_list: List[int]) -> int: 

43 """ 

44 Get the shared element between the two lists 

45 

46 :param left_list: left list of items 

47 :type left_list: List[int] 

48 

49 :param right_list: right list of items 

50 :type right_list: List[int] 

51 

52 :return: shared element between lists 

53 :rtype: int 

54 """ 

55 left_list = sorted(left_list) 

56 right_list = sorted(right_list) 

57 

58 idx = 0 

59 idy = 0 

60 

61 while left_list[idx] != right_list[idy]: 

62 if left_list[idx] < right_list[idy]: 

63 idx += 1 

64 elif left_list[idx] > right_list[idy]: 

65 idy += 1 

66 

67 return left_list[idx] 

68 

69 

70def count_total_priority(items: List[List[int]]) -> int: 

71 """ 

72 Count the total priority for the 2 compartment case 

73 

74 :param items: list of all backpack contents 

75 :type items: List[List[int]] 

76 

77 :return: total sum of priority for the shared items 

78 :rtype: int 

79 """ 

80 sum_ = 0 

81 for priorities in items: 

82 

83 n = len(priorities) // 2 

84 

85 left_list = priorities[:n] 

86 right_list = priorities[n:] 

87 sum_ += get_shared_element(left_list, right_list) 

88 return sum_ 

89 

90 

91def get_triplet_shared_element( 

92 left_list: List[int], middle_list: List[int], right_list: List[int] 

93) -> int: 

94 """ 

95 Get the shared element between the three lists 

96 

97 :param left_list: left list of items 

98 :type left_list: List[int] 

99 

100 :param middle_list: left list of items 

101 :type middle_list: List[int] 

102 

103 :param right_list: right list of items 

104 :type right_list: List[int] 

105 

106 :return: shared element between lists 

107 :rtype: int 

108 """ 

109 l_list = sorted(left_list) 

110 m_list = sorted(middle_list) 

111 r_list = sorted(right_list) 

112 

113 idx = 0 

114 idy = 0 

115 idz = 0 

116 

117 while not (l_list[idx] == m_list[idy] == r_list[idz]): 

118 if (l_list[idx] <= m_list[idy]) and (l_list[idx] <= r_list[idz]): 

119 idx += 1 

120 elif (m_list[idy] <= l_list[idx]) and (m_list[idy] <= r_list[idz]): 

121 idy += 1 

122 else: 

123 idz += 1 

124 

125 return l_list[idx] 

126 

127 

128def count_triplet_priority(items: List[List[int]]) -> int: 

129 """ 

130 Count the total priority for the 3 compartment case 

131 

132 :param items: list of all backpack contents 

133 :type items: List[List[int]] 

134 

135 :return: total sum of priority for the shared items 

136 :rtype: int 

137 """ 

138 

139 sum_ = 0 

140 for i in range(0, len(items), 3): 

141 left_list = items[i] 

142 middle_list = items[i + 1] 

143 right_list = items[i + 2] 

144 sum_ += get_triplet_shared_element(left_list, middle_list, right_list) 

145 return sum_ 

146 

147 

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

149 data = get_raw_data("./src/aoc2022/data/day3.txt") 

150 parsed_data = parse_data_to_array(data) 

151 

152 total_priority = count_total_priority(parsed_data) 

153 print(f"The incorrect items add up to {total_priority} priority.") 

154 

155 total_priority = count_triplet_priority(parsed_data) 

156 print(f"The badges add up to {total_priority} priority.")