day 22 part 2
This commit is contained in:
119
src/day22.rs
119
src/day22.rs
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user