Skip to content

Instantly share code, notes, and snippets.

@tbarusseau
Created December 4, 2023 09:29
Show Gist options
  • Save tbarusseau/0fd45616bc50fa452450a702eb31fbf6 to your computer and use it in GitHub Desktop.
Save tbarusseau/0fd45616bc50fa452450a702eb31fbf6 to your computer and use it in GitHub Desktop.
#[derive(Debug)]
struct Game {
winning: Vec<String>,
rolled: Vec<String>,
}
impl From<&str> for Game {
fn from(value: &str) -> Self {
let colon_index = value.find(':').unwrap();
let mut map = value[colon_index + 1..].split(" | ").map(|s| {
s.trim()
.chars()
.filter(|c| c.is_numeric() || c.is_whitespace())
.collect::<String>()
.split(' ')
.filter(|s| !s.is_empty())
.map(std::borrow::ToOwned::to_owned)
.collect_vec()
});
let winning = map.next().unwrap();
let rolled = map.next().unwrap();
Self { winning, rolled }
}
}
impl Game {
fn count_wins(&self) -> usize {
self.rolled.iter().fold(0, |acc, v| {
if self.winning.contains(v) {
acc + 1
} else {
acc
}
})
}
}
fn process_input(input: &str) -> Vec<Game> {
input.lines().map(Game::from).collect_vec()
}
fn solve_part1(input: &str) -> Box<dyn std::fmt::Display> {
let input = process_input(input);
let res = input.iter().fold(0, |acc, g| {
let wins = g.count_wins();
if wins == 0 {
return acc;
}
acc + 2_i32.pow((wins - 1) as u32)
});
Box::new(res)
}
fn solve_part2(input: &str) -> Box<dyn std::fmt::Display> {
let games = process_input(input);
let mut card_counts = vec![1u32];
let mut count = 0;
for (n, game) in games.iter().enumerate() {
let wins = game.count_wins();
let end = wins + n + 1;
if end > card_counts.len() {
card_counts.resize(end, 1);
}
for i in n + 1..end {
card_counts[i] += card_counts[n];
}
count += card_counts[n];
}
Box::new(count)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment