day-6 done

This commit is contained in:
Dylan Thies
2023-12-06 23:32:34 -05:00
parent e21503ed71
commit c75de28690
5 changed files with 158 additions and 0 deletions

4
2023/day-6/src/lib.rs Normal file
View File

@@ -0,0 +1,4 @@
pub mod part1;
pub use crate::part1::*;
pub mod part2;
pub use crate::part2::*;

12
2023/day-6/src/main.rs Normal file
View File

@@ -0,0 +1,12 @@
#![warn(clippy::all, clippy::pedantic)]
use day_6::part1;
use day_6::part2;
fn main() {
let input = include_str!("./input.txt");
let part1_result = part1(input);
println!("part 1: {part1_result}");
let part2_result = part2(input);
println!("part 2: {part2_result}");
}

65
2023/day-6/src/part1.rs Normal file
View File

@@ -0,0 +1,65 @@
#![warn(clippy::all, clippy::pedantic)]
use itertools::Itertools;
use nom::{
bytes::complete::tag,
character::complete,
multi::separated_list1,
sequence::{pair, preceded},
IResult,
};
#[must_use]
pub fn part1(input: &str) -> String {
let (_, races) = parse_input(input).expect("input expected");
races
.iter()
.map(|(time, distance)| {
(0..=*time)
.filter_map(|x| {
if (time - x) * x > *distance {
Some(())
} else {
None
}
})
.count()
})
.product::<usize>()
.to_string()
}
fn parse_input(input: &str) -> IResult<&str, Vec<(u64, u64)>> {
let (input, time) = preceded(
pair(tag("Time:"), complete::space1),
separated_list1(complete::space1, complete::u64),
)(input)?;
let (input, _) = complete::line_ending(input)?;
let (input, distance) = preceded(
pair(tag("Distance:"), complete::space1),
separated_list1(complete::space1, complete::u64),
)(input)?;
Ok((
input,
time.iter()
.interleave(distance.iter())
.map(|x| *x)
.tuples()
.collect(),
))
}
#[cfg(test)]
mod test {
use super::*;
const INPUT: &str = "Time: 7 15 30
Distance: 9 40 200";
#[test]
fn part1_works() {
let result = part1(INPUT);
assert_eq!(result, "288".to_string());
}
}

65
2023/day-6/src/part2.rs Normal file
View File

@@ -0,0 +1,65 @@
#![warn(clippy::all, clippy::pedantic)]
use itertools::Itertools;
use nom::{
bytes::complete::tag,
character::complete,
multi::separated_list1,
sequence::{pair, preceded},
IResult,
};
#[must_use]
pub fn part2(input: &str) -> String {
let (_, race) = parse_input(input).expect("input expected");
(0..=race.0)
.filter_map(|x| {
if (race.0 - x) * x > race.1 {
Some(())
} else {
None
}
})
.count()
.to_string()
}
fn parse_input(input: &str) -> IResult<&str, (u64, u64)> {
let (input, time) = preceded(
pair(tag("Time:"), complete::space1),
separated_list1(complete::space1, complete::u64),
)(input)?;
let (input, _) = complete::line_ending(input)?;
let (input, distance) = preceded(
pair(tag("Distance:"), complete::space1),
separated_list1(complete::space1, complete::u64),
)(input)?;
let distance = distance
.iter()
.map(|x| x.to_string())
.join("")
.parse::<u64>()
.expect("is a number");
let time = time
.iter()
.map(|x| x.to_string())
.join("")
.parse::<u64>()
.expect("is a number");
Ok((input, (time, distance)))
}
#[cfg(test)]
mod test {
use super::*;
const INPUT: &str = "Time: 7 15 30
Distance: 9 40 200";
#[test]
fn part2_works() {
let result = part2(INPUT);
assert_eq!(result, "71503".to_string());
}
}