80 lines
1.8 KiB
Rust
80 lines
1.8 KiB
Rust
//! Day 9: Mirage Maintenance
|
|
|
|
use itertools::Itertools;
|
|
|
|
pub const DAY: u8 = 9;
|
|
pub const TITLE: &str = "Mirage Maintenance";
|
|
|
|
fn parse(input: Vec<String>) -> Vec<Vec<i32>> {
|
|
input
|
|
.iter()
|
|
.map(|l| {
|
|
l.split_ascii_whitespace()
|
|
.map(|n| n.parse().unwrap())
|
|
.collect()
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn solve(input: Vec<String>, first: bool) -> String {
|
|
let parsed = parse(input);
|
|
parsed
|
|
.into_iter()
|
|
.map(|l| {
|
|
let mut sequences: Vec<Vec<i32>> = vec![l];
|
|
while !sequences.last().unwrap().iter().all_equal() {
|
|
sequences.push(
|
|
sequences
|
|
.last()
|
|
.unwrap()
|
|
.iter()
|
|
.tuple_windows()
|
|
.map(|(a, b)| b - a)
|
|
.collect_vec(),
|
|
);
|
|
}
|
|
|
|
sequences.iter().rev().fold(0, |acc, s| {
|
|
if first {
|
|
s.first().unwrap() - acc
|
|
} else {
|
|
acc + s.last().unwrap()
|
|
}
|
|
})
|
|
})
|
|
.sum::<i32>()
|
|
.to_string()
|
|
}
|
|
|
|
pub fn part1(input: Vec<String>) -> String {
|
|
solve(input, false)
|
|
}
|
|
|
|
pub fn part2(input: Vec<String>) -> String {
|
|
solve(input, true)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn t_example1() {
|
|
assert_eq!(part1(crate::read_example(DAY, 1)), "114");
|
|
}
|
|
|
|
#[test]
|
|
fn t_part1() {
|
|
assert_eq!(part1(crate::read_input(DAY)), "1884768153");
|
|
}
|
|
|
|
#[test]
|
|
fn t_example2() {
|
|
assert_eq!(part2(crate::read_example(DAY, 2)), "2");
|
|
}
|
|
|
|
#[test]
|
|
fn t_part2() {
|
|
assert_eq!(part2(crate::read_input(DAY)), "1031");
|
|
}
|
|
}
|