Files
advent-of-code-2023/src/bin/part09.rs
2023-12-09 14:22:02 +01:00

75 lines
1.9 KiB
Rust

use std::time;
fn main() {
let t1 = time::Instant::now();
let data = load_input();
let d1 = t1.elapsed();
println!("Loading: {:?}", d1);
let t2 = time::Instant::now();
let sum1 = data.iter().map(|d| extrapolate_next_value(&d)).sum::<i32>();
let sum2 = data.iter().map(|d| extrapolate_previous_value(&d)).sum::<i32>();
let d2 = t2.elapsed();
println!("Summing: {:?}", d2);
println!("Total: {:?}", d1 + d2);
println!("Sum1: {}", sum1);
println!("Sum2: {}", sum2);
assert_eq!(sum1, 1584748274);
assert_eq!(sum2, 1026);
}
fn extrapolate_next_value(series: &[i32]) -> i32 {
let differences = forward_differences(series);
let mut next_value = *series.last().unwrap();
next_value += differences.iter().skip(1).map(|d| d.last().unwrap()).sum::<i32>();
// for diff in differences.iter().skip(1) {
// next_value += diff.last().unwrap();
// }
next_value
}
fn extrapolate_previous_value(series: &[i32]) -> i32 {
let differences = forward_differences(series);
let mut previous_value = *series.first().unwrap();
for (i, diff) in differences.iter().skip(1).enumerate() {
if i % 2 == 0 {
previous_value -= diff[0];
} else {
previous_value += diff[0];
}
}
previous_value
}
fn forward_differences(series: &[i32]) -> Vec<Vec<i32>> {
let mut differences = vec![series.to_vec()];
while differences.last().unwrap().iter().any(|d| *d != 0) {
let last = differences.last().unwrap();
let next = last.windows(2).map(|w| w[1] - w[0]).collect();
differences.push(next);
}
differences
}
fn load_input() -> Vec<Vec<i32>> {
let data = std::fs::read_to_string("src/bin/part09.txt")
.expect("Could not read file")
.lines()
.map(|l| {
l.split_whitespace().map(|s| s.parse::<i32>().unwrap()).collect::<Vec<_>>()
})
.collect::<Vec<_>>();
data
}