use std::borrow::Borrow; use std::fs::File; use std::io::{BufReader}; use std::io::prelude::*; use std::vec; struct Board { contents: Vec>, matched: Vec>, size: usize, won: bool } fn main(){ let file = File::open("./input.txt").expect("Read failed"); let reader = BufReader::new(file); let mut line_vec = Vec::new(); for line in reader.lines(){ let line_as_string = line.unwrap(); line_vec.push(line_as_string); } let first_line = &line_vec[0]; let input_sequence_str = first_line.split(',').collect::>(); let input_sequence_u32: Vec = input_sequence_str.iter().map(|x| x.parse::().unwrap()).collect(); let mut boards: Vec = Vec::new(); let mut temp_board: Vec> = Vec::new(); let mut final_score = 0; let mut last_winning_index = 0; let mut last_winning_score = 0; for line_nr in 2..line_vec.len() { let current_line = line_vec[line_nr].to_owned(); if current_line == "" { let mut matched_vec = Vec::new(); for _ in 0..temp_board.len(){ matched_vec.push(vec![false; temp_board.len()]) } boards.push(Board {contents:temp_board.to_owned(), matched:matched_vec, size : temp_board.len(), won: false}); temp_board = Vec::new(); } else { let temp_vec_str = current_line.split_whitespace().collect::>(); let line_as_u32_vec: Vec = temp_vec_str.iter().map(|x| x.parse::().unwrap()).collect(); temp_board.push(line_as_u32_vec); } } // If there is no trailing newline the last board gets stuck in the temp_board vec if temp_board.len() != 0 { let mut matched_vec = Vec::new(); for _ in 0..temp_board.len(){ matched_vec.push(vec![false; temp_board.len()]) } boards.push(Board {contents:temp_board.to_owned(), matched:matched_vec, size : temp_board.len(), won: false}); } for input in input_sequence_u32{ println!("processing {}", input); for i in 0..boards.len(){ boards[i] = check_for_hit(boards[i].borrow(), input); print!(""); } for i in 0..boards.len(){ if check_if_won(boards[i].borrow()){ boards[i].won = true; if final_score == 0 { final_score = calculate_score(boards[i].borrow(), input); } } } let mut temp_remaining = 0; let mut remaining_index = 0; for i in 0..boards.len(){ if !boards[i].won { temp_remaining += 1; remaining_index = i; } } if temp_remaining == 0 && last_winning_score == 0{ last_winning_score = calculate_score(boards[last_winning_index].borrow(), input); } last_winning_index = remaining_index; } println!("Result score: {}", final_score); println!("Last winning score: {}", last_winning_score); } fn check_for_hit(in_board: &Board, in_number: u32) -> Board { let mut out_board = Board{contents:in_board.contents.to_owned(), matched:in_board.matched.to_owned(), size:in_board.size.to_owned(), won: false}; for (index_l, line) in out_board.contents.iter().enumerate() { for (index_e, element) in line.iter().enumerate(){ if *element == in_number{ out_board.matched[index_l][index_e] = true; } } } return out_board; } fn check_if_won(in_board: &Board) -> bool { let size = in_board.size; let matched_vec = in_board.matched.to_owned(); //Check Vertical for column in 0..size { for row in 0..size{ if matched_vec[row][column] == false { break; } else if row == size -1 { return true; } } } //Check horizontal for line in matched_vec{ for (pos, element) in line.iter().enumerate() { if !element { break; } else if pos == size - 1 { return true; } } } return false; } fn calculate_score(in_board: &Board, current_number: u32) -> u32 { let matched_vec = in_board.matched.to_owned(); let content_vec = in_board.contents.to_owned(); let size = in_board.size; let mut score = 0; for line in 0..size{ for element in 0..size{ if !matched_vec[line][element] { score += content_vec[line][element]; } } } return score * current_number; }