76 lines
1.5 KiB
Rust
76 lines
1.5 KiB
Rust
use aoc_runner_derive::{aoc, aoc_generator};
|
|
|
|
type Seq = Vec<i64>;
|
|
|
|
fn all_zero(s: &Seq) -> bool {
|
|
s.iter().find(|t| **t != 0).is_none()
|
|
}
|
|
|
|
#[aoc_generator(day9)]
|
|
fn parse(input: &str) -> Vec<Seq> {
|
|
input
|
|
.lines()
|
|
.filter_map(|line| {
|
|
if !line.is_empty() {
|
|
let nums = line.split(" ").map(|n| n.parse::<i64>().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) -> i64 {
|
|
if all_zero(s) {
|
|
0
|
|
} else {
|
|
let d = get_diffs(s);
|
|
s.last().unwrap() + next_number(&d)
|
|
}
|
|
}
|
|
|
|
#[aoc(day9, part1)]
|
|
fn part1(input: &[Seq]) -> i64 {
|
|
input.iter().map(|s| next_number(&s)).sum()
|
|
}
|
|
|
|
fn previous_number(s: &Seq) -> i64 {
|
|
if all_zero(s) {
|
|
0
|
|
} else {
|
|
let d = get_diffs(s);
|
|
s[0] - previous_number(&d)
|
|
}
|
|
}
|
|
|
|
#[aoc(day9, part2)]
|
|
fn part2(input: &[Seq]) -> i64 {
|
|
input.iter().map(|s| previous_number(&s)).sum()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
const SAMPLE_DATA: &'static str = r#"0 3 6 9 12 15
|
|
1 3 6 10 15 21
|
|
10 13 16 21 30 45
|
|
"#;
|
|
|
|
#[test]
|
|
fn sample_data() {
|
|
let input = parse(&SAMPLE_DATA);
|
|
assert_eq!(part1(&input), 114);
|
|
assert_eq!(part2(&input), 2);
|
|
}
|
|
}
|