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;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
const FILE_STR: &'static str = include_str!("input.txt");
|
const FILE_STR: &'static str = include_str!("input.txt");
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Debug, Default)]
|
||||||
struct ScratchCard {
|
struct ScratchCard {
|
||||||
winning: Vec<usize>,
|
winning: Vec<usize>,
|
||||||
chosen: Vec<usize>,
|
chosen: Vec<usize>,
|
||||||
|
chosen_winners: HashSet<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScratchCard {
|
impl ScratchCard {
|
||||||
fn new(winning: Vec<usize>, chosen: Vec<usize>) -> Self {
|
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 score(&mut self) -> usize {
|
||||||
fn parse_num_str(s: &str) -> Vec<usize> {
|
self.find_chosen_winners();
|
||||||
s.split_ascii_whitespace()
|
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)
|
.filter(|s| s.len() > 0)
|
||||||
.map(|s| s.trim())
|
.map(parse_game_table_line),
|
||||||
.map(|s| usize::from_str_radix(s, 10).unwrap())
|
))
|
||||||
.collect::<Vec<usize>>()
|
}
|
||||||
|
|
||||||
|
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) {
|
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()))
|
(card_num, ScratchCard::new(nums[0].clone(), nums[1].clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_game_table(table: &str) -> GameMap {
|
/// Parse numbers from a line, separated/surrounded by whitespace
|
||||||
HashMap::from_iter(
|
fn parse_num_str(s: &str) -> Vec<usize> {
|
||||||
table
|
s.split_ascii_whitespace()
|
||||||
.split('\n')
|
|
||||||
.filter(|s| s.len() > 0)
|
.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() {
|
fn part_one() {
|
||||||
let map = parse_game_table(FILE_STR);
|
let mut map = GameMap::parse(FILE_STR);
|
||||||
println!("{:#?}", map);
|
let sum = map.get_score_sum();
|
||||||
|
println!("Part 1 Score Sum {}", sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -57,4 +93,11 @@ fn main() {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
const EXAMPLE_FILE_STR: &'static str = include_str!("example_input.txt");
|
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