use std::collections::VecDeque; use log::debug; use super::utils::Part; struct Card { nb_winning: u32, value: u32, count: u32 } fn parse(line: &str) -> Card { debug!("Processing {}", line); let (_, values) = line.split_once(':').unwrap(); let (winning, numbers) = values.split_once('|').unwrap(); let nb_win : Vec = winning.trim().split(' ').filter(|v| !v.is_empty()).map(|v| v.parse().unwrap()).collect(); let nb_card : Vec = numbers.trim().split(' ').filter(|v| !v.is_empty()).map(|v| v.parse().unwrap()).collect(); debug!("{:?}", nb_win); debug!("{:?}", nb_card); let mut value = 0; let mut winner_nb = 0; for nb in nb_card { if nb_win.contains(&nb) { winner_nb += 1; if value == 0 { value = 1; }else{ value *= 2; } } } Card { nb_winning: winner_nb, value, count: 1 } } pub fn solve(lines: Vec, part: Part) -> u32 { let mut cards : Vec = lines.iter().map(|l| parse(l)).collect(); match part { Part::One => cards.iter().map(|c| c.value).sum(), Part::Two => { let mut next_adds : VecDeque = VecDeque::new(); let mut counter = 0; for card in &mut cards { counter += 1; debug!("Card {}: Adding {} next cards", counter, card.nb_winning); if let Some(bonus) = next_adds.pop_front(){ // If there is a value, we add it to the current card card.count += bonus; debug!("Current card count is {}", card.count); } for i in 0..(card.nb_winning) { // For each value our current card has we add all those on the stack if let Some(value) = next_adds.get_mut(i as usize){ *value += card.count; }else{ next_adds.push_back(card.count); } } debug!("Next bonus: {:?}", next_adds); } cards.iter().map(|c| c.count).sum() } } } #[cfg(test)] mod tests { use super::{parse, solve}; #[test] fn test_line() { let line = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53".to_owned(); let card = parse(&line); assert_eq!(card.value, 8); } #[test] fn test_part2(){ let lines = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53\nCard 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\nCard 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1\nCard 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83\nCard 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\nCard 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11".to_owned(); let result =solve(lines.lines().map(|v| v.to_owned()).collect(), crate::utils::Part::Two); assert_eq!(result, 30); } }