Files
advent-of-code-2023-rust/src/day4.rs

92 lines
2.7 KiB
Rust

use crate::day_solver::DaySolver;
pub struct Day4 {
cards: Vec<Card>
}
struct Card {
// id: u32,
winning: Vec<u32>,
having: Vec<u32>
}
impl Card {
fn win_count(&self) -> usize {
self.having.iter().filter(|n| self.winning.contains(n)).count()
}
fn score(&self) -> u32 {
let win_count = self.win_count();
if win_count == 0 { return 0 };
return 1 << (win_count - 1)
}
}
impl Day4 {
pub fn create(input: String) -> Self {
let lines = input.lines();
// let lines = util::read_file("input/dayX.txt");
// For performance reasons, let's first figure out the how many winning numbers and "having" numbers we get per card
let (_, right) = input.lines().next().unwrap().split_once(":").unwrap();
let (win_str, having_str) = right.split_once("|").unwrap();
let win_count = win_str.trim().split_whitespace().count();
let having_count = having_str.trim().split_whitespace().count();
// Put the input into the day struct
return Day4 {
cards: lines
.map(|l| {
let (_, right) = l.split_once(": ").unwrap();
let (win_str, having_str) = right.split_once("|").unwrap();
let mut winning_vec = Vec::with_capacity(win_count + 1);
winning_vec.extend(win_str.trim().split_whitespace().map(|n| n.parse::<u32>().unwrap()));
let mut having_vec = Vec::with_capacity(having_count + 1);
having_vec.extend(having_str.trim().split_whitespace().map(|n| n.parse::<u32>().unwrap()));
Card {
// id: left[5..].trim().parse().unwrap(),
winning: winning_vec,
having: having_vec
}
})
.collect()
}
}
}
impl DaySolver for Day4 {
fn solve_part1(&mut self) -> String {
return self.cards.iter().map(|c| c.score()).sum::<u32>().to_string()
}
fn solve_part2(&mut self) -> String {
let mut card_counts: Vec<u32> = vec![1; self.cards.len()];
card_counts.fill(1);
for (i, card) in self.cards.iter().enumerate() {
let copies = card_counts[i];
let win_count = card.win_count();
for j in 0..win_count {
card_counts[i + j + 1] += copies
}
}
return card_counts.iter().sum::<u32>().to_string();
}
}
#[test]
fn test_part1() {
let mut day = Day4::create("input/day04_example.txt".to_string());
assert_eq!("13", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day4::create("input/day04_example.txt".to_string());
assert_eq!("30", day.solve_part2());
}