@@ -5,8 +5,23 @@ use aoc::graph::BFS;
5
5
use aoc:: grid:: Cell ;
6
6
use aoc:: Puzzle ;
7
7
use itertools:: Itertools ;
8
+ use lazy_static:: lazy_static;
8
9
use std:: collections:: { HashMap , HashSet } ;
9
10
11
+ lazy_static ! {
12
+ static ref CORNER_DIRS : [ [ Direction ; 3 ] ; 4 ] = [
13
+ [ Direction :: LeftAndUp , Direction :: Left , Direction :: Up ] ,
14
+ [ Direction :: RightAndUp , Direction :: Right , Direction :: Up ] ,
15
+ [ Direction :: RightAndDown , Direction :: Right , Direction :: Down ] ,
16
+ [ Direction :: LeftAndDown , Direction :: Left , Direction :: Down ] ,
17
+ ] ;
18
+ static ref MATCHES : [ [ bool ; 3 ] ; 3 ] = [
19
+ [ false , false , false ] ,
20
+ [ true , false , false ] ,
21
+ [ false , true , true ] ,
22
+ ] ;
23
+ }
24
+
10
25
#[ derive( Clone , Debug ) ]
11
26
struct Regions {
12
27
plots_by_plant : HashMap < char , HashSet < Cell > > ,
@@ -84,13 +99,41 @@ impl<'a> Iterator for RegionIterator<'a> {
84
99
}
85
100
}
86
101
102
+ enum Pricing {
103
+ Perimeter ,
104
+ NumberOfSides ,
105
+ }
106
+
107
+ impl Pricing {
108
+ fn calculate ( & self , plot : & Cell , region : & HashSet < Cell > ) -> usize {
109
+ match self {
110
+ Pricing :: Perimeter => {
111
+ 4 - plot
112
+ . capital_neighbours ( )
113
+ . iter ( )
114
+ . filter ( |n| region. contains ( n) )
115
+ . count ( )
116
+ }
117
+ Pricing :: NumberOfSides => CORNER_DIRS
118
+ . iter ( )
119
+ . filter ( |d| {
120
+ let test = ( 0 ..3 )
121
+ . map ( |i| {
122
+ plot. try_at ( d[ i] )
123
+ . is_some_and ( |n| region. contains ( & n) )
124
+ } )
125
+ . collect :: < Vec < bool > > ( ) ;
126
+ MATCHES . iter ( ) . any ( |m| * m == * test)
127
+ } )
128
+ . count ( ) ,
129
+ }
130
+ }
131
+ }
132
+
87
133
struct AoC2024_12 ;
88
134
89
135
impl AoC2024_12 {
90
- fn solve < F > ( & self , input : & [ String ] , count : F ) -> usize
91
- where
92
- F : Fn ( & Cell , & HashSet < Cell > ) -> usize ,
93
- {
136
+ fn solve ( & self , input : & [ String ] , pricing : Pricing ) -> usize {
94
137
let regions: Regions = ( 0 ..input. len ( ) )
95
138
. cartesian_product ( 0 ..input[ 0 ] . len ( ) )
96
139
. map ( |( r, c) | ( input[ r] . chars ( ) . nth ( c) . unwrap ( ) , Cell :: at ( r, c) ) )
@@ -99,7 +142,7 @@ impl AoC2024_12 {
99
142
. iter ( )
100
143
. map ( |r| {
101
144
r. iter ( )
102
- . map ( |plot| count ( plot, & r) * r. len ( ) )
145
+ . map ( |plot| pricing . calculate ( plot, & r) * r. len ( ) )
103
146
. sum :: < usize > ( )
104
147
} )
105
148
. sum ( )
@@ -118,43 +161,11 @@ impl aoc::Puzzle for AoC2024_12 {
118
161
}
119
162
120
163
fn part_1 ( & self , input : & Self :: Input ) -> Self :: Output1 {
121
- let count_edges = |plot : & Cell , region : & HashSet < Cell > | {
122
- 4 - plot
123
- . capital_neighbours ( )
124
- . iter ( )
125
- . filter ( |n| region. contains ( n) )
126
- . count ( )
127
- } ;
128
- self . solve ( input, count_edges)
164
+ self . solve ( input, Pricing :: Perimeter )
129
165
}
130
166
131
167
fn part_2 ( & self , input : & Self :: Input ) -> Self :: Output2 {
132
- let corner_dirs = [
133
- [ Direction :: LeftAndUp , Direction :: Left , Direction :: Up ] ,
134
- [ Direction :: RightAndUp , Direction :: Right , Direction :: Up ] ,
135
- [ Direction :: RightAndDown , Direction :: Right , Direction :: Down ] ,
136
- [ Direction :: LeftAndDown , Direction :: Left , Direction :: Down ] ,
137
- ] ;
138
- let matches = [
139
- [ false , false , false ] ,
140
- [ true , false , false ] ,
141
- [ false , true , true ] ,
142
- ] ;
143
- let count_corners = |plot : & Cell , region : & HashSet < Cell > | {
144
- corner_dirs
145
- . iter ( )
146
- . filter ( |d| {
147
- let test = ( 0 ..3 )
148
- . map ( |i| match plot. try_at ( d[ i] ) {
149
- Some ( n) => region. contains ( & n) ,
150
- None => false ,
151
- } )
152
- . collect :: < Vec < bool > > ( ) ;
153
- matches. iter ( ) . any ( |m| * m == * test)
154
- } )
155
- . count ( )
156
- } ;
157
- self . solve ( input, count_corners)
168
+ self . solve ( input, Pricing :: NumberOfSides )
158
169
}
159
170
160
171
fn samples ( & self ) {
0 commit comments