1
+ use std:: collections:: HashMap ;
1
2
use std:: collections:: HashSet ;
2
3
use std:: fs:: File ;
3
4
use std:: io:: BufRead ;
@@ -20,11 +21,15 @@ type Secrets = [u64; MAX_STEPS];
20
21
type Price = [ i64 ; MAX_STEPS ] ;
21
22
type Diff = [ i64 ; MAX_STEPS ] ;
22
23
24
+ type Quad = ( i8 , i8 , i8 , i8 ) ;
25
+ type QuadMap = HashMap < Quad , i64 > ;
26
+
23
27
#[ derive( Debug ) ]
24
28
struct BananaMarket {
25
29
secrets : Vec < Secrets > ,
26
30
prices : Vec < Price > ,
27
31
diffs : Vec < Diff > ,
32
+ quad_map : QuadMap ,
28
33
}
29
34
30
35
impl BananaMarket {
@@ -33,6 +38,7 @@ impl BananaMarket {
33
38
secrets : Vec :: new ( ) ,
34
39
prices : Vec :: new ( ) ,
35
40
diffs : Vec :: new ( ) ,
41
+ quad_map : HashMap :: new ( ) ,
36
42
}
37
43
}
38
44
@@ -51,11 +57,34 @@ impl BananaMarket {
51
57
let mut diffs: Diff = [ 0 ; MAX_STEPS ] ;
52
58
let mut last_price = ( start_secret % 10 ) as i64 ;
53
59
let mut secret = start_secret;
60
+
61
+ let mut seen_set = HashSet :: new ( ) ;
62
+
54
63
for i in 0 ..MAX_STEPS {
55
64
secrets[ i] = secret;
56
65
prices[ i] = ( secret % 10 ) as i64 ;
57
66
diffs[ i] = prices[ i] - last_price;
58
67
last_price = prices[ i] ;
68
+
69
+ // We use i > 3, because technically the first price doesn't
70
+ // really have a difference to it.
71
+ if i > 3 {
72
+ let quad = (
73
+ diffs[ i - 3 ] as i8 ,
74
+ diffs[ i - 2 ] as i8 ,
75
+ diffs[ i - 1 ] as i8 ,
76
+ diffs[ i] as i8 ,
77
+ ) ;
78
+ if !seen_set. contains ( & quad) {
79
+ if let std:: collections:: hash_map:: Entry :: Vacant ( e) = self . quad_map . entry ( quad)
80
+ {
81
+ e. insert ( prices[ i] ) ;
82
+ } else {
83
+ * self . quad_map . get_mut ( & quad) . unwrap ( ) += prices[ i] ;
84
+ }
85
+ seen_set. insert ( quad) ;
86
+ }
87
+ }
59
88
secret = compute_secret ( secret) ;
60
89
}
61
90
self . secrets . push ( secrets) ;
@@ -110,7 +139,23 @@ impl BananaMarket {
110
139
total
111
140
}
112
141
113
- fn find_best_total ( & self ) -> i64 {
142
+ fn find_best_total_lookup ( & self ) -> i64 {
143
+ let mut best_quad = ( 0 , 0 , 0 , 0 ) ;
144
+ let mut best = 0 ;
145
+ for ( & k, & v) in self . quad_map . iter ( ) {
146
+ if v > best {
147
+ best = v;
148
+ best_quad = k;
149
+ }
150
+ }
151
+
152
+ println ! ( "Best price: {best}" ) ;
153
+ println ! ( "Best quad: {:?}" , best_quad) ;
154
+
155
+ best
156
+ }
157
+
158
+ fn find_best_total_brute_force ( & self ) -> i64 {
114
159
let mut best = 0 ;
115
160
116
161
let quads = self . find_diff_quads ( ) ;
@@ -119,7 +164,7 @@ impl BananaMarket {
119
164
let val = self . evaluate_diff_quad ( & quad) ;
120
165
if val > best {
121
166
best = val;
122
- best_quad = quad. clone ( ) ;
167
+ best_quad = quad;
123
168
}
124
169
}
125
170
@@ -211,8 +256,11 @@ fn test_prelim() {
211
256
212
257
#[ test]
213
258
fn test_prelim2 ( ) {
214
- let total =
215
- BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "prelim2.txt" ) ) ) . find_best_total ( ) ;
259
+ let total = BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "prelim2.txt" ) ) )
260
+ . find_best_total_brute_force ( ) ;
261
+ assert_eq ! ( total, 23 ) ;
262
+ let total = BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "prelim2.txt" ) ) )
263
+ . find_best_total_lookup ( ) ;
216
264
assert_eq ! ( total, 23 ) ;
217
265
}
218
266
@@ -222,13 +270,20 @@ fn test_part1() {
222
270
assert_eq ! ( sum, 19458130434 ) ;
223
271
}
224
272
273
+ #[ test]
274
+ fn test_part2 ( ) {
275
+ let total = BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "input.txt" ) ) )
276
+ . find_best_total_lookup ( ) ;
277
+ assert_eq ! ( total, 2130 ) ;
278
+ }
279
+
225
280
fn main ( ) {
226
281
compute_secret_n_sum ( & read_secret_numbers ( & get_input ( "prelim.txt" ) ) , 2000 ) ;
227
282
compute_secret_n_sum ( & read_secret_numbers ( & get_input ( "input.txt" ) ) , 2000 ) ;
228
283
let market = BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "prelim2.txt" ) ) ) ;
229
- market. find_best_total ( ) ;
284
+ market. find_best_total_brute_force ( ) ;
285
+ market. find_best_total_lookup ( ) ;
230
286
let market = BananaMarket :: from_vec ( & read_secret_numbers ( & get_input ( "input.txt" ) ) ) ;
231
- //let quads = market.find_diff_quads();
232
- //println!("quads: {}", quads.len());
233
- market. find_best_total ( ) ;
287
+ market. find_best_total_lookup ( ) ;
288
+ //market.find_best_total_brute_force();
234
289
}
0 commit comments