87 lines
1.7 KiB
Rust
87 lines
1.7 KiB
Rust
advent_of_code::solution!(9);
|
|
|
|
type Seq = Vec<i32>;
|
|
|
|
fn all_zero(s: &Seq) -> bool {
|
|
s.iter().find(|t| **t != 0).is_none()
|
|
}
|
|
|
|
fn parse(input: &str) -> Vec<Seq> {
|
|
input
|
|
.lines()
|
|
.filter_map(|line| {
|
|
if !line.is_empty() {
|
|
let nums = line.split(" ").map(|n| n.parse::<i32>().unwrap()).collect();
|
|
Some(nums)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn get_diffs(s: &Seq) -> Seq {
|
|
let mut result: Seq = vec![];
|
|
for index in 0..(s.len() - 1) {
|
|
result.push(s[index + 1] - s[index]);
|
|
}
|
|
result
|
|
}
|
|
|
|
fn next_number(s: &Seq) -> i32 {
|
|
if all_zero(s) {
|
|
0
|
|
} else {
|
|
let d = get_diffs(s);
|
|
s.last().unwrap() + next_number(&d)
|
|
}
|
|
}
|
|
|
|
pub fn part_one(input: &str) -> Option<u32> {
|
|
Some(
|
|
parse(input)
|
|
.iter()
|
|
.map(|s| next_number(&s))
|
|
.sum::<i32>()
|
|
.try_into()
|
|
.unwrap(),
|
|
)
|
|
}
|
|
|
|
fn previous_number(s: &Seq) -> i32 {
|
|
if all_zero(s) {
|
|
0
|
|
} else {
|
|
let d = get_diffs(s);
|
|
s[0] - previous_number(&d)
|
|
}
|
|
}
|
|
|
|
pub fn part_two(input: &str) -> Option<u32> {
|
|
Some(
|
|
parse(input)
|
|
.iter()
|
|
.map(|s| previous_number(&s))
|
|
.sum::<i32>()
|
|
.try_into()
|
|
.unwrap(),
|
|
)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_part_one() {
|
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
|
assert_eq!(result, Some(114));
|
|
}
|
|
|
|
#[test]
|
|
fn test_part_two() {
|
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
|
assert_eq!(result, Some(2));
|
|
}
|
|
}
|