2023 day9/rust: add solution
This commit is contained in:
parent
c1ceef4afd
commit
91f1c1b609
4 changed files with 121 additions and 0 deletions
10
2023/day9/rust/Cargo.toml
Normal file
10
2023/day9/rust/Cargo.toml
Normal 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
102
2023/day9/rust/src/main.rs
Normal 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
8
Cargo.lock
generated
|
@ -679,6 +679,14 @@ dependencies = [
|
||||||
"petgraph",
|
"petgraph",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust_2023_09"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aoc",
|
||||||
|
"itertools 0.12.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
|
|
@ -34,4 +34,5 @@ members = [
|
||||||
"2023/day6/rust",
|
"2023/day6/rust",
|
||||||
"2023/day7/rust",
|
"2023/day7/rust",
|
||||||
"2023/day8/rust",
|
"2023/day8/rust",
|
||||||
|
"2023/day9/rust",
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue