solution: day 4

This commit is contained in:
Matej Janezic 2023-12-04 06:42:15 +01:00
parent 000000906f
commit 0000010044
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
2 changed files with 85 additions and 0 deletions

6
data/examples/04.txt Normal file
View 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

79
src/bin/04.rs Normal file
View File

@ -0,0 +1,79 @@
use std::str::FromStr;
use aoc::parsers::to_vec;
struct ParseCardError;
struct Card {
winning: Vec<u32>,
numbers: Vec<u32>,
}
impl FromStr for Card {
type Err = ParseCardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (_, rest) = s.split_once(": ").unwrap();
let (win, my) = rest.split_once(" | ").unwrap();
let winning: Vec<u32> = to_vec(win, ' ');
let numbers: Vec<u32> = to_vec(my, ' ');
Ok(Card { winning, numbers })
}
}
impl Card {
fn n_matches(&self) -> usize {
self.numbers
.iter()
.filter(|n| self.winning.contains(n))
.count()
}
fn score(&self) -> u32 {
let c = self.n_matches();
if c == 0 {
return 0;
}
2_u32.pow((self.n_matches() - 1) as u32)
}
}
pub fn part_one(input: &str) -> Option<u32> {
Some(
input
.lines()
.filter_map(|l| l.parse::<Card>().ok())
.map(|g| g.score())
.sum(),
)
}
pub fn part_two(input: &str) -> Option<u32> {
let cards: Vec<Card> = to_vec(input, '\n');
let mut multiples = vec![1; cards.len()];
for (i, card) in cards.iter().enumerate() {
for j in 0..card.n_matches() {
multiples[i + j + 1] += multiples[i];
}
}
Some(multiples.iter().sum::<u32>())
}
aoc::solution!(4);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
assert_eq!(part_one(&aoc::template::read_file("examples", 4)), Some(13));
}
#[test]
fn test_part_two() {
assert_eq!(part_two(&aoc::template::read_file("examples", 4)), Some(30));
}
}