11use crate :: solutions:: Solution ;
22use crate :: utils:: grid:: Grid ;
33use crate :: utils:: point:: Point ;
4- use itertools:: Itertools ;
4+ use crate :: utils:: surface_range:: SurfaceRange ;
5+ use itertools:: { concat, Itertools } ;
56
67pub struct Day08 ;
78
@@ -17,37 +18,81 @@ impl Solution for Day08 {
1718 points
1819 . iter ( )
1920 . combinations ( 2 )
20- . flat_map ( |pair| self . antinodes ( * pair[ 0 ] , * pair[ 1 ] ) )
21+ . flat_map ( |pair| self . antinodes_part_one ( * pair[ 0 ] , * pair[ 1 ] , & surface_range ) )
2122 . collect :: < Vec < Point > > ( )
2223 } )
23- . filter ( |p| surface_range. contains ( * p) )
2424 . unique ( )
2525 . count ( )
2626 . to_string ( )
2727 }
2828
29- fn part_two ( & self , _input : & str ) -> String {
30- String :: from ( '0' )
29+ fn part_two ( & self , input : & str ) -> String {
30+ let grid: Grid < char > = Grid :: from ( input) ;
31+ let surface_range = grid. surface_range ( ) ;
32+
33+ grid. elements_with_points ( )
34+ . iter ( )
35+ . filter ( |( element, _) | * * element != '.' )
36+ . flat_map ( |( _, points) | {
37+ points
38+ . iter ( )
39+ . combinations ( 2 )
40+ . flat_map ( |pair| self . antinodes_part_two ( * pair[ 0 ] , * pair[ 1 ] , & surface_range) )
41+ . collect :: < Vec < Point > > ( )
42+ } )
43+ . unique ( )
44+ . count ( )
45+ . to_string ( )
3146 }
3247}
3348
3449impl Day08 {
35- fn antinodes ( & self , p1 : Point , p2 : Point ) -> Vec < Point > {
50+ fn antinodes_part_one ( & self , p1 : Point , p2 : Point , surface_range : & SurfaceRange ) -> Vec < Point > {
3651 let diff = p1 - p2;
3752
3853 vec ! [ p1 + diff, p1 - diff, p2 + diff, p2 - diff]
3954 . into_iter ( )
4055 . filter ( |p| * p != p1 && * p != p2)
56+ . filter ( |p| surface_range. contains ( * p) )
4157 . collect ( )
4258 }
59+
60+ fn antinodes_part_two ( & self , p1 : Point , p2 : Point , surface_range : & SurfaceRange ) -> Vec < Point > {
61+ let diff = p1 - p2;
62+
63+ let first = self . antipodes_in_dir ( p1, diff, surface_range) ;
64+ let second = self . antipodes_in_dir ( p2, -diff, surface_range) ;
65+
66+ let vec = concat ( vec ! [ first, second] ) ;
67+
68+ vec. into_iter ( ) . unique ( ) . collect ( )
69+ }
70+
71+ fn antipodes_in_dir (
72+ & self ,
73+ point : Point ,
74+ diff : Point ,
75+ surface_range : & SurfaceRange ,
76+ ) -> Vec < Point > {
77+ let mut vec = Vec :: new ( ) ;
78+ let mut current = point;
79+
80+ while surface_range. contains ( current) {
81+ vec. push ( current) ;
82+
83+ current = current + diff;
84+ }
85+
86+ vec
87+ }
4388}
4489
4590#[ cfg( test) ]
4691mod tests {
4792 use crate :: solutions:: year2024:: day08:: Day08 ;
4893 use crate :: solutions:: Solution ;
4994 use crate :: utils:: grid:: Grid ;
50- use itertools:: Itertools ;
95+ use itertools:: { concat , Itertools } ;
5196
5297 const EXAMPLE : & str = r#"............
5398........0...
@@ -68,7 +113,12 @@ mod tests {
68113 }
69114
70115 #[ test]
71- fn antinodes ( ) {
116+ fn part_two_example_test ( ) {
117+ assert_eq ! ( "34" , Day08 . part_two( EXAMPLE ) ) ;
118+ }
119+
120+ #[ test]
121+ fn antinodes_part_one ( ) {
72122 const GRID : & str = r#"..........
73123...#......
74124..........
@@ -85,12 +135,42 @@ mod tests {
85135
86136 let ( p1, p2) = elements. get ( & 'a' ) . unwrap ( ) . iter ( ) . collect_tuple ( ) . unwrap ( ) ;
87137
88- let mut result = Day08 . antinodes ( * p1, * p2) ;
138+ let mut result = Day08 . antinodes_part_one ( * p1, * p2, & grid . surface_range ( ) ) ;
89139 let mut expected = elements. get ( & '#' ) . unwrap ( ) . to_vec ( ) ;
90140
91141 result. sort ( ) ;
92142 expected. sort ( ) ;
93143
94144 assert_eq ! ( expected, result) ;
95145 }
146+
147+ #[ test]
148+ fn part_two_second_example ( ) {
149+ const GRID : & str = r#"T....#....
150+ ...T......
151+ .T....#...
152+ .........#
153+ ..#.......
154+ ..........
155+ ...#......
156+ ..........
157+ ....#.....
158+ .........."# ;
159+
160+ let grid: Grid < char > = Grid :: from ( GRID ) ;
161+ let elements = grid. elements_with_points ( ) ;
162+
163+ let ( p1, p2, p3) = elements. get ( & 'T' ) . unwrap ( ) . iter ( ) . collect_tuple ( ) . unwrap ( ) ;
164+
165+ let result1 = Day08 . antinodes_part_two ( * p1, * p2, & grid. surface_range ( ) ) ;
166+ let result2 = Day08 . antinodes_part_two ( * p1, * p3, & grid. surface_range ( ) ) ;
167+ let result3 = Day08 . antinodes_part_two ( * p2, * p3, & grid. surface_range ( ) ) ;
168+
169+ let result = concat ( vec ! [ result1, result2, result3] )
170+ . iter ( )
171+ . unique ( )
172+ . count ( ) ;
173+
174+ assert_eq ! ( 9 , result) ;
175+ }
96176}
0 commit comments