AOC Day 4 Part Two
unknown
plain_text
4 years ago
6.9 kB
5
Indexable
use std::io::{self, BufRead};
use std::fs::File;
struct BoardNumber {
value: u32,
marked: bool,
}
struct Board {
value_arr: Vec<Vec<BoardNumber>>,
}
impl Board {
fn new() -> Board {
let board = Board {
value_arr: vec![
vec![
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
],
vec![
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
],
vec![
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
],
vec![
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
],
vec![
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
BoardNumber { value: 0, marked: false },
],
]
};
return board;
}
fn mark_number(&mut self, number: u32) {
for line in &mut self.value_arr {
for board_num in line {
if number == board_num.value {
board_num.marked = true;
}
}
}
}
fn sum_unmarked(&self) -> u32 {
let mut sum: u32 = 0;
for line in &self.value_arr {
for board_num in line {
if !board_num.marked { sum += board_num.value }
}
}
sum
}
fn check_win(&self) -> bool {
self.check_horiz() || self.check_vertical() || self.check_diagonal()
}
fn print_board(&self) {
for line in &self.value_arr {
println!("{} {} {} {} {}", line[0].value, line[1].value, line[2].value, line[3].value, line[4].value)
}
}
fn check_diagonal(&self) -> bool {
let diagonal_one = self.value_arr[0][0].marked
&& self.value_arr[1][1].marked
&& self.value_arr[2][2].marked
&& self.value_arr[3][3].marked
&& self.value_arr[4][4].marked;
let diagonal_two = self.value_arr[4][0].marked
&& self.value_arr[3][1].marked
&& self.value_arr[2][2].marked
&& self.value_arr[1][3].marked
&& self.value_arr[0][4].marked;
diagonal_one || diagonal_two
}
fn check_vertical(&self) -> bool {
for i in 0..5 {
let v_win = self.value_arr[i][0].marked
&& self.value_arr[i][1].marked
&& self.value_arr[i][2].marked
&& self.value_arr[i][3].marked
&& self.value_arr[i][4].marked;
if v_win { return true; }
}
false
}
fn check_horiz(&self) -> bool {
for i in 0..5 {
let h_win = self.value_arr[0][i].marked
&& self.value_arr[1][i].marked
&& self.value_arr[2][i].marked
&& self.value_arr[3][i].marked
&& self.value_arr[4][i].marked;
if h_win { return true; }
}
false
}
}
fn main() {
//Read in file
let file = File::open("./input.txt").unwrap();
let lines = io::BufReader::new(file).lines();
let mut str_lines: Vec<String> = Vec::new();
for line in lines {
if let Ok(input) = line {
str_lines.push(input);
}
}
//Get numbers
let mut numbers: Vec<u32> = Vec::new();
for token in str_lines[0].split(',') {
numbers.push(token.parse().unwrap());
}
//Count boards
let mut num_boards: usize = 0;
for line in &str_lines {
if line.is_empty() { num_boards += 1 }
}
num_boards -= 1;
//Build boards
let mut boards: Vec<Board> = Vec::new();
for board_idx in 0..num_boards {
let mut board = Board::new();
let mut vec_nums: Vec<Vec<u32>> = Vec::new();
let start_line: usize = board_idx * 6 + 2;
let line_width: usize = 5;
for i in 0..line_width {
let line = str_lines[start_line + i].clone();
vec_nums.push(Vec::new());
for token in line.split_whitespace() {
vec_nums[i].push(token.parse().unwrap());
}
}
for x in 0..line_width {
for y in 0..line_width {
board.value_arr[x][y].value = vec_nums[x][y];
}
}
boards.push(board);
}
//Run game
let mut last_num: u32;
let mut num_idx: usize = 0;
let mut last_found = false;
while !last_found {
last_num = numbers[num_idx];
for mut b in &mut boards{
b.mark_number(last_num);
}
let mut count_winning = 0;
for b in &boards{
if b.check_win() {count_winning += 1}
}
if count_winning == num_boards - 1{
for mut b in &mut boards{
if !b.check_win() {
//Play until win
let mut board_wins = false;
while !board_wins {
last_num = numbers[num_idx];
b.mark_number(last_num);
if b.check_win() {
let board_sum = b.sum_unmarked();
let value = board_sum * last_num;
println!("Winning value: {}", value);
board_wins = true;
last_found = true;
}
num_idx += 1;
}
}
}
}
num_idx += 1;
}
}
Editor is loading...