2023 day9/rust: add solution

This commit is contained in:
Xiretza 2023-12-09 12:43:14 +00:00
parent c1ceef4afd
commit 91f1c1b609
4 changed files with 121 additions and 0 deletions

10
2023/day9/rust/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "rust_2023_09"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aoc = { path = "../../../common/rust" }
itertools = "0.12.0"

102
2023/day9/rust/src/main.rs Normal file
View file

@ -0,0 +1,102 @@
#![warn(clippy::pedantic)]
use std::{collections::VecDeque, io::stdin};
use itertools::Itertools;
type Value = isize;
fn make_derivative(xs: &[Value]) -> Option<VecDeque<Value>> {
if xs.iter().all_equal() {
None
} else {
Some(xs.iter().tuple_windows().map(|(a, b)| b - a).collect())
}
}
#[derive(Debug, Clone, Copy)]
enum Direction {
Forward,
Backward,
}
#[derive(Debug)]
struct History {
values: VecDeque<Value>,
derivatives: Vec<VecDeque<Value>>,
}
impl History {
pub fn new(values: VecDeque<Value>) -> Self {
let derivatives = std::iter::successors(Some(values.clone()), |prev| {
let (s1, s2) = prev.as_slices();
assert!(s2.is_empty());
make_derivative(s1)
})
.skip(1)
.collect();
Self {
values,
derivatives,
}
}
pub fn expand(&mut self, direction: Direction) {
Self::expand_values(&mut self.values, &mut self.derivatives, direction);
}
fn expand_values(
values: &mut VecDeque<Value>,
derivatives: &mut [VecDeque<Value>],
direction: Direction,
) {
if !derivatives.is_empty() {
let (next_values, next_derivatives) = derivatives.split_first_mut().unwrap();
Self::expand_values(next_values, next_derivatives, direction);
}
match direction {
Direction::Forward => {
let derivative = derivatives.first().map_or(0, |d| *d.back().unwrap());
values.push_back(*values.back().unwrap() + derivative);
}
Direction::Backward => {
let derivative = derivatives.first().map_or(0, |d| *d.front().unwrap());
values.push_front(*values.front().unwrap() - derivative);
}
}
}
}
fn main() {
let mut histories: VecDeque<_> = stdin()
.lines()
.map(Result::unwrap)
.map(|l| History::new(l.split(' ').map(|n| n.parse().unwrap()).collect()))
.collect();
for history in &mut histories {
history.expand(Direction::Forward);
}
println!(
"{}",
histories
.iter()
.map(|h| h.values.back().unwrap())
.sum::<Value>()
);
for history in &mut histories {
history.expand(Direction::Backward);
}
println!(
"{}",
histories
.iter()
.map(|h| h.values.front().unwrap())
.sum::<Value>()
);
}

8
Cargo.lock generated
View file

@ -679,6 +679,14 @@ dependencies = [
"petgraph",
]
[[package]]
name = "rust_2023_09"
version = "0.1.0"
dependencies = [
"aoc",
"itertools 0.12.0",
]
[[package]]
name = "rustversion"
version = "1.0.14"

View file

@ -34,4 +34,5 @@ members = [
"2023/day6/rust",
"2023/day7/rust",
"2023/day8/rust",
"2023/day9/rust",
]