5
5
6
6
import sys
7
7
from collections import defaultdict
8
- from typing import Callable
8
+ from enum import Enum
9
+ from enum import auto
10
+ from enum import unique
9
11
from typing import Iterator
10
12
11
13
from aoc .common import InputData
68
70
"""
69
71
70
72
73
+ @unique
74
+ class Pricing (Enum ):
75
+ PERIMETER = auto ()
76
+ NUMBER_OF_SIDES = auto ()
77
+
78
+ def calculate (self , plot : Cell , region : set [Cell ]) -> int :
79
+ match self :
80
+ case Pricing .PERIMETER :
81
+ return 4 - sum (
82
+ n in region for n in plot .get_capital_neighbours ()
83
+ )
84
+ case Pricing .NUMBER_OF_SIDES :
85
+ return sum (
86
+ tuple (
87
+ 1 if plot .at (d [i ]) in region else 0 for i in range (3 )
88
+ )
89
+ in ((0 , 0 , 0 ), (1 , 0 , 0 ), (0 , 1 , 1 ))
90
+ for d in CORNER_DIRS
91
+ )
92
+
93
+
71
94
class Solution (SolutionBase [Input , Output1 , Output2 ]):
72
95
def parse_input (self , input_data : InputData ) -> Input :
73
96
return input_data
74
97
75
- def solve (
76
- self , input : Input , count : Callable [[Cell , set [Cell ]], int ]
77
- ) -> int :
98
+ def solve (self , input : Input , pricing : Pricing ) -> int :
78
99
def get_regions (input : Input ) -> Iterator [set [Cell ]]:
79
100
plots_by_plant = defaultdict [str , set [Cell ]](set )
80
101
for r , row in enumerate (input ):
@@ -94,25 +115,16 @@ def get_regions(input: Input) -> Iterator[set[Cell]]:
94
115
all_plots_with_plant -= region
95
116
96
117
return sum (
97
- sum (count (plot , region ) for plot in region ) * len (region )
118
+ sum (pricing .calculate (plot , region ) for plot in region )
119
+ * len (region )
98
120
for region in get_regions (input )
99
121
)
100
122
101
123
def part_1 (self , input : Input ) -> Output1 :
102
- def count_edges (plot : Cell , region : set [Cell ]) -> int :
103
- return 4 - sum (n in region for n in plot .get_capital_neighbours ())
104
-
105
- return self .solve (input , count_edges )
124
+ return self .solve (input , Pricing .PERIMETER )
106
125
107
126
def part_2 (self , input : Input ) -> Output2 :
108
- def count_corners (plot : Cell , region : set [Cell ]) -> int :
109
- return sum (
110
- tuple (1 if plot .at (d [i ]) in region else 0 for i in range (3 ))
111
- in ((0 , 0 , 0 ), (1 , 0 , 0 ), (0 , 1 , 1 ))
112
- for d in CORNER_DIRS
113
- )
114
-
115
- return self .solve (input , count_corners )
127
+ return self .solve (input , Pricing .NUMBER_OF_SIDES )
116
128
117
129
@aoc_samples (
118
130
(
0 commit comments