diff --git a/src/day4/mod.rs b/src/day4/mod.rs index a26f736..7a83dc3 100644 --- a/src/day4/mod.rs +++ b/src/day4/mod.rs @@ -1,12 +1,28 @@ use std::{collections::HashSet, path::Path, str::FromStr}; +use itertools::Itertools; + use crate::input::{AdventError, read_into_vec}; impl FromStr for ScratchGame { type Err = AdventError; fn from_str(s: &str) -> Result { - todo!() + let split = s.split(':').collect_vec(); + let id = split[0].split_whitespace().collect_tuple::<(&str, &str)>().ok_or(AdventError("Game Id not found.".into()))?.1.parse::()?; + let split = split[1].split('|').collect_vec(); + let my_numbers: HashSet = split[0].trim().split_whitespace().map(|x| { + x.parse::() + }).collect::, _>>()?; + let winning_numbers: HashSet = split[1].trim().split_whitespace().map(|x| -> Result { + x.parse::().map_err(Into::into) + }).collect::, _>>()?; + + Ok(ScratchGame { + id, + my_numbers, + winning_numbers + }) } } @@ -17,10 +33,33 @@ struct ScratchGame { } pub fn one() -> Result { - let games = read_into_vec::(Path::new("resources/input4.txt")); - Ok(0) + let games = read_into_vec::(Path::new("resources/input4.txt"))?; + Ok(games.into_iter().fold(Ok(0), |acc: Result, game: ScratchGame| { + let acc = acc?; + let my_winning_numbers = game.my_numbers.intersection(&game.winning_numbers); + Ok(acc + match my_winning_numbers.count() { + 0 => 0, + x => (2 as u64).pow((x-1).try_into()?) + }) + })? as u32) } pub fn two() -> Result { - Ok(0) + let games = read_into_vec::(Path::new("resources/input4.txt"))?; + let mut vec = Vec::::new(); + vec.resize(games.len(), 1); + + for game in games.into_iter() { + let my_winning_numbers = game.my_numbers.intersection(&game.winning_numbers); + let nr_free_tickets = my_winning_numbers.count() as i32; + + for index in game.id..(game.id + nr_free_tickets ) { + let nr_to_count = vec[(game.id - 1) as usize]; + for _ in 0..nr_to_count { + vec[index as usize] += 1; + } + } + } + + Ok(vec.iter().sum()) } \ No newline at end of file diff --git a/src/input/mod.rs b/src/input/mod.rs index 157a5d0..31a9a07 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,4 +1,4 @@ -use std::{io::{BufReader, BufRead, self}, fs::File, str::FromStr, path::Path, convert::Infallible, num::ParseIntError}; +use std::{io::{BufReader, BufRead, self}, fs::File, str::FromStr, path::Path, convert::Infallible, num::{ParseIntError, TryFromIntError}}; #[derive(Debug)] pub struct AdventError(pub String); @@ -21,6 +21,12 @@ impl From for AdventError { } } +impl From for AdventError { + fn from(e: TryFromIntError) -> Self { + AdventError(e.to_string()) + } +} + pub fn read_into_vec(file_path : &Path) -> Result, AdventError> where AdventError: From<::Err> { let file = File::open(file_path).expect("no such file"); let buf = BufReader::new(file);