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::(); let sum2 = data.iter().map(|d| extrapolate_previous_value(&d)).sum::(); 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::(); // 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> { 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> { 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::().unwrap()).collect::>() }) .collect::>(); data }