122 lines
3.1 KiB
Rust
122 lines
3.1 KiB
Rust
|
pub fn day4() {
|
||
|
// let input = r#"
|
||
|
// 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
|
||
|
|
||
|
// 22 13 17 11 0
|
||
|
// 8 2 23 4 24
|
||
|
// 21 9 14 16 7
|
||
|
// 6 10 3 18 5
|
||
|
// 1 12 20 15 19
|
||
|
|
||
|
// 3 15 0 2 22
|
||
|
// 9 18 13 17 5
|
||
|
// 19 8 7 25 23
|
||
|
// 20 11 10 24 4
|
||
|
// 14 21 16 12 6
|
||
|
|
||
|
// 14 21 17 24 4
|
||
|
// 10 16 15 9 19
|
||
|
// 18 8 23 26 20
|
||
|
// 22 11 13 6 5
|
||
|
// 2 0 12 3 7
|
||
|
// "#
|
||
|
// .trim();
|
||
|
|
||
|
let input = include_str!("../input/day4.txt");
|
||
|
|
||
|
let mut parts = input.split("\n\n");
|
||
|
let drawn = parts
|
||
|
.next()
|
||
|
.unwrap()
|
||
|
.split(",")
|
||
|
.map(|s| s.parse::<i32>().unwrap());
|
||
|
let mut boards: Vec<Board> = parts.map(|b| b.into()).collect();
|
||
|
|
||
|
let mut found_p1_winner = false;
|
||
|
let mut in_progress_indices = (0..boards.len()).collect::<Vec<_>>();
|
||
|
|
||
|
'outer: for n in drawn {
|
||
|
for (i, b) in boards.iter_mut().enumerate() {
|
||
|
b.mark(n);
|
||
|
if b.is_winner() {
|
||
|
if !found_p1_winner {
|
||
|
found_p1_winner = true;
|
||
|
println!("p1: winning board index: {}", i);
|
||
|
println!("p1: winning board score: {}", b.score());
|
||
|
println!("p1: final score: {}", b.score() * n);
|
||
|
}
|
||
|
|
||
|
// boo, just let me remove an element
|
||
|
in_progress_indices.retain(|&it| it != i);
|
||
|
|
||
|
if in_progress_indices.len() == 0 {
|
||
|
println!("p2: last remaining board index: {}", i);
|
||
|
println!("p2: board score: {}", b.score());
|
||
|
println!("p2: final score: {}", b.score() * n);
|
||
|
break 'outer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
struct Board {
|
||
|
numbers: [[i32; 5]; 5],
|
||
|
marked: Vec<(usize, usize)>,
|
||
|
}
|
||
|
|
||
|
impl Board {
|
||
|
fn mark(&mut self, n: i32) {
|
||
|
for x in 0..5 {
|
||
|
for y in 0..5 {
|
||
|
if self.numbers[x][y] == n {
|
||
|
self.marked.push((x, y));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn is_winner(&self) -> bool {
|
||
|
for i in 0..5 {
|
||
|
let mut row = (0..5).map(|y| (i, y));
|
||
|
let mut col = (0..5).map(|x| (x, i));
|
||
|
if row.all(|pair| self.marked.contains(&pair))
|
||
|
|| col.all(|pair| self.marked.contains(&pair))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
false
|
||
|
}
|
||
|
|
||
|
fn score(&self) -> i32 {
|
||
|
let mut sum = 0;
|
||
|
for x in 0..5 {
|
||
|
for y in 0..5 {
|
||
|
if !self.marked.contains(&(x, y)) {
|
||
|
sum += self.numbers[x][y];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
sum
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<&str> for Board {
|
||
|
fn from(str: &str) -> Self {
|
||
|
let mut numbers = [[0; 5]; 5];
|
||
|
for (i, line) in str.lines().enumerate() {
|
||
|
let mut row = [0; 5];
|
||
|
for (j, num) in line.split_whitespace().enumerate() {
|
||
|
row[j] = num.parse().unwrap();
|
||
|
}
|
||
|
numbers[i] = row;
|
||
|
}
|
||
|
Self {
|
||
|
numbers,
|
||
|
marked: vec![],
|
||
|
}
|
||
|
}
|
||
|
}
|