diff --git a/2023/rust/src/day4.rs b/2023/rust/src/day4.rs new file mode 100644 index 0000000..0444667 --- /dev/null +++ b/2023/rust/src/day4.rs @@ -0,0 +1,83 @@ +mod prelude; +extern crate nom; +use nom::{ + branch::alt, + bytes::complete::{tag, take_while}, + character::complete::space1, + combinator::{map_res, value}, + multi::separated_list0, + sequence::tuple, + IResult, +}; +use std::{collections::HashSet, iter::FromIterator}; + +use crate::prelude::*; + +fn main() { + Day4::show(day_input(4), day_input(4)) +} + +#[derive(Debug)] +struct Card { + id: usize, + winning: HashSet, + has: Vec, +} + +impl Card { + fn points(&self) -> usize { + let num_winning = self.has.iter().filter(|n| self.winning.contains(n)).count() as u32; + println!("{self:?} num_winning -> {num_winning}"); + if num_winning >= 1 { + 2_u64.pow(num_winning - 1) as usize + } else { + 0 + } + } +} + +// parser +fn int(input: &str) -> IResult<&str, usize> { + map_res(take_while(char::is_numeric), str::parse)(input) +} + +fn card(input: &str) -> IResult<&str, Card> { + let (input, id) = int(tuple((tag("Card"), space1))(input)?.0)?; + let (input, winning_list) = separated_list0(space1, int)(tuple((tag(":"), space1))(input)?.0)?; + let (input, has) = separated_list0(space1, int)(tuple((space1, tag("|"), space1))(input)?.0)?; + let winning = HashSet::from_iter(winning_list); + Ok((input, Card { id, winning, has })) +} + +struct Day4 {} +impl Day4 {} +impl AoCSolution for Day4 { + type Input = String; + type Solution = usize; + + fn part1(input: Self::Input) -> Self::Solution { + input.lines().map(|s| card(s).unwrap().1.points()).sum() + } + + fn part2(input: Self::Input) -> Self::Solution { + 0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + let input = r#"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 +Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 +Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 +Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 +Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 +Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"#; + println!("input:\n{input}"); + assert_eq!(Day4::part1(input.into()), 13); + assert_eq!(Day4::part2(input.into()), 0); + } +}