Skip to content

Commit 31910e5

Browse files
committed
Improved problem 22 part 2 for AOC2024 with lookup vs. brute-force
This solution computes the totals for seen quads on the fly for each particular bidder. We only add the first time we have seen it, and any previous bidder automatically doesn't have any of these quad patterns (by definition). Any subsequent bidders will automatically update the running total for the quad.
1 parent 344f57c commit 31910e5

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

aoc22/src/main.rs

+63-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::collections::HashSet;
23
use std::fs::File;
34
use std::io::BufRead;
@@ -20,11 +21,15 @@ type Secrets = [u64; MAX_STEPS];
2021
type Price = [i64; MAX_STEPS];
2122
type Diff = [i64; MAX_STEPS];
2223

24+
type Quad = (i8, i8, i8, i8);
25+
type QuadMap = HashMap<Quad, i64>;
26+
2327
#[derive(Debug)]
2428
struct BananaMarket {
2529
secrets: Vec<Secrets>,
2630
prices: Vec<Price>,
2731
diffs: Vec<Diff>,
32+
quad_map: QuadMap,
2833
}
2934

3035
impl BananaMarket {
@@ -33,6 +38,7 @@ impl BananaMarket {
3338
secrets: Vec::new(),
3439
prices: Vec::new(),
3540
diffs: Vec::new(),
41+
quad_map: HashMap::new(),
3642
}
3743
}
3844

@@ -51,11 +57,34 @@ impl BananaMarket {
5157
let mut diffs: Diff = [0; MAX_STEPS];
5258
let mut last_price = (start_secret % 10) as i64;
5359
let mut secret = start_secret;
60+
61+
let mut seen_set = HashSet::new();
62+
5463
for i in 0..MAX_STEPS {
5564
secrets[i] = secret;
5665
prices[i] = (secret % 10) as i64;
5766
diffs[i] = prices[i] - last_price;
5867
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+
}
5988
secret = compute_secret(secret);
6089
}
6190
self.secrets.push(secrets);
@@ -110,7 +139,23 @@ impl BananaMarket {
110139
total
111140
}
112141

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 {
114159
let mut best = 0;
115160

116161
let quads = self.find_diff_quads();
@@ -119,7 +164,7 @@ impl BananaMarket {
119164
let val = self.evaluate_diff_quad(&quad);
120165
if val > best {
121166
best = val;
122-
best_quad = quad.clone();
167+
best_quad = quad;
123168
}
124169
}
125170

@@ -211,8 +256,11 @@ fn test_prelim() {
211256

212257
#[test]
213258
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();
216264
assert_eq!(total, 23);
217265
}
218266

@@ -222,13 +270,20 @@ fn test_part1() {
222270
assert_eq!(sum, 19458130434);
223271
}
224272

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+
225280
fn main() {
226281
compute_secret_n_sum(&read_secret_numbers(&get_input("prelim.txt")), 2000);
227282
compute_secret_n_sum(&read_secret_numbers(&get_input("input.txt")), 2000);
228283
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();
230286
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();
234289
}

0 commit comments

Comments
 (0)