Skip to content

Commit 879c47b

Browse files
committed
22th day
1 parent c4df1ed commit 879c47b

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

data/examples/22-1.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
10
3+
100
4+
2024

data/examples/22-2.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
2
3+
3
4+
2024

src/bin/22.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
advent_of_code::solution!(22);
2+
3+
use advent_of_code::maneatingape::hash::*;
4+
use advent_of_code::maneatingape::parse::*;
5+
6+
fn parse_data(input: &str) -> Vec<u32> {
7+
input.lines().map(|line| line.unsigned()).collect()
8+
}
9+
10+
const MASK_8_BITS: u32 = (1 << 8) - 1;
11+
const MASK_24_BITS: u32 = (1 << 24) - 1;
12+
13+
#[allow(clippy::let_and_return)]
14+
fn next_price(secret_number: u32) -> u32 {
15+
let secret_number = secret_number << 6 & MASK_24_BITS ^ secret_number;
16+
let secret_number = secret_number >> 5 ^ secret_number;
17+
let secret_number = secret_number << 11 & MASK_24_BITS ^ secret_number;
18+
19+
secret_number
20+
}
21+
22+
pub fn part_one(input: &str) -> Option<u64> {
23+
let data = parse_data(input);
24+
25+
let result = data
26+
.into_iter()
27+
.map(|secret_number| {
28+
(0..2000).fold(secret_number, |secret_number, _| next_price(secret_number)) as u64
29+
})
30+
.sum();
31+
32+
Some(result)
33+
}
34+
35+
pub fn part_two(input: &str) -> Option<u32> {
36+
let data = parse_data(input);
37+
38+
let mut prices = FastMap::new();
39+
40+
for (i, secret_number) in data.into_iter().enumerate() {
41+
let mut secret_number = secret_number;
42+
let mut prev_cost = secret_number % 10;
43+
44+
let mut four_changes = 0;
45+
46+
for n in 0..2000 {
47+
secret_number = next_price(secret_number);
48+
let cost = secret_number % 10;
49+
50+
four_changes <<= 8;
51+
four_changes |= cost.wrapping_sub(prev_cost) & MASK_8_BITS;
52+
53+
if n >= 4 {
54+
prices.entry((i, four_changes)).or_insert(cost);
55+
}
56+
57+
prev_cost = cost;
58+
}
59+
}
60+
61+
let mut best_results = FastMap::with_capacity(prices.len());
62+
for ((_, four_changes), cost) in prices.into_iter() {
63+
*best_results.entry(four_changes).or_insert(0) += cost;
64+
}
65+
66+
let result = best_results.into_values().max().unwrap();
67+
68+
Some(result)
69+
}
70+
71+
#[cfg(test)]
72+
mod tests {
73+
use super::*;
74+
75+
#[test]
76+
fn test_part_one() {
77+
let input = advent_of_code::template::read_file_part("examples", DAY, 1);
78+
let result = part_one(&input);
79+
assert_eq!(result, Some(37327623));
80+
}
81+
82+
#[test]
83+
fn test_part_two() {
84+
let input = advent_of_code::template::read_file_part("examples", DAY, 2);
85+
let result = part_two(&input);
86+
assert_eq!(result, Some(23));
87+
}
88+
}

0 commit comments

Comments
 (0)