AOC Day Four Part Two Cleaned Up
unknown
rust
3 years ago
6.7 kB
4
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 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 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 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...