1
0
Fork 0

day 4 solution

main
Andrew Coleman 2023-12-05 10:59:27 -05:00
parent cf3d410dc7
commit 45481154d1
2 changed files with 114 additions and 0 deletions

113
2023/src/day04.rs Normal file
View File

@ -0,0 +1,113 @@
use aoc_runner_derive::{aoc, aoc_generator};
use std::collections::HashSet;
#[derive(Debug)]
struct Card {
id: usize,
winning: HashSet<u32>,
present: HashSet<u32>,
}
impl Card {
fn matching_numbers(&self) -> Vec<&u32> {
self.winning
.intersection(&self.present)
.collect::<Vec<&u32>>()
}
}
#[aoc_generator(day4)]
fn parse(input: &str) -> Vec<Card> {
input
.lines()
.filter_map(|line| {
if !line.is_empty() {
let cparts: Vec<&str> = line.split(": ").collect();
let id = cparts[0]
.split(" ")
.collect::<Vec<&str>>()
.last()?
.trim_start()
.parse::<usize>()
.unwrap();
let cnums: Vec<&str> = cparts[1].split(" | ").collect();
let winning: HashSet<u32> = cnums[0]
.replace(" ", " ")
.trim_start()
.split(" ")
.map(|n| n.parse::<u32>().unwrap())
.collect();
let present: HashSet<u32> = cnums[1]
.replace(" ", " ")
.trim_start()
.split(" ")
.map(|n| n.parse::<u32>().unwrap())
.collect();
Some(Card {
id,
winning,
present,
})
} else {
None
}
})
.collect()
}
#[aoc(day4, part1)]
fn part1(input: &[Card]) -> i32 {
let mut sum = 0;
let base: i32 = 2;
for c in input.iter() {
let m = c.matching_numbers();
if m.is_empty() {
continue;
}
let p = base.pow(m.len() as u32 - 1);
if m.len() > 0 {
sum += p;
}
}
sum
}
#[aoc(day4, part2)]
fn part2(input: &[Card]) -> u32 {
let mut cards: [u32; 202] = [1; 202];
for i in input.len()..cards.len() {
cards[i] = 0;
}
for c in input.iter() {
let m = c.matching_numbers();
let cur = c.id - 1;
for i in 1..=m.len() {
let dest = cur + i;
if dest >= input.len() {
continue;
}
cards[dest] += cards[cur];
}
}
cards.iter().sum()
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE_DATA: &'static str = r#"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 sample_data() {
let cards = parse(&SAMPLE_DATA);
assert_eq!(part1(&cards), 13);
assert_eq!(part2(&cards), 30);
}
}

View File

@ -3,5 +3,6 @@ use aoc_runner_derive::aoc_lib;
mod day01;
mod day02;
mod day03;
mod day04;
aoc_lib! { year = 2023 }