day(04): add solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
45b6f64a3e
commit
19604eafb2
2 changed files with 98 additions and 0 deletions
6
samples/day04.txt
Normal file
6
samples/day04.txt
Normal file
|
@ -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
|
92
src/bin/day04.rs
Normal file
92
src/bin/day04.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use std::{collections::HashSet, str::FromStr};
|
||||||
|
|
||||||
|
use aoc_2023::*;
|
||||||
|
|
||||||
|
type Output1 = i32;
|
||||||
|
type Output2 = Output1;
|
||||||
|
|
||||||
|
struct Card {
|
||||||
|
winning: HashSet<i32>,
|
||||||
|
draw: Vec<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Card {
|
||||||
|
type Err = &'static str;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
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<Card>,
|
||||||
|
}
|
||||||
|
impl Solution<Output1, Output2> for Day04 {
|
||||||
|
fn new<P: AsRef<Path>>(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);
|
Loading…
Reference in a new issue