Skip to content

Commit

Permalink
2023: Day 4
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 4, 2023
1 parent 407855c commit 996e730
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Thank you to [Eric Wastl](http://was.tl) for running this incredible yearly even
- [Day 01: Trebuchet?!](aoc_2023/src/day_01.rs)
- [Day 02: Cube Conundrum](aoc_2023/src/day_02.rs)
- [Day 03: Gear Ratios](aoc_2023/src/day_03.rs)
- [Day 04: Scratchcards](aoc_2023/src/day_04.rs)

## [2022](https://adventofcode.com/2022) [![aoc_2022](https://github.com/Basicprogrammer10/advent-of-code/actions/workflows/aoc_2022.yml/badge.svg)](https://github.com/Basicprogrammer10/advent-of-code/actions/workflows/aoc_2022.yml)

Expand Down
101 changes: 101 additions & 0 deletions aoc_2023/src/day_04.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use common::{Answer, Solution};

pub struct Day04;

impl Solution for Day04 {
fn name(&self) -> &'static str {
"Scratchcards"
}

fn part_a(&self, input: &str) -> Answer {
let cards = parse(input);
cards
.iter()
.map(|x| x.count_wins())
.filter(|x| *x > 0)
.map(|x| 2u32.pow(x.saturating_sub(1) as u32))
.sum::<u32>()
.into()
}

fn part_b(&self, input: &str) -> Answer {
let cards = parse(input);

let mut queue = cards.clone();
let mut visited = 0;

while let Some(card) = queue.pop() {
let wins = card.count_wins();
visited += 1;
if wins == 0 {
continue;
}

let num = card.number as usize;
for i in num + 1..=num + wins {
queue.push(cards[i as usize - 1].clone());
}
}

visited.into()
}
}

#[derive(Clone)]
struct Card {
number: u8,
winning: Vec<u8>,
scratch: Vec<u8>,
}

fn parse(input: &str) -> Vec<Card> {
let mut cards = Vec::new();
for line in input.lines() {
let (_, line) = line.split_once(": ").unwrap();
let (winning, scratch) = line.split_once(" | ").unwrap();
let parse = |s: &str| s.split_whitespace().map(|x| x.parse().unwrap()).collect();
cards.push(Card {
number: cards.len() as u8 + 1,
winning: parse(winning),
scratch: parse(scratch),
});
}

cards
}

impl Card {
fn count_wins(&self) -> usize {
self.scratch
.iter()
.filter(|x| self.winning.contains(x))
.count()
}
}

#[cfg(test)]
mod test {
use common::Solution;
use indoc::indoc;

use super::Day04;

const CASE: &str = indoc! {"
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
"};

#[test]
fn part_a() {
assert_eq!(Day04.part_a(CASE), 13.into());
}

#[test]
fn part_b() {
assert_eq!(Day04.part_b(CASE), 30.into());
}
}
2 changes: 2 additions & 0 deletions aoc_2023/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ mod aoc_lib;
mod day_01;
mod day_02;
mod day_03;
mod day_04;
// [import_marker]

#[rustfmt::skip]
pub const ALL: &[&dyn Solution] = &[
&day_01::Day01,
&day_02::Day02,
&day_03::Day03,
&day_04::Day04,
// [list_marker]
];
Loading

0 comments on commit 996e730

Please sign in to comment.