@@ -24,20 +24,44 @@ struct Graph {
24
24
}
25
25
26
26
impl Graph {
27
- fn find_antinodes ( & mut self ) -> usize {
27
+ fn inbounds ( & self , coord : Coord ) -> bool {
28
+ coord. 0 >= 0
29
+ && coord. 0 < self . width as isize
30
+ && coord. 1 >= 0
31
+ && coord. 1 < self . height as isize
32
+ }
33
+
34
+ fn compute_antinodes ( & self , left : Coord , right : Coord , harmonics : bool ) -> Vec < Coord > {
35
+ let mut nodes = Vec :: new ( ) ;
36
+ let mut coord = left;
37
+ let diff = ( left. 0 - right. 0 , left. 1 - right. 1 ) ;
38
+ if harmonics {
39
+ while self . inbounds ( coord) {
40
+ nodes. push ( coord) ;
41
+ coord = ( coord. 0 + diff. 0 , coord. 1 + diff. 1 ) ;
42
+ }
43
+ } else {
44
+ coord = ( coord. 0 + diff. 0 , coord. 1 + diff. 1 ) ;
45
+ if self . inbounds ( coord) {
46
+ nodes. push ( coord) ;
47
+ }
48
+ }
49
+
50
+ nodes
51
+ }
52
+
53
+ fn find_antinodes ( & mut self , harmonics : bool ) -> usize {
28
54
let mut antinodes = HashSet :: new ( ) ;
29
55
for locs in self . antennas . values ( ) {
30
56
for ( idx, & left) in locs. iter ( ) . enumerate ( ) {
31
57
for & right in locs. iter ( ) . skip ( idx + 1 ) {
32
- let nodes = compute_antinodes ( left, right) ;
58
+ let nodes = self . compute_antinodes ( left, right, harmonics) ;
59
+ for node in nodes {
60
+ antinodes. insert ( node) ;
61
+ }
62
+ let nodes = self . compute_antinodes ( right, left, harmonics) ;
33
63
for node in nodes {
34
- if node. 0 >= 0
35
- && node. 0 < self . width as isize
36
- && node. 1 >= 0
37
- && node. 1 < self . height as isize
38
- {
39
- antinodes. insert ( node) ;
40
- }
64
+ antinodes. insert ( node) ;
41
65
}
42
66
}
43
67
}
@@ -64,63 +88,6 @@ impl Graph {
64
88
}
65
89
}
66
90
67
- // None of these are bounds-checked. We do that in the caller.
68
- fn compute_antinodes ( left : Coord , right : Coord ) -> Vec < Coord > {
69
- let mut nodes = Vec :: new ( ) ;
70
- let x_diff = ( left. 0 - right. 0 ) . abs ( ) ;
71
- let y_diff = ( left. 1 - right. 1 ) . abs ( ) ;
72
- if left. 0 < right. 0 {
73
- if left. 1 < right. 1 {
74
- // L.
75
- // .R
76
- let x = left. 0 - x_diff;
77
- let y = left. 1 - y_diff;
78
- nodes. push ( ( x, y) ) ;
79
-
80
- let x = right. 0 + x_diff;
81
- let y = right. 1 + y_diff;
82
- nodes. push ( ( x, y) ) ;
83
- } else {
84
- // left.1 >= right.1
85
- // .R
86
- // L.
87
- let x = left. 0 - x_diff;
88
- let y = left. 1 + y_diff;
89
- nodes. push ( ( x, y) ) ;
90
-
91
- let x = right. 0 + x_diff;
92
- let y = right. 1 - y_diff;
93
- nodes. push ( ( x, y) ) ;
94
- }
95
- } else {
96
- // left.0 >= right.0
97
- if left. 1 < right. 1 {
98
- // .L
99
- // R.
100
- let x = right. 0 - x_diff;
101
- let y = right. 1 + y_diff;
102
- nodes. push ( ( x, y) ) ;
103
-
104
- let x = left. 0 + x_diff;
105
- let y = left. 1 - y_diff;
106
- nodes. push ( ( x, y) ) ;
107
- } else {
108
- // left.1 >= right.1
109
- // R.
110
- // .L
111
- let x = right. 0 - x_diff;
112
- let y = right. 1 - y_diff;
113
- nodes. push ( ( x, y) ) ;
114
-
115
- let x = left. 0 + x_diff;
116
- let y = left. 1 + y_diff;
117
- nodes. push ( ( x, y) ) ;
118
- }
119
- }
120
-
121
- nodes
122
- }
123
-
124
91
fn read_graph ( lines : & [ String ] ) -> Graph {
125
92
let mut antennas: HashMap < char , Vec < Coord > > = HashMap :: new ( ) ;
126
93
let height = lines. len ( ) ;
@@ -149,17 +116,31 @@ fn read_graph(lines: &[String]) -> Graph {
149
116
150
117
#[ test]
151
118
fn test_prelim ( ) {
152
- let antinodes = read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( ) ;
119
+ let antinodes = read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( false ) ;
153
120
assert_eq ! ( antinodes, 14 ) ;
154
121
}
155
122
156
123
#[ test]
157
124
fn test_part1 ( ) {
158
- let antinodes = read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( ) ;
125
+ let antinodes = read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( false ) ;
159
126
assert_eq ! ( antinodes, 344 ) ;
160
127
}
161
128
129
+ #[ test]
130
+ fn test_prelim2 ( ) {
131
+ let antinodes = read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( true ) ;
132
+ assert_eq ! ( antinodes, 34 ) ;
133
+ }
134
+
135
+ #[ test]
136
+ fn test_part2 ( ) {
137
+ let antinodes = read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( true ) ;
138
+ assert_eq ! ( antinodes, 1182 ) ;
139
+ }
140
+
162
141
fn main ( ) {
163
- read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( ) ;
164
- read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( ) ;
142
+ read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( false ) ;
143
+ read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( false ) ;
144
+ read_graph ( & get_input ( "prelim.txt" ) ) . find_antinodes ( true ) ;
145
+ read_graph ( & get_input ( "input.txt" ) ) . find_antinodes ( true ) ;
165
146
}
0 commit comments