Improve day 9
This commit is contained in:
parent
a040d7f517
commit
b146637ad2
2 changed files with 20 additions and 25 deletions
|
@ -4,51 +4,46 @@ const INPUT: &str = include_str!("../../input/09");
|
|||
const TEST_INPUT: &str = include_str!("../../input/09-test");
|
||||
|
||||
fn main() {
|
||||
let (test1, test2) = solve(TEST_INPUT);
|
||||
let (part1, part2) = solve(INPUT);
|
||||
|
||||
assert_eq!(test1, 114, "Part 1");
|
||||
println!("Part 1: {}", part1);
|
||||
assert_eq!(test2, 2, "Part 2");
|
||||
println!("Part 2: {}", part2);
|
||||
assert_eq!(part1(TEST_INPUT), 114, "Part 1");
|
||||
println!("Part 1: {}", part1(INPUT));
|
||||
assert_eq!(part2(TEST_INPUT), 2, "Part 2");
|
||||
println!("Part 2: {}", part2(INPUT));
|
||||
}
|
||||
|
||||
fn solve(input: &str) -> (i64, i64) {
|
||||
let (forward, backward): (Vec<i64>, Vec<i64>) = input
|
||||
fn part1(input: &str) -> i64 {
|
||||
input.lines().map(parse_ws_separated).map(extrapolate).sum()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> i64 {
|
||||
input
|
||||
.lines()
|
||||
.map(parse_ws_separated)
|
||||
.map(|numbers| numbers.rev())
|
||||
.map(extrapolate)
|
||||
.unzip();
|
||||
(forward.into_iter().sum(), backward.into_iter().sum())
|
||||
.sum()
|
||||
}
|
||||
|
||||
/// Extrapolate (forward, backward).
|
||||
fn extrapolate(mut input: impl Iterator<Item = i64>) -> (i64, i64) {
|
||||
fn extrapolate(mut input: impl Iterator<Item = i64>) -> i64 {
|
||||
let start = input.next().unwrap();
|
||||
|
||||
// We do not need to store all values,
|
||||
// only the first and last difference values are important.
|
||||
let mut forward = vec![start];
|
||||
let mut backward = vec![start];
|
||||
// only the difference values are important.
|
||||
let mut differences = vec![start];
|
||||
|
||||
// Build the list of differences
|
||||
for next in input {
|
||||
let mut propagate_diff = next;
|
||||
for diff in &mut forward {
|
||||
for diff in &mut differences {
|
||||
let previous = *diff;
|
||||
*diff = propagate_diff;
|
||||
propagate_diff -= previous;
|
||||
}
|
||||
let double_0 = *forward.last().unwrap() == 0 && propagate_diff == 0;
|
||||
let double_0 = *differences.last().unwrap() == 0 && propagate_diff == 0;
|
||||
if !double_0 {
|
||||
forward.push(propagate_diff);
|
||||
backward.push(propagate_diff);
|
||||
differences.push(propagate_diff);
|
||||
}
|
||||
}
|
||||
|
||||
// Extrapolate
|
||||
let forward = forward.into_iter().sum();
|
||||
let backward = backward.into_iter().rev().fold(0, |a, b| b - a);
|
||||
|
||||
(forward, backward)
|
||||
differences.into_iter().sum()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
/// Parse a whitespace separated list of things.
|
||||
///
|
||||
/// Panics on parse error.
|
||||
pub fn parse_ws_separated<T>(s: &str) -> impl Iterator<Item = T> + '_
|
||||
pub fn parse_ws_separated<T>(s: &str) -> impl DoubleEndedIterator<Item = T> + '_
|
||||
where
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: Debug,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue