advent_of_code_2023/src/day4/mod.rs

92 lines
3.0 KiB
Rust

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<u32> = winning.trim().split(' ').filter(|v| !v.is_empty()).map(|v| v.parse().unwrap()).collect();
let nb_card : Vec<u32> = 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<String>, part: Part) -> u32 {
let mut cards : Vec<Card> = 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<u32> = 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);
}
}