Skip to content

Instantly share code, notes, and snippets.

@typester
Created December 5, 2023 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typester/c7099571facac2874bfb0f1604507c90 to your computer and use it in GitHub Desktop.
Save typester/c7099571facac2874bfb0f1604507c90 to your computer and use it in GitHub Desktop.
2023 Advent of Code Day 4
use std::collections::HashMap;
use lazy_static::lazy_static;
use regex::Regex;
const INPUT: &str = "..snip..";
fn main() {
let sum: u32 = INPUT.lines()
.map(parse_game)
.map(|card| {
let mut point = 0;
for wining_num in card.wining_numbers.iter() {
if let Some(_) = card.my_numbers.iter().find(|n| *n == wining_num) {
if point == 0 {
point = 1;
} else {
point *= 2;
}
}
}
point
}).sum();
println!("part1: {}", sum);
let mut sum: u32 = 0;
let cards: Vec<Card> = INPUT.lines().map(parse_game).collect();
let mut cache: HashMap<usize, u32> = HashMap::new();
for i in 0..cards.len() {
sum += count_recurse(&cards, i, &mut cache);
}
println!("part2: {}", sum);
}
struct Card {
num: u32,
wining_numbers: Vec<u32>,
my_numbers: Vec<u32>,
}
impl Card {
fn matches(&self) -> u32 {
self.wining_numbers.iter().fold(0, |mut acc, w| {
if self.my_numbers.iter().find(|n| *n == w).is_some() {
acc += 1
}
acc
})
}
}
fn parse_game(s: &str) -> Card {
lazy_static! {
static ref RE_HEAD: Regex = Regex::new(r"(\d+)").unwrap();
static ref RE_NUM: Regex = Regex::new(r"(\d+)").unwrap();
}
let (info, numbers) = {
let mut iter = s.split(":");
(iter.next().unwrap(), iter.next().unwrap())
};
let game = RE_HEAD.captures(info).unwrap()[1].parse::<u32>().unwrap();
let (wining_numbers, my_numbers) = {
let mut iter = numbers.split("|");
let wining_iter = RE_NUM.captures_iter(iter.next().unwrap());
let mynum_iter = RE_NUM.captures_iter(iter.next().unwrap());
let wining_numbers: Vec<u32> = wining_iter.map(|c| {
c.get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u32>().unwrap()
}).collect();
let my_numbers: Vec<u32> = mynum_iter.map(|c| {
c.get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u32>().unwrap()
}).collect();
(wining_numbers, my_numbers)
};
Card { num: game, wining_numbers, my_numbers }
}
fn count_recurse(cards: &Vec<Card>, index: usize, cache: &mut HashMap<usize, u32>) -> u32 {
if let Some(cached) = cache.get(&index) {
return *cached;
}
if let Some(card) = cards.get(index) {
let mut sum: u32 = 1;
let matches = card.matches();
if matches > 0 {
for n in 1..=matches {
sum += count_recurse(cards, index + (n as usize), cache);
}
}
cache.insert(index, sum);
return sum;
}
0
}
#[cfg(test)]
mod tests {
use lazy_static::lazy_static;
use regex::Regex;
#[test]
fn test_re() {
lazy_static! {
static ref RE_NUM: Regex = Regex::new(r"(\d+)").unwrap();
}
let input = "1 22 3";
let mut iter = RE_NUM.captures_iter(input);
assert_eq!(iter.next().unwrap().get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u32>().unwrap(), 1);
assert_eq!(iter.next().unwrap().get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u32>().unwrap(), 22);
assert_eq!(iter.next().unwrap().get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u32>().unwrap(), 3);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment