day-9 done and clippied

This commit is contained in:
Dylan Thies
2023-12-09 10:27:54 -05:00
parent 78e50d8c82
commit 91d7d7ced5
6 changed files with 106 additions and 10 deletions

9
2023/Cargo.lock generated
View File

@@ -102,6 +102,15 @@ dependencies = [
"rstest", "rstest",
] ]
[[package]]
name = "day-9"
version = "2023.0.0"
dependencies = [
"itertools",
"nom",
"rstest",
]
[[package]] [[package]]
name = "derive-getters" name = "derive-getters"
version = "0.3.0" version = "0.3.0"

View File

@@ -31,7 +31,7 @@ impl Branches {
} }
} }
/// day 4 part 1 of aoc 2023 /// day 8 part 1 of aoc 2023
/// ///
/// # Arguments /// # Arguments
/// - input the input for today's puzzle /// - input the input for today's puzzle

View File

@@ -30,7 +30,7 @@ impl Branches {
} }
} }
/// day 4 part 1 of aoc 2023 /// day 8 part 2 of aoc 2023
/// ///
/// # Arguments /// # Arguments
/// - input the input for today's puzzle /// - input the input for today's puzzle

View File

@@ -10,3 +10,4 @@ repository.workspace = true
[dependencies] [dependencies]
nom.workspace = true nom.workspace = true
itertools.workspace = true itertools.workspace = true
rstest = {workspace = true}

View File

@@ -1,20 +1,62 @@
#![warn(clippy::all, clippy::pedantic)] #![warn(clippy::all, clippy::pedantic)]
use nom::{character::complete, multi::separated_list1, IResult};
use std::{iter::successors, ops::Not};
/// day 9 part 1 of aoc 2023
///
/// # Arguments
/// - input the input for today's puzzle
///
/// # Panics
/// panics whne it cannot parse the input OR when ever the number of game numbers is greater than
/// usize
#[must_use] #[must_use]
pub fn part1 (_input: &str) -> String { pub fn part1(input: &str) -> String {
"Not Finished".to_string() let (_, report) = parse_input(input).expect("should have valid input for aoc");
report.iter().map(|x| get_next(x)).sum::<i64>().to_string()
}
fn get_next(array: &[i64]) -> i64 {
let array = Vec::from(array);
successors(Some(array), |a| {
a.iter()
.all(|x| x == &0)
.not()
.then_some(a.windows(2).map(|a| a[1] - a[0]).collect::<Vec<_>>())
})
.map(|x| *x.last().unwrap())
.sum()
}
fn parse_input(input: &str) -> IResult<&str, Vec<Vec<i64>>> {
separated_list1(
complete::line_ending,
separated_list1(complete::space1, complete::i64),
)(input)
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use rstest::rstest;
const INPUT: &str = ""; #[rstest]
#[case(vec![0,3,6,9,12,15], 18)]
#[case(vec![1,3,6,10,15,21], 28)]
#[case(vec![10,13,16,21,30,45], 68)]
fn part1_next(#[case] array: Vec<i64>, #[case] expected: i64) {
assert_eq!(get_next(&array), expected);
}
const INPUT: &str = "0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45";
#[test] #[test]
fn part1_works() { fn part1_works() {
let result = part1(INPUT); let result = part1(INPUT);
assert_eq!(result, "Not Finished".to_string()); assert_eq!(result, "114".to_string());
} }
} }

View File

@@ -1,20 +1,64 @@
#![warn(clippy::all, clippy::pedantic)] #![warn(clippy::all, clippy::pedantic)]
use nom::{character::complete, multi::separated_list1, IResult};
use std::{iter::successors, ops::Not};
/// day 9 part 2 of aoc 2023
///
/// # Arguments
/// - input the input for today's puzzle
///
/// # Panics
/// panics whne it cannot parse the input OR when ever the number of game numbers is greater than
/// usize
#[must_use] #[must_use]
pub fn part2 (_input: &str) -> String { pub fn part2(input: &str) -> String {
"Not Finished".to_string() let (_, report) = parse_input(input).expect("should have valid input for aoc");
report.iter().map(|x| get_next(x)).sum::<i64>().to_string()
}
fn get_next(array: &[i64]) -> i64 {
let array = Vec::from(array);
let mut a = successors(Some(array.clone()), |a| {
a.iter()
.all(|x| x == &0)
.not()
.then_some(a.windows(2).map(|a| a[1] - a[0]).collect::<Vec<_>>())
})
.map(|x| *x.first().unwrap())
.collect::<Vec<_>>();
a.reverse();
a.iter().fold(0, |acc, x| x - acc)
}
fn parse_input(input: &str) -> IResult<&str, Vec<Vec<i64>>> {
separated_list1(
complete::line_ending,
separated_list1(complete::space1, complete::i64),
)(input)
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use rstest::rstest;
const INPUT: &str = ""; #[rstest]
#[case(vec![0,3,6,9,12,15], -3)]
#[case(vec![1,3,6,10,15,21], 0)]
#[case(vec![10,13,16,21,30,45], 5)]
fn part2_next(#[case] array: Vec<i64>, #[case] expected: i64) {
assert_eq!(get_next(&array), expected);
}
const INPUT: &str = "0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45";
#[test] #[test]
fn part2_works() { fn part2_works() {
let result = part2(INPUT); let result = part2(INPUT);
assert_eq!(result, "Not Finished".to_string()); assert_eq!(result, "2".to_string());
} }
} }