2021-12-04 13:15:12 +00:00
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
use color_eyre::eyre::{eyre, Error};
|
|
|
|
|
|
|
|
use super::board::Board;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Bingo {
|
|
|
|
pub boards: Vec<Board>,
|
|
|
|
pub numbers: Vec<i32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Bingo {
|
|
|
|
/// The game loop for part one.
|
|
|
|
///
|
|
|
|
/// Loops over the bingo numbers until it finds the first board that has won.
|
|
|
|
pub fn play_until_first_win(mut self) -> (Board, i32) {
|
|
|
|
for number in self.numbers {
|
|
|
|
for board in &mut self.boards {
|
|
|
|
board.mark_number(number);
|
|
|
|
|
|
|
|
if board.check() {
|
|
|
|
return (board.clone(), number);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unreachable!()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The game loop for part two.
|
|
|
|
///
|
|
|
|
/// Loops over the bingo numbers until only one board is left and then returns
|
|
|
|
/// that as the winner.
|
|
|
|
pub fn play_until_last_win(mut self) -> (Board, i32) {
|
|
|
|
for number in self.numbers {
|
|
|
|
for board in &mut self.boards {
|
|
|
|
board.mark_number(number);
|
|
|
|
board.has_won = board.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.boards.len() == 1 {
|
|
|
|
return (self.boards.first().unwrap().clone(), number);
|
|
|
|
}
|
|
|
|
|
2022-10-03 11:02:39 +00:00
|
|
|
self.boards.retain(|board| !board.has_won);
|
2021-12-04 13:15:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unreachable!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for Bingo {
|
|
|
|
type Err = Error;
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
let numbers = s
|
2022-10-02 20:20:09 +00:00
|
|
|
.split('\n')
|
2021-12-04 13:15:12 +00:00
|
|
|
.next()
|
2022-10-02 20:20:09 +00:00
|
|
|
.ok_or_else(|| eyre!("Didn't find bingo numbers on the first line"))?
|
|
|
|
.split(',')
|
2021-12-04 13:15:12 +00:00
|
|
|
.map(str::parse)
|
|
|
|
.collect::<Result<_, _>>()?;
|
|
|
|
|
|
|
|
let boards = s
|
|
|
|
.split("\n\n")
|
|
|
|
.skip(1)
|
|
|
|
.map(str::parse)
|
|
|
|
.collect::<Result<_, _>>()?;
|
|
|
|
|
|
|
|
Ok(Self { boards, numbers })
|
|
|
|
}
|
|
|
|
}
|