Complete 2023 day7

This commit is contained in:
Timothy Warren 2023-12-18 15:38:07 -05:00
parent cb784f6d6b
commit 770ef4c830

View File

@ -8,7 +8,7 @@ const FILE_STR: &str = include_str!("input.txt");
#[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]
enum NormalCardType { enum PartOne {
#[default] #[default]
Two = 0, Two = 0,
Three, Three,
@ -25,9 +25,9 @@ enum NormalCardType {
Ace, Ace,
} }
impl From<char> for NormalCardType { impl From<char> for PartOne {
fn from(value: char) -> Self { fn from(value: char) -> Self {
use NormalCardType::*; use PartOne::*;
match value { match value {
'2' => Two, '2' => Two,
@ -50,7 +50,7 @@ impl From<char> for NormalCardType {
#[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]
enum WildJokerCardType { enum PartTwo {
#[default] #[default]
Joker = 0, Joker = 0,
Two, Two,
@ -67,9 +67,9 @@ enum WildJokerCardType {
Ace, Ace,
} }
impl From<char> for WildJokerCardType { impl From<char> for PartTwo {
fn from(value: char) -> Self { fn from(value: char) -> Self {
use WildJokerCardType::*; use PartTwo::*;
match value { match value {
'J' => Joker, 'J' => Joker,
'2' => Two, '2' => Two,
@ -88,13 +88,9 @@ impl From<char> for WildJokerCardType {
} }
} }
} }
type PartOne = NormalCardType;
type PartTwo = WildJokerCardType;
trait CardType: Eq + Copy + PartialOrd + Ord + Debug + Hash + From<char> {} trait CardType: Eq + Copy + PartialOrd + Ord + Debug + Hash + From<char> {}
impl CardType for NormalCardType {} impl CardType for PartOne {}
impl CardType for WildJokerCardType {} impl CardType for PartTwo {}
#[derive(Debug, Default, PartialEq, Eq)] #[derive(Debug, Default, PartialEq, Eq)]
struct Hand<T> { struct Hand<T> {
@ -103,10 +99,7 @@ struct Hand<T> {
bet: usize, bet: usize,
} }
impl<T: CardType> Hand<T> impl<T: CardType> Hand<T> {
where
HandType: From<[T; 5]>,
{
fn parse(line: &str) -> Self { fn parse(line: &str) -> Self {
let mut parts = line.split_whitespace(); let mut parts = line.split_whitespace();
let raw_hand = parts.next().unwrap(); let raw_hand = parts.next().unwrap();
@ -163,8 +156,51 @@ enum HandType {
} }
impl HandType { impl HandType {
fn from_cards(value: [WildJokerCardType; 5]) -> Self { fn from_cards(value: [PartTwo; 5]) -> Self {
todo!(); let mut cards = Vec::from(value);
cards.sort_unstable();
let mut count_map: HashMap<PartTwo, usize> = HashMap::new();
cards.into_iter().for_each(|ct| {
match count_map.get(&ct) {
Some(count) => count_map.insert(ct, *count + 1),
None => count_map.insert(ct, 1),
};
});
let mut card_type_counts: Vec<usize> = count_map.clone().into_values().collect();
card_type_counts.sort_unstable();
let joker_count = if let Some(count) = count_map.get(&PartTwo::Joker) {
*count
} else {
0usize
};
let base_type = match card_type_counts[..] {
[5] => FiveOfAKind,
[1, 4] => FourOfAKind,
[2, 3] => FullHouse,
[1, 1, 3] => ThreeOfAKind,
[1, 2, 2] => TwoPair,
[1, 1, 1, 2] => OnePair,
_ => HighCard,
};
match (joker_count, base_type) {
(0, _) => base_type,
(_, FourOfAKind) => FiveOfAKind,
(_, FullHouse) => FiveOfAKind,
(_, ThreeOfAKind) => FourOfAKind,
(1, TwoPair) => FullHouse,
(_, TwoPair) => FourOfAKind,
(_, OnePair) => ThreeOfAKind,
(_, HighCard) => OnePair,
(_, _) => base_type,
}
} }
} }
@ -224,6 +260,16 @@ impl<T: CardType> Game<T> {
} }
} }
impl Game<PartTwo> {
fn get_wild_score_sum(&mut self) -> usize {
self.hands
.iter_mut()
.for_each(|hand| hand.kind = HandType::from_cards(hand.cards));
self.get_score_sum()
}
}
fn part_one() { fn part_one() {
let mut game: Game<PartOne> = Game::parse(FILE_STR); let mut game: Game<PartOne> = Game::parse(FILE_STR);
let score = game.get_score_sum(); let score = game.get_score_sum();
@ -232,7 +278,10 @@ fn part_one() {
} }
fn part_two() { fn part_two() {
let _game: Game<PartTwo> = Game::parse(FILE_STR); let mut game: Game<PartTwo> = Game::parse(FILE_STR);
let score = game.get_wild_score_sum();
println!("Part 2: Sum of wildcard scores: {}", score);
} }
fn main() { fn main() {
@ -252,5 +301,8 @@ mod test {
} }
#[test] #[test]
fn get_wild_score_sum() {} fn get_wild_score_sum() {
let mut game: Game<PartTwo> = Game::parse(EXAMPLE_FILE_STR);
assert_eq!(5905, game.get_wild_score_sum());
}
} }