aboutsummaryrefslogtreecommitdiff
path: root/src/day4.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/day4.rs')
-rw-r--r--src/day4.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/day4.rs b/src/day4.rs
index 9f4f82e..945f9a5 100644
--- a/src/day4.rs
+++ b/src/day4.rs
@@ -25,7 +25,7 @@ mod bingo_internals {
}
#[derive(Debug,Clone,Copy)]
- struct WonBingoCard{
+ pub struct WonBingoCard{
score : usize,
round : usize,
}
@@ -34,6 +34,9 @@ mod bingo_internals {
pub fn get_score(&self) -> usize {
self.score
}
+ pub fn get_winning_round(&self) -> usize {
+ self.round
+ }
}
impl UnfinishedBingoCard {
@@ -255,6 +258,13 @@ mod bingo_internals {
self.round
}
+ pub fn get_winner_cards_ascending(&self) -> impl Iterator<Item=(usize, & WonBingoCard)>+Clone {
+ self.cards.iter().enumerate().filter_map(|(winner_number, card)| match card {
+ BingoCard::Unfinished(_) => { None }
+ BingoCard::Won(card) => { Some((winner_number, card)) }
+ })
+ }
+
pub fn get_winner_cards_scores_ascending(&self) -> impl Iterator<Item=WinnerNumberAndScore>+Clone+'_ {
self.cards.iter().enumerate().filter_map(|(winner_number, card)| card.get_score().map(|score| WinnerNumberAndScore { winner_number, score}))
}
@@ -489,7 +499,7 @@ fn find_first_player_that_hasnt_won(game : &BingoGame) -> Option<usize> {
})
}
-#[aoc(day4, part2)]
+#[aoc(day4, part2, StopBeforeLastPlayerFinishes)]
pub fn solve_part2(input : &GameAndInput) -> Result<usize, BingoGameSolutionError> {
use std::ops::ControlFlow as Cf;
let (game_before_last_card_finishes, mut input_iterator) = run_game_until_only_one_player_left(input.game.clone(), input.input.iter())?;
@@ -517,6 +527,28 @@ pub fn solve_part2(input : &GameAndInput) -> Result<usize, BingoGameSolutionErro
}
}
+#[aoc(day4, part2, JustContinueAndFindOutAfter)]
+pub fn solve_part2_just_finish_and_find_out_after(input : &GameAndInput) -> Result<usize, BingoGameSolutionError> {
+ use std::cmp::max;
+ let end_state = input.input.iter().fold(input.game.clone(), |game, value| game.cross_number(*value));
+ let (winner_count, last_round_someone_won) = end_state.get_winner_cards_ascending()
+ .fold((0,0), | (winner_count, last_round_someone_won), (_, winner) | (winner_count + 1, max(last_round_someone_won, winner.get_winning_round())));
+ if winner_count != end_state.get_number_of_cards_in_game() {
+ Err(BingoGameSolutionError::InsufficientInput { current_game_state : end_state})
+ }
+ else {
+ let mut last_winners = end_state.get_winner_cards_ascending()
+ .filter(|(_, winner)| winner.get_winning_round() == last_round_someone_won);
+ let last_winners_count = last_winners.clone().count();
+ if last_winners_count == 1 {
+ Ok(last_winners.next().unwrap().1.get_score())
+ }
+ else {
+ Err(BingoGameSolutionError::Tie{ winners : last_winners.map(|(winner_number, card)| WinnerNumberAndScore{ winner_number, score : card.get_score()}).collect() })
+ }
+ }
+}
+
#[cfg(test)]
pub mod tests{