From 19604eafb2ad91b4bfc1eb3cadeb8d31976a5373 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Mon, 4 Dec 2023 10:35:34 +0100 Subject: [PATCH] day(04): add solution Signed-off-by: Matej Focko --- samples/day04.txt | 6 ++++ src/bin/day04.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 samples/day04.txt create mode 100644 src/bin/day04.rs diff --git a/samples/day04.txt b/samples/day04.txt new file mode 100644 index 0000000..9bdb874 --- /dev/null +++ b/samples/day04.txt @@ -0,0 +1,6 @@ +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 diff --git a/src/bin/day04.rs b/src/bin/day04.rs new file mode 100644 index 0000000..2bdac72 --- /dev/null +++ b/src/bin/day04.rs @@ -0,0 +1,92 @@ +use std::{collections::HashSet, str::FromStr}; + +use aoc_2023::*; + +type Output1 = i32; +type Output2 = Output1; + +struct Card { + winning: HashSet, + draw: Vec, +} + +impl FromStr for Card { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + let mut parts = s.split(':').nth(1).unwrap().split('|'); + + let winning = parts + .next() + .unwrap() + .split_ascii_whitespace() + .map(|n| n.parse().unwrap()) + .collect(); + let draw = parts + .next() + .unwrap() + .split_ascii_whitespace() + .map(|n| n.parse().unwrap()) + .collect(); + + Ok(Card { winning, draw }) + } +} + +impl Card { + fn matching(&self) -> usize { + self.draw + .iter() + .filter(|card| self.winning.contains(card)) + .count() + } + + fn score(&self) -> i32 { + let mut matched = 0; + + for card in &self.draw { + if self.winning.contains(card) { + matched += 1; + } + } + + if matched > 1 { + 1 << (matched - 1) + } else { + matched + } + } +} + +struct Day04 { + cards: Vec, +} +impl Solution for Day04 { + fn new>(pathname: P) -> Self { + let cards = file_to_structs(pathname); + + Self { cards } + } + + fn part_1(&mut self) -> Output1 { + self.cards.iter().map(Card::score).sum() + } + + fn part_2(&mut self) -> Output2 { + let mut counts = vec![1; self.cards.len()]; + + for (i, card) in self.cards.iter().enumerate() { + for j in 1..=card.matching() { + counts[i + j] += counts[i]; + } + } + + counts.iter().sum() + } +} + +fn main() -> Result<()> { + Day04::main() +} + +test_sample!(day_04, Day04, 13, 30);