162 lines
4.6 KiB
Rust
162 lines
4.6 KiB
Rust
use std::borrow::Borrow;
|
|
use std::fs::File;
|
|
use std::io::{BufReader};
|
|
use std::io::prelude::*;
|
|
use std::vec;
|
|
|
|
struct Board {
|
|
contents: Vec<Vec<u32>>,
|
|
matched: Vec<Vec<bool>>,
|
|
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::<Vec<&str>>();
|
|
let input_sequence_u32: Vec<u32> = input_sequence_str.iter().map(|x| x.parse::<u32>().unwrap()).collect();
|
|
|
|
let mut boards: Vec<Board> = Vec::new();
|
|
|
|
let mut temp_board: Vec<Vec<u32>> = 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::<Vec<&str>>();
|
|
let line_as_u32_vec: Vec<u32> = temp_vec_str.iter().map(|x| x.parse::<u32>().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;
|
|
} |