From 7c6265afecd4bc8978d4e4f23c1655a38d303369 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Wed, 6 Dec 2023 15:19:09 +0200 Subject: [PATCH] finished day 06 --- 2023/; | 90 ++++++++++++++++++++++++++++++++++++ 2023/Cargo.lock | 7 +++ 2023/day-06/Cargo.toml | 9 ++++ 2023/day-06/input1.txt | 2 + 2023/day-06/input2.txt | 2 + 2023/day-06/src/bin/part1.rs | 9 ++++ 2023/day-06/src/bin/part2.rs | 9 ++++ 2023/day-06/src/lib.rs | 2 + 2023/day-06/src/part1.rs | 89 +++++++++++++++++++++++++++++++++++ 2023/day-06/src/part2.rs | 80 ++++++++++++++++++++++++++++++++ 10 files changed, 299 insertions(+) create mode 100644 2023/; create mode 100644 2023/day-06/Cargo.toml create mode 100644 2023/day-06/input1.txt create mode 100644 2023/day-06/input2.txt create mode 100644 2023/day-06/src/bin/part1.rs create mode 100644 2023/day-06/src/bin/part2.rs create mode 100644 2023/day-06/src/lib.rs create mode 100644 2023/day-06/src/part1.rs create mode 100644 2023/day-06/src/part2.rs diff --git a/2023/; b/2023/; new file mode 100644 index 0000000..4ff0007 --- /dev/null +++ b/2023/; @@ -0,0 +1,90 @@ +use std::str::FromStr; + +use color_eyre::Result; + +#[derive(Debug, Clone)] +struct Record { + time: usize, + distance: usize, + my_distance: Vec, +} + +impl From<(usize, usize)> for Record { + fn from(value: (usize, usize)) -> Self { + let (time, distance) = value; + Self { + time, + distance, + my_distance: Vec::new(), + } + } +} + +#[derive(Debug, Clone)] +struct Records(Vec); +impl FromStr for Records { + type Err = &'static str; + fn from_str(s: &str) -> std::prelude::v1::Result { + let mut lines = s.lines(); + let time_values: Vec<_> = lines + .next() + .and_then(|line| { + line.split_whitespace() + .skip(1) + .map(|s| s.parse().ok()) + .collect() + }) + .ok_or("Invalid input format")?; + let distabce_values: Vec<_> = lines + .next() + .and_then(|line| { + line.split_whitespace() + .skip(1) + .map(|s| s.parse().ok()) + .collect() + }) + .ok_or("Invalid input format")?; + let records: Vec<_> = time_values + .into_iter() + .zip(distabce_values.into_iter()) + .map(Record::from) + .collect(); + Ok(Records(records)) + } +} + +pub fn process(input: &str) -> Result { + let mut records: Records = input.parse().expect("Error parsing input"); + records.0.iter_mut().for_each(|record| { + (0..=record.time).for_each(|time| { + let distance = time * (record.time - time); + record.my_distance.push(distance); + }) + }); + let total: usize = records + .0 + .iter() + .map(|record| { + record + .my_distance + .iter() + .filter(|&&num| num > record.distance) + .count() + }) + .product(); + dbg!(&total); + Ok(0) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_process() -> Result<()> { + let input = "Time: 7 15 30 +Distance: 9 40 200"; + assert_eq!(288, process(input)?); + Ok(()) + } +} diff --git a/2023/Cargo.lock b/2023/Cargo.lock index 8064b56..fb5c368 100644 --- a/2023/Cargo.lock +++ b/2023/Cargo.lock @@ -103,6 +103,13 @@ dependencies = [ "color-eyre", ] +[[package]] +name = "day-06" +version = "0.1.0" +dependencies = [ + "color-eyre", +] + [[package]] name = "either" version = "1.9.0" diff --git a/2023/day-06/Cargo.toml b/2023/day-06/Cargo.toml new file mode 100644 index 0000000..307fb55 --- /dev/null +++ b/2023/day-06/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day-06" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +color-eyre = { workspace = true } diff --git a/2023/day-06/input1.txt b/2023/day-06/input1.txt new file mode 100644 index 0000000..7c06e07 --- /dev/null +++ b/2023/day-06/input1.txt @@ -0,0 +1,2 @@ +Time: 59 68 82 74 +Distance: 543 1020 1664 1022 diff --git a/2023/day-06/input2.txt b/2023/day-06/input2.txt new file mode 100644 index 0000000..7c06e07 --- /dev/null +++ b/2023/day-06/input2.txt @@ -0,0 +1,2 @@ +Time: 59 68 82 74 +Distance: 543 1020 1664 1022 diff --git a/2023/day-06/src/bin/part1.rs b/2023/day-06/src/bin/part1.rs new file mode 100644 index 0000000..0f1a83d --- /dev/null +++ b/2023/day-06/src/bin/part1.rs @@ -0,0 +1,9 @@ +use color_eyre::Result; +use day_06::part1::process; + +fn main() -> Result<()> { + let file = include_str!("../../input1.txt"); + let result = process(file)?; + println!("{}", result); + Ok(()) +} diff --git a/2023/day-06/src/bin/part2.rs b/2023/day-06/src/bin/part2.rs new file mode 100644 index 0000000..23ed8e9 --- /dev/null +++ b/2023/day-06/src/bin/part2.rs @@ -0,0 +1,9 @@ +use color_eyre::Result; +use day_06::part2::process; + +fn main() -> Result<()> { + let file = include_str!("../../input2.txt"); + let result = process(file)?; + println!("{}", result); + Ok(()) +} diff --git a/2023/day-06/src/lib.rs b/2023/day-06/src/lib.rs new file mode 100644 index 0000000..faaf542 --- /dev/null +++ b/2023/day-06/src/lib.rs @@ -0,0 +1,2 @@ +pub mod part1; +pub mod part2; diff --git a/2023/day-06/src/part1.rs b/2023/day-06/src/part1.rs new file mode 100644 index 0000000..bb4a12e --- /dev/null +++ b/2023/day-06/src/part1.rs @@ -0,0 +1,89 @@ +use std::str::FromStr; + +use color_eyre::Result; + +#[derive(Debug, Clone)] +struct Record { + time: usize, + distance: usize, + my_distance: Vec, +} + +impl From<(usize, usize)> for Record { + fn from(value: (usize, usize)) -> Self { + let (time, distance) = value; + Self { + time, + distance, + my_distance: Vec::new(), + } + } +} + +#[derive(Debug, Clone)] +struct Records(Vec); +impl FromStr for Records { + type Err = &'static str; + fn from_str(s: &str) -> std::prelude::v1::Result { + let mut lines = s.lines(); + let time_values: Vec<_> = lines + .next() + .and_then(|line| { + line.split_whitespace() + .skip(1) + .map(|s| s.parse().ok()) + .collect() + }) + .ok_or("Invalid input format")?; + let distabce_values: Vec<_> = lines + .next() + .and_then(|line| { + line.split_whitespace() + .skip(1) + .map(|s| s.parse().ok()) + .collect() + }) + .ok_or("Invalid input format")?; + let records: Vec<_> = time_values + .into_iter() + .zip(distabce_values.into_iter()) + .map(Record::from) + .collect(); + Ok(Records(records)) + } +} + +pub fn process(input: &str) -> Result { + let mut records: Records = input.parse().expect("Error parsing input"); + records.0.iter_mut().for_each(|record| { + (0..=record.time).for_each(|time| { + let distance = time * (record.time - time); + record.my_distance.push(distance); + }) + }); + let total: usize = records + .0 + .iter() + .map(|record| { + record + .my_distance + .iter() + .filter(|&&num| num > record.distance) + .count() + }) + .product(); + Ok(total) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_process() -> Result<()> { + let input = "Time: 7 15 30 +Distance: 9 40 200"; + assert_eq!(288, process(input)?); + Ok(()) + } +} diff --git a/2023/day-06/src/part2.rs b/2023/day-06/src/part2.rs new file mode 100644 index 0000000..8e66e87 --- /dev/null +++ b/2023/day-06/src/part2.rs @@ -0,0 +1,80 @@ +use std::str::FromStr; + +use color_eyre::Result; + +#[derive(Debug, Clone)] +struct Record { + time: usize, + distance: usize, + my_distance: Vec, +} + +impl From<(usize, usize)> for Record { + fn from(value: (usize, usize)) -> Self { + let (time, distance) = value; + Self { + time, + distance, + my_distance: Vec::new(), + } + } +} + +impl FromStr for Record { + type Err = &'static str; + fn from_str(s: &str) -> std::prelude::v1::Result { + let mut lines = s.lines(); + let time_line = lines.next().ok_or("Invalid input format")?; + let time = time_line + .split_whitespace() + .skip(1) + .collect::() + .parse::() + .map_err(|_| "Failed to parse distance")?; + + let distance_line = lines.next().ok_or("Invalid input format")?; + let distance = distance_line + .split_whitespace() + .skip(1) + .collect::() + .parse::() + .map_err(|_| "Failed to parse distance")?; + + Ok(Record { + time, + distance, + my_distance: Vec::new(), + }) + } +} + +pub fn process(input: &str) -> Result { + let mut record: Record = input.parse().expect("Error parsing input"); + dbg!(&record); + + (0..=record.time).for_each(|time| { + let distance = time * (record.time - time); + record.my_distance.push(distance); + }); + + let total = record + .my_distance + .iter() + .filter(|&&num| num > record.distance); + + Ok(total.count()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_process() -> Result<()> { + let input = "Time: 7 15 30 +Distance: 9 40 200 +"; + assert_eq!(71503, process(input)?); + Ok(()) + } +}