Complete 2023 day4 part 1
This commit is contained in:
parent
3a87c13750
commit
c3773862a4
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
type GameMap = HashMap<usize, ScratchCard>;
|
||||
fn find_chosen_winners(&mut self) {
|
||||
self.winning
|
||||
.iter()
|
||||
.filter(|w| self.chosen.contains(w))
|
||||
.for_each(|cw| _ = self.chosen_winners.insert(*cw));
|
||||
}
|
||||
|
||||
/// Parse numbers from a line, separated/surrounded by whitespace
|
||||
fn parse_num_str(s: &str) -> Vec<usize> {
|
||||
s.split_ascii_whitespace()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct GameMap(HashMap<usize, ScratchCard>);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user