Complete 2023 day4 part 1

This commit is contained in:
Timothy Warren 2023-12-08 12:08:55 -05:00
parent 3a87c13750
commit c3773862a4

View File

@ -1,29 +1,64 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;
const FILE_STR: &'static str = include_str!("input.txt");
#[derive(Default, Debug)]
#[derive(Debug, Default)]
struct ScratchCard {
winning: Vec<usize>,
chosen: Vec<usize>,
chosen_winners: HashSet<usize>,
}
impl ScratchCard {
fn new(winning: Vec<usize>, chosen: Vec<usize>) -> Self {
ScratchCard { winning, chosen }
ScratchCard {
winning,
chosen,
..Self::default()
}
}
fn find_chosen_winners(&mut self) {
self.winning
.iter()
.filter(|w| self.chosen.contains(w))
.for_each(|cw| _ = self.chosen_winners.insert(*cw));
}
fn score(&mut self) -> usize {
self.find_chosen_winners();
if self.chosen_winners.is_empty() {
return 0;
}
let winner_count = self.chosen_winners.len() as u32;
usize::pow(2, winner_count - 1)
}
}
type GameMap = HashMap<usize, ScratchCard>;
#[derive(Debug, Default)]
struct GameMap(HashMap<usize, ScratchCard>);
/// Parse numbers from a line, separated/surrounded by whitespace
fn parse_num_str(s: &str) -> Vec<usize> {
s.split_ascii_whitespace()
impl GameMap {
fn parse(table: &str) -> Self {
Self(HashMap::from_iter(
table
.split('\n')
.filter(|s| s.len() > 0)
.map(|s| s.trim())
.map(|s| usize::from_str_radix(s, 10).unwrap())
.collect::<Vec<usize>>()
.map(parse_game_table_line),
))
}
fn find_all_chosen_winners(&mut self) {
self.0.iter_mut().for_each(|(_, sc)| {
sc.find_chosen_winners();
})
}
fn get_score_sum(&mut self) -> usize {
self.0.iter_mut().map(|(_, sc)| sc.score()).sum()
}
}
fn parse_game_table_line(line: &str) -> (usize, ScratchCard) {
@ -35,18 +70,19 @@ fn parse_game_table_line(line: &str) -> (usize, ScratchCard) {
(card_num, ScratchCard::new(nums[0].clone(), nums[1].clone()))
}
fn parse_game_table(table: &str) -> GameMap {
HashMap::from_iter(
table
.split('\n')
/// Parse numbers from a line, separated/surrounded by whitespace
fn parse_num_str(s: &str) -> Vec<usize> {
s.split_ascii_whitespace()
.filter(|s| s.len() > 0)
.map(parse_game_table_line),
)
.map(|s| s.trim())
.map(|s| usize::from_str_radix(s, 10).unwrap())
.collect::<Vec<usize>>()
}
fn part_one() {
let map = parse_game_table(FILE_STR);
println!("{:#?}", map);
let mut map = GameMap::parse(FILE_STR);
let sum = map.get_score_sum();
println!("Part 1 Score Sum {}", sum);
}
fn main() {
@ -57,4 +93,11 @@ fn main() {
mod tests {
use super::*;
const EXAMPLE_FILE_STR: &'static str = include_str!("example_input.txt");
#[test]
fn test_part1_example() {
let mut map = GameMap::parse(EXAMPLE_FILE_STR);
let actual = map.get_score_sum();
assert_eq!(13, actual);
}
}