diff --git a/src/bin/day4.rs b/src/bin/day4.rs index 214307c..66c8d7e 100644 --- a/src/bin/day4.rs +++ b/src/bin/day4.rs @@ -1,20 +1,15 @@ use aoc23::prelude::*; use itertools::Itertools; use std::{ - collections::{ - HashMap, - VecDeque, - }, + collections::{HashMap, VecDeque}, str::FromStr, }; #[derive(Debug)] struct Card { id: usize, - winning_numbers: Vec, - numbers: Vec, - matches: usize, - score: usize, + part_2_matches: usize, + part_1_score: usize, } impl FromStr for Card { @@ -23,61 +18,66 @@ impl FromStr for Card { fn from_str(s: &str) -> std::result::Result { let mut id: Option = None; let mut winning_numbers: Vec = vec![]; - let mut numbers: Vec = vec![]; let mut score = 0; let mut matches = 0; for part in s.split(':') { if id.is_some() { for (num_mode, wins_or_nums) in part.split('|').enumerate() { - wins_or_nums.trim().split_whitespace().into_iter().map(|num| { - num.parse::().expect(&format!("could not parse number: {}", num)) - }).for_each(|num| { - if num_mode == 0 { - winning_numbers.push(num); - } else { - numbers.push(num); - if winning_numbers.iter().any(|winner| winner == &num) { - matches += 1; - score = if score == 0 { - 1 - } else { - score * 2 - }; + wins_or_nums + .trim() + .split_whitespace() + .into_iter() + .map(|num| { + num.parse::() + .expect(&format!("could not parse number: {}", num)) + }) + .for_each(|num| { + if num_mode == 0 { + winning_numbers.push(num); + } else { + if winning_numbers.iter().any(|winner| winner == &num) { + matches += 1; + score = if score == 0 { 1 } else { score * 2 }; + } } - } - }); + }); } } else { - id = Some(part.split_whitespace().last().ok_or("Failed to get last item")?.parse()?) + id = Some( + part.split_whitespace() + .last() + .ok_or("Failed to get last item")? + .parse()?, + ) } } Ok(Card { id: id.ok_or("no id found")?, - winning_numbers, - numbers, - score, - matches, + part_1_score: score, + part_2_matches: matches, }) } } fn part1(input: String) -> Result { - Ok( - input - .lines() - .map(|line| line.parse::()) - .filter_map(|card| card.ok()) - .fold(0, |sum, card| sum + card.score), - ) + Ok(input + .lines() + .map(|line| line.parse::()) + .filter_map(|card| card.ok()) + .fold(0, |sum, card| sum + card.part_1_score)) } fn part2(input: String) -> Result { let mut sum = 0; - let cards = input.lines().map(|line| line.parse::()).filter_map(|card| card.ok()).collect_vec(); + let cards = input + .lines() + .map(|line| line.parse::()) + .filter_map(|card| card.ok()) + .collect_vec(); let mut queue: VecDeque<&Card> = cards.iter().collect(); while let Some(card) = queue.pop_front() { sum += 1; - for card_index in card.id .. card.id + card.matches { + for card_index in card.id..card.id + card.part_2_matches { cards.get(card_index).map(|c| queue.push_back(&c)); } }