65 lines
1.3 KiB
Rust
65 lines
1.3 KiB
Rust
|
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
||
|
|
||
|
use aoc23::read;
|
||
|
use chumsky::{prelude::*, text::int};
|
||
|
use std::collections::HashSet;
|
||
|
|
||
|
struct Card {
|
||
|
id: usize,
|
||
|
winning_nums: HashSet<usize>,
|
||
|
nums: HashSet<usize>
|
||
|
}
|
||
|
|
||
|
impl Card {
|
||
|
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||
|
let nums = just(" ")
|
||
|
.repeated()
|
||
|
.ignore_then(int(10))
|
||
|
.separated_by(just(" "))
|
||
|
.map(|nums| {
|
||
|
nums.into_iter()
|
||
|
.map(|num: String| num.parse().unwrap())
|
||
|
.collect::<HashSet<usize>>()
|
||
|
});
|
||
|
|
||
|
just("Card")
|
||
|
.ignore_then(just(" ").repeated())
|
||
|
.ignore_then(int(10))
|
||
|
.then_ignore(just(": "))
|
||
|
.then(nums)
|
||
|
.then_ignore(just(" | "))
|
||
|
.then(nums)
|
||
|
.map(|((id, winning_nums), nums): ((String, _), _)| Self {
|
||
|
id: id.parse().unwrap(),
|
||
|
winning_nums,
|
||
|
nums
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn parser() -> impl Parser<char, Vec<Card>, Error = Simple<char>> {
|
||
|
Card::parser()
|
||
|
.then_ignore(just("\n"))
|
||
|
.repeated()
|
||
|
.then_ignore(end())
|
||
|
}
|
||
|
|
||
|
fn main() -> anyhow::Result<()> {
|
||
|
let cards = read("inputs/day4.txt", parser())?;
|
||
|
|
||
|
let mut points = 0;
|
||
|
for card in &cards {
|
||
|
let matches = card
|
||
|
.nums
|
||
|
.iter()
|
||
|
.filter(|num| card.winning_nums.contains(num))
|
||
|
.count();
|
||
|
if matches > 0 {
|
||
|
points += 1 << (matches - 1);
|
||
|
}
|
||
|
}
|
||
|
println!("{points}");
|
||
|
|
||
|
Ok(())
|
||
|
}
|