99 lines
2.2 KiB
Rust
99 lines
2.2 KiB
Rust
|
use std::fs::File;
|
||
|
use std::io::{BufRead, BufReader, Lines};
|
||
|
use itertools::Itertools;
|
||
|
|
||
|
// BOILERPLATE
|
||
|
type InputIter = Lines<BufReader<File>>;
|
||
|
|
||
|
fn get_input() -> InputIter {
|
||
|
let f = File::open("input").unwrap();
|
||
|
let br = BufReader::new(f);
|
||
|
br.lines()
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
println!("Problem 1 solution: {}", problem1(get_input()));
|
||
|
println!("Problem 2 solution: {}", problem2(get_input()));
|
||
|
}
|
||
|
|
||
|
// PARSE
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
struct History(Vec<Vec<i64>>);
|
||
|
|
||
|
impl From<&str> for History {
|
||
|
fn from(s: &str) -> Self {
|
||
|
let hist: Vec<i64> = s
|
||
|
.split_whitespace()
|
||
|
.map(|num| num.parse().unwrap())
|
||
|
.collect();
|
||
|
Self(vec![hist])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl History {
|
||
|
fn build_row(&mut self) {
|
||
|
let last = self.0.last().unwrap();
|
||
|
self.0.push(
|
||
|
last.iter()
|
||
|
.tuple_windows()
|
||
|
.map(|(a, b)| b - a)
|
||
|
.collect(),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
fn build(&mut self) {
|
||
|
while !self.0.last().unwrap().iter().all(|x| *x == 0) {
|
||
|
self.build_row();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn extrapolate(&mut self) {
|
||
|
self.build();
|
||
|
self.0.last_mut().unwrap().push(0);
|
||
|
for (lower, upper) in (0..self.0.len()).rev().tuple_windows() {
|
||
|
let new_value = self.0[upper].last().unwrap() + self.0[lower].last().unwrap();
|
||
|
self.0[upper].push(new_value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// PROBLEM 1 solution
|
||
|
|
||
|
fn problem1<T: BufRead>(input: Lines<T>) -> i64 {
|
||
|
let mut histories: Vec<History> = input.map(|s| History::from(s.unwrap().as_str())).collect();
|
||
|
|
||
|
for history in &mut histories {
|
||
|
history.extrapolate();
|
||
|
}
|
||
|
|
||
|
histories.iter().map(|history| history.0.first().unwrap().last().unwrap()).sum()
|
||
|
}
|
||
|
|
||
|
// PROBLEM 2 solution
|
||
|
fn problem2<T: BufRead>(input: Lines<T>) -> u64 {
|
||
|
0
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use crate::*;
|
||
|
use std::io::Cursor;
|
||
|
|
||
|
const EXAMPLE: &str = &"0 3 6 9 12 15
|
||
|
1 3 6 10 15 21
|
||
|
10 13 16 21 30 45";
|
||
|
|
||
|
#[test]
|
||
|
fn problem1_example() {
|
||
|
let c = Cursor::new(EXAMPLE);
|
||
|
assert_eq!(problem1(c.lines()), 114);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn problem2_example() {
|
||
|
let c = Cursor::new(EXAMPLE);
|
||
|
assert_eq!(problem2(c.lines()), 0);
|
||
|
}
|
||
|
}
|