day22: part 2 solution. 38s runtime but works.
This commit is contained in:
parent
52e7bb9af7
commit
c433076f40
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 8.0 KiB |
@ -1,6 +1,6 @@
|
||||
<!-- AOC TILES BEGIN -->
|
||||
<h1 align="center">
|
||||
2024 - 40 ⭐ - Rust
|
||||
2024 - 42 ⭐ - Rust
|
||||
</h1>
|
||||
<a href="src/day1.rs">
|
||||
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
|
||||
@ -65,4 +65,7 @@
|
||||
<a href="src/day21.rs">
|
||||
<img src=".aoc_tiles/tiles/2024/21.png" width="161px">
|
||||
</a>
|
||||
<a href="src/day22.rs">
|
||||
<img src=".aoc_tiles/tiles/2024/22.png" width="161px">
|
||||
</a>
|
||||
<!-- AOC TILES END -->
|
||||
|
107
src/day22.rs
107
src/day22.rs
@ -1,4 +1,12 @@
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use itertools::Itertools;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
struct Change {
|
||||
price: i8,
|
||||
delta: i8,
|
||||
}
|
||||
|
||||
fn evolve_secret(mut n: i64) -> i64 {
|
||||
n = ((n * 64) ^ n) % 16777216;
|
||||
@ -14,6 +22,54 @@ fn rounds(mut secret: i64, n: i64) -> i64 {
|
||||
secret
|
||||
}
|
||||
|
||||
fn prices(mut secret: i64, n: i64) -> Vec<i8> {
|
||||
let mut prices = vec![(secret % 10) as i8];
|
||||
for _ in 1..n {
|
||||
secret = evolve_secret(secret);
|
||||
prices.push((secret % 10) as i8);
|
||||
}
|
||||
prices
|
||||
}
|
||||
|
||||
fn changes(prices: &Vec<i8>) -> Vec<Change> {
|
||||
prices
|
||||
.windows(2)
|
||||
.map(|a| Change {
|
||||
price: a[1],
|
||||
delta: a[1] - a[0],
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn profit_for_sequence(changes: &Vec<Vec<Change>>, seq: &[i8]) -> i64 {
|
||||
changes
|
||||
.par_iter()
|
||||
.filter_map(|inner| {
|
||||
if let Some(buy) = inner
|
||||
.windows(seq.len())
|
||||
.find(|window| window.iter().zip(seq).all(|(w, z)| w.delta == *z))
|
||||
{
|
||||
Some(buy[seq.len() - 1].price as i64)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn find_best_sequence(changes: &Vec<Vec<Change>>) -> [i8; 4] {
|
||||
let mut best_seq = [0, 0, 0, 0];
|
||||
let mut best_profit = 0;
|
||||
for seq in (0..4).map(|_| (-9..=9 as i8)).multi_cartesian_product() {
|
||||
let profit = profit_for_sequence(changes, &seq);
|
||||
if profit > best_profit {
|
||||
best_seq = seq.try_into().unwrap();
|
||||
best_profit = profit;
|
||||
}
|
||||
}
|
||||
best_seq
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> Vec<i64> {
|
||||
input.lines().map(|l| l.parse().unwrap()).collect()
|
||||
}
|
||||
@ -27,9 +83,14 @@ fn part1(input: &str) -> i64 {
|
||||
|
||||
#[aoc(day22, part2)]
|
||||
fn part2(input: &str) -> i64 {
|
||||
todo!()
|
||||
}
|
||||
let secrets = parse(input);
|
||||
|
||||
let price_changes = secrets.iter().map(|s| changes(&prices(*s, 2000))).collect_vec();
|
||||
|
||||
let seq = find_best_sequence(&price_changes);
|
||||
println!("found best seq: {:?}", seq);
|
||||
profit_for_sequence(&price_changes, &seq)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@ -37,6 +98,11 @@ mod tests {
|
||||
const EXAMPLE: &str = "1
|
||||
10
|
||||
100
|
||||
2024";
|
||||
|
||||
const EXAMPLE2: &str = "1
|
||||
2
|
||||
3
|
||||
2024";
|
||||
|
||||
#[test]
|
||||
@ -52,13 +118,46 @@ mod tests {
|
||||
assert_eq!(rounds(10, 2000), 4700978);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prices() {
|
||||
assert_eq!(prices(123, 10), vec![3, 0, 6, 5, 4, 4, 6, 4, 4, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_profit() {
|
||||
assert_eq!(
|
||||
profit_for_sequence(&vec![changes(&prices(123, 10))], &[-1, -1, 0, 2]),
|
||||
6
|
||||
);
|
||||
let secrets = parse(EXAMPLE2);
|
||||
|
||||
let price_changes = secrets.iter().map(|s| changes(&prices(*s, 2000))).collect_vec();
|
||||
assert_eq!(
|
||||
profit_for_sequence(&price_changes, &[-2, 1, -1, 3]),
|
||||
23
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_changes() {
|
||||
let changes = changes(&prices(123, 10));
|
||||
assert_eq!(
|
||||
changes.iter().map(|c| c.delta).collect_vec(),
|
||||
vec![-3, 6, -1, -1, 0, 2, -2, 0, -2]
|
||||
);
|
||||
assert_eq!(
|
||||
changes.iter().map(|c| c.price).collect_vec(),
|
||||
vec![0, 6, 5, 4, 4, 6, 4, 4, 2]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
assert_eq!(part1(EXAMPLE),37327623);
|
||||
assert_eq!(part1(EXAMPLE), 37327623);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example() {
|
||||
assert_eq!(part2(EXAMPLE), 0);
|
||||
assert_eq!(part2(EXAMPLE2), 23);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user