1
0

day 22 part 2

This commit is contained in:
2025-07-30 21:24:19 +02:00
parent 0482402173
commit b75a35a4c1
2 changed files with 110 additions and 16 deletions

View File

@@ -1,4 +1,6 @@
use std::{fs::read_to_string, ops::BitXor};
use std::{collections::HashSet, fs::read_to_string, ops::BitXor};
use itertools::Itertools;
pub fn day_main() {
let input = read_to_string("input/day22.txt").unwrap();
@@ -16,13 +18,17 @@ fn part1(input: &str) -> RiddleResult {
fn solution(initial_secret: i64) -> i64 {
let mut secret = initial_secret;
for _ in 0..2000 {
secret = prune(mix(secret * 64, secret));
secret = prune(mix(secret / 32, secret));
secret = prune(mix(secret * 2048, secret))
secret = fun_name(secret);
}
secret
}
fn fun_name(secret: i64) -> i64 {
let secret = prune(mix(secret * 64, secret));
let secret = prune(mix(secret / 32, secret));
prune(mix(secret * 2048, secret))
}
fn mix(value: i64, secret: i64) -> i64 {
value.bitxor(secret)
}
@@ -31,15 +37,89 @@ fn prune(value: i64) -> i64 {
value % 16777216
}
fn part2(_input: &str) -> RiddleResult {
0
fn part2(input: &str) -> RiddleResult {
let deltas = input
.trim()
.lines()
.map(|is| is.parse().unwrap())
.map(|s| generate(s))
.collect_vec();
let all_quadruples = sequences(&deltas);
println!(
"we have {} different sequences to check",
all_quadruples.len()
);
all_quadruples
.into_iter()
.enumerate()
.map(|(n, seq)| {
if n % 100 == 0 {
println!("{n}");
}
deltas
.iter()
.map(|monkey| find_first(seq, monkey))
.flat_map(|first| first.map(|f| f.3.price).or(Some(0)))
.sum()
})
.max()
.unwrap()
}
fn sequences(deltas: &Vec<Vec<Foo>>) -> HashSet<(i64, i64, i64, i64)> {
let mut all_quadruples = HashSet::new();
for monkey in deltas {
monkey
.iter()
.skip(1)
.tuple_windows()
.for_each(|(a, b, c, d)| {
all_quadruples.insert((a.delta, b.delta, c.delta, d.delta));
});
}
all_quadruples
}
fn find_first(seq: (i64, i64, i64, i64), monkey: &Vec<Foo>) -> Option<(&Foo, &Foo, &Foo, &Foo)> {
monkey.iter().tuple_windows().find(|(a, b, c, d)| {
a.delta == seq.0 && b.delta == seq.1 && c.delta == seq.2 && d.delta == seq.3
})
}
fn generate(start: i64) -> Vec<Foo> {
let mut result = Vec::with_capacity(2000);
result.push(Foo {
secret: start,
price: start % 10,
delta: -999999,
});
for i in 1..=2000 {
let prev = result[i - 1].secret;
let next = fun_name(prev);
let price = next % 10;
let delta = price - result[i - 1].price;
result.push(Foo {
secret: next,
price,
delta,
});
}
result
}
#[derive(Debug, PartialEq, Eq)]
struct Foo {
secret: i64,
price: i64,
delta: i64,
}
#[cfg(test)]
mod test {
use super::{part1, part2};
const TEST_INPUT: &str = r"";
use super::*;
#[test]
fn test1() {
@@ -57,6 +137,25 @@ mod test {
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 0);
let input = "1
2
3
2024
";
assert_eq!(part2(input), 23);
}
#[test]
fn finds_first() {
let monkey = generate(123);
let f = find_first((-1, -1, 0, 2), &monkey);
assert_eq!(
&Foo {
secret: 12683156,
price: 6,
delta: 2,
},
f.unwrap().3
);
}
}

View File

@@ -169,7 +169,7 @@ where
#[cfg(test)]
mod test {
use super::{part1, part2};
use super::part1;
const TEST_INPUT: &str = r"x00: 1
x01: 0
@@ -222,9 +222,4 @@ tnw OR pbm -> gnj";
fn test1() {
assert_eq!(part1(TEST_INPUT), 2024);
}
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 0);
}
}