Skip to content

Commit

Permalink
day 6 cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
madser123 committed Jul 18, 2024
1 parent c557eb0 commit 997111c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 32 deletions.
4 changes: 2 additions & 2 deletions bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ fn day5(input: String) {
}

fn day6(input: String) {
let races = Races::from_multiple_races(&input).expect("Failed to parse races");
let races = Races::from_str(&input).expect("Failed to parse races");
let winning_product = races.get_winning_product();
println!("Winning product for multiple races: {winning_product}");

let race = Races::from_single_race(&input).expect("Failed to parse race");
let race = races.as_single_race().expect("Failed to parse race");
let winning_product = race.get_winning_product();
println!("Winning product for single race: {winning_product}");
}
Expand Down
64 changes: 34 additions & 30 deletions lib/boat_race/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use std::num::ParseIntError;
use std::{num::ParseIntError, str::FromStr};

#[derive(Debug)]
pub enum ParseRaceError {
ParseInt(ParseIntError),
Invalid(String),
}

impl From<ParseIntError> for ParseRaceError {
fn from(value: ParseIntError) -> Self {
Self::ParseInt(value)
}
}

pub struct Race {
time: u64,
distance: u64,
Expand Down Expand Up @@ -65,42 +71,21 @@ pub struct Races {
races: Vec<Race>,
}

impl Races {
pub fn get_winning_product(&self) -> u64 {
self.races.iter().map(Race::find_winning_conditions_amount).product()
}
impl FromStr for Races {
type Err = ParseRaceError;

pub fn from_single_race(races: &str) -> Result<Self, ParseRaceError> {
let numbers = races
.lines()
.map(|line| {
line.split(':')
.last()
.ok_or_else(|| ParseRaceError::Invalid("Failed to get numbers".to_string()))?
.split_ascii_whitespace()
.collect::<String>()
.parse::<u64>()
.map_err(ParseRaceError::ParseInt)
})
.collect::<Result<Vec<u64>, ParseRaceError>>()?;

let races = vec![Race::new(numbers[0], numbers[1])];

Ok(Self { races })
}

pub fn from_multiple_races(races: &str) -> Result<Self, ParseRaceError> {
let numbers = races
fn from_str(s: &str) -> Result<Self, Self::Err> {
let numbers = s
.lines()
.map(|line| {
line.split(':')
.last()
.ok_or_else(|| ParseRaceError::Invalid("Failed to get numbers".to_string()))?
.split_ascii_whitespace()
.map(|n| n.parse::<u64>().map_err(ParseRaceError::ParseInt))
.collect::<Result<Vec<u64>, ParseRaceError>>()
.collect::<Result<Vec<u64>, _>>()
})
.collect::<Result<Vec<Vec<u64>>, ParseRaceError>>()?;
.collect::<Result<Vec<Vec<u64>>, _>>()?;

let races = numbers[0]
.iter()
Expand All @@ -112,6 +97,25 @@ impl Races {
}
}

impl Races {
pub fn get_winning_product(&self) -> u64 {
self.races.iter().map(Race::find_winning_conditions_amount).product()
}

pub fn as_single_race(self) -> Result<Self, ParseRaceError> {
let (time, distance) = self
.races
.into_iter()
.fold((String::new(), String::new()), |(time, distance), race| {
(time + &race.time.to_string(), distance + &race.distance.to_string())
});

let race = Race::new(time.parse()?, distance.parse()?);

Ok(Self { races: vec![race] })
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -121,15 +125,15 @@ Distance: 9 40 200";

#[test]
fn solution_1() {
let product = Races::from_multiple_races(EXAMPLE)
let product = Races::from_str(EXAMPLE)
.expect("Failed to parse races")
.get_winning_product();
assert_eq!(product, 288)
}

#[test]
fn solution_2() {
let product = Races::from_single_race(EXAMPLE)
let product = Races::from_str(EXAMPLE)
.expect("Failed to parse race")
.get_winning_product();
assert_eq!(product, 71503);
Expand Down

0 comments on commit 997111c

Please sign in to comment.