day 4 part 2
This commit is contained in:
parent
d618c30f3d
commit
4b0072f574
1 changed files with 43 additions and 18 deletions
|
@ -2,16 +2,15 @@
|
|||
|
||||
use aoc23::read;
|
||||
use chumsky::{prelude::*, text::int};
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
struct Card {
|
||||
id: usize,
|
||||
winning_nums: HashSet<usize>,
|
||||
nums: HashSet<usize>
|
||||
}
|
||||
|
||||
impl Card {
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
fn parser() -> impl Parser<char, (usize, Self), Error = Simple<char>> {
|
||||
let nums = just(" ")
|
||||
.repeated()
|
||||
.ignore_then(int(10))
|
||||
|
@ -29,36 +28,62 @@ impl Card {
|
|||
.then(nums)
|
||||
.then_ignore(just(" | "))
|
||||
.then(nums)
|
||||
.map(|((id, winning_nums), nums): ((String, _), _)| Self {
|
||||
id: id.parse().unwrap(),
|
||||
winning_nums,
|
||||
nums
|
||||
.map(|((id, winning_nums), nums): ((String, _), _)| {
|
||||
(id.parse().unwrap(), Self { winning_nums, nums })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn parser() -> impl Parser<char, Vec<Card>, Error = Simple<char>> {
|
||||
fn parser() -> impl Parser<char, BTreeMap<usize, Card>, Error = Simple<char>> {
|
||||
Card::parser()
|
||||
.then_ignore(just("\n"))
|
||||
.repeated()
|
||||
.map(|cards| cards.into_iter().collect())
|
||||
.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);
|
||||
let matches = cards
|
||||
.iter()
|
||||
.map(|(id, card)| {
|
||||
(
|
||||
*id,
|
||||
card.nums
|
||||
.iter()
|
||||
.filter(|num| card.winning_nums.contains(num))
|
||||
.count()
|
||||
)
|
||||
})
|
||||
.collect::<BTreeMap<usize, usize>>();
|
||||
|
||||
// part 1
|
||||
println!(
|
||||
"{}",
|
||||
matches
|
||||
.values()
|
||||
.map(|count| match count {
|
||||
0 => 0,
|
||||
_ => 1 << (count - 1)
|
||||
})
|
||||
.sum::<usize>()
|
||||
);
|
||||
|
||||
// part 2
|
||||
let mut copies = cards
|
||||
.keys()
|
||||
.map(|key| (*key, 1))
|
||||
.collect::<BTreeMap<usize, usize>>();
|
||||
for id in cards.keys() {
|
||||
let num_copies = copies[id];
|
||||
for next in id + 1 ..= id + matches[id] {
|
||||
if let Some(next_copies) = copies.get_mut(&next) {
|
||||
*next_copies += num_copies;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{points}");
|
||||
println!("{}", copies.values().sum::<usize>());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue