66 lines
1.6 KiB
Rust
66 lines
1.6 KiB
Rust
|
pub fn run() {
|
||
|
let input = include_str!("../input/day9.txt");
|
||
|
// let input = r#"0 3 6 9 12 15
|
||
|
// 1 3 6 10 15 21
|
||
|
// 10 13 16 21 30 45"#;
|
||
|
|
||
|
let sequences = input.lines().map(parse_sequence).collect::<Vec<_>>();
|
||
|
|
||
|
dbg!(sequences.iter().map(|s| extrapolate(&s)).sum::<i32>());
|
||
|
dbg!(sequences.iter().map(|s| extrapolate_back(&s)).sum::<i32>());
|
||
|
}
|
||
|
|
||
|
fn parse_sequence(s: &str) -> Vec<i32> {
|
||
|
s.trim().split(" ").map(|s| s.parse().unwrap()).collect()
|
||
|
}
|
||
|
|
||
|
fn extrapolate(seq: &[i32]) -> i32 {
|
||
|
let deltas = deltas(seq);
|
||
|
if deltas.iter().all(|x| *x == 0) {
|
||
|
*seq.last().unwrap()
|
||
|
} else {
|
||
|
let next_delta = extrapolate(&deltas);
|
||
|
*seq.last().unwrap() + next_delta
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn extrapolate_back(seq: &[i32]) -> i32 {
|
||
|
let deltas = deltas(seq);
|
||
|
if deltas.iter().all(|x| *x == 0) {
|
||
|
seq[0]
|
||
|
} else {
|
||
|
let prev_delta = extrapolate_back(&deltas);
|
||
|
seq[0] - prev_delta
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn deltas(seq: &[i32]) -> Vec<i32> {
|
||
|
seq.iter()
|
||
|
.zip(seq.iter().skip(1))
|
||
|
.map(|(a, b)| b - a)
|
||
|
.collect()
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use super::*;
|
||
|
|
||
|
#[test]
|
||
|
fn test_deltas() {
|
||
|
assert_eq!(deltas(&[1, 2, 3]), vec![1, 1]);
|
||
|
assert_eq!(deltas(&[1, 1, 1]), vec![0, 0]);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_extrapolate() {
|
||
|
assert_eq!(extrapolate(&[1, 1, 1]), 1);
|
||
|
assert_eq!(extrapolate(&[1, 2, 3]), 4);
|
||
|
assert_eq!(extrapolate(&[1, 3, 6]), 10);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_extrapolate_back() {
|
||
|
assert_eq!(extrapolate_back(&[10, 13, 16, 21, 30, 45]), 5);
|
||
|
}
|
||
|
}
|