90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
#[derive(Debug, Clone)]
|
|
pub struct Field {
|
|
pub number: usize,
|
|
pub marked: bool,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Board {
|
|
pub fields: [[Field; 5]; 5],
|
|
pub finished: bool,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Game {
|
|
pub boards: Vec<Board>,
|
|
pub input_numbers: Vec<usize>,
|
|
}
|
|
|
|
impl Board {
|
|
pub fn mark(&mut self, num: usize) -> Option<usize> {
|
|
if self.finished {
|
|
return None;
|
|
}
|
|
for lines in self.fields.iter_mut() {
|
|
for field in lines.iter_mut() {
|
|
if field.number == num {
|
|
field.marked = true;
|
|
}
|
|
}
|
|
}
|
|
if let Some(score) = self.bingo().map(|pre_score| pre_score * num) {
|
|
self.finished = true;
|
|
Some(score)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn bingo(&self) -> Option<usize> {
|
|
let mut completed = false;
|
|
for i in 0..5 {
|
|
if (self.fields[i][0].marked
|
|
&& self.fields[i][1].marked
|
|
&& self.fields[i][2].marked
|
|
&& self.fields[i][3].marked
|
|
&& self.fields[i][4].marked)
|
|
|| (self.fields[0][i].marked
|
|
&& self.fields[1][i].marked
|
|
&& self.fields[2][i].marked
|
|
&& self.fields[3][i].marked
|
|
&& self.fields[4][i].marked)
|
|
{
|
|
completed = true;
|
|
}
|
|
}
|
|
if completed {
|
|
Some(self.pre_score())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn pre_score(&self) -> usize {
|
|
self.fields
|
|
.iter()
|
|
.flat_map(|lines| lines.iter())
|
|
.map(|field| if field.marked { 0 } else { field.number })
|
|
.sum()
|
|
}
|
|
}
|
|
|
|
impl Game {
|
|
pub fn get_scores(mut self, max: Option<usize>) -> Vec<usize> {
|
|
let mut scores = Vec::new();
|
|
for num in self.input_numbers {
|
|
for board in &mut self.boards {
|
|
if let Some(score) = board.mark(num) {
|
|
scores.push(score);
|
|
if let Some(max) = max {
|
|
if scores.len() >= max {
|
|
return scores;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
scores
|
|
}
|
|
}
|