mod tensor; use std::io::{BufRead}; use std::collections::{HashMap}; use std::ops::{IndexMut}; pub type Matrix = tensor::Tensor<(bool, u64), 2>; pub type Index = tensor::Index<2>; fn read_board(handle: &mut std::io::StdinLock) -> Option { let mut lines = handle.lines(); let first_line = lines.next()?.ok()?; let mut words = first_line.split_whitespace(); let mut data: Vec<(bool, u64)> = words.map(|x| (false, x.parse().expect("Malformed input"))).collect(); let n = data.len(); for i in 1..n { let line = lines.next().expect("Malformed input").expect("IO error"); let mut words = line.split_whitespace(); data.extend(words.map(|x| (false, x.parse::().expect("Malformed input")))); } lines.next(); Some(Matrix::new_from([n, n], data)) } fn is_board_winning(board: & Matrix, pivot: Index) -> bool { let mut win_row = true; for j in 0..board.shape()[1] { if !board[[pivot[0], j]].0 { win_row = false; break; } } if win_row { return true; } let mut win_col = true; for i in 0..board.shape()[0] { if !board[[i, pivot[1]]].0 { win_col = false; break; } } win_col } fn board_score(board: & Matrix) -> u64 { board.data().into_iter().filter(|x| !x.0).map(|x| x.1).sum() } pub fn main() { let mut stdin = std::io::stdin(); let numbers: Vec = { let mut handle = stdin.lock(); let mut lines = handle.lines(); let line = lines.next().expect("Malformed input").expect("IO error"); let mut words = line.split(','); words.map(|s| s.parse().expect("Malformed input")).collect() }; { let mut handle = stdin.lock(); let mut lines = handle.lines(); lines.next(); } let mut handle = stdin.lock(); let mut boards: Vec = Vec::new(); let mut inverse: HashMap> = HashMap::new(); while let Some(mat) = read_board(&mut handle) { let shape = mat.shape(); for i in 0..shape[0] { for j in 0..shape[1] { let x = mat[[i, j]].1; if let Some(k) = inverse.get_mut(&x) { k.push((boards.len(), [i, j])); } else { inverse.insert(x, vec![(boards.len(), [i, j])]); } } } boards.push(mat); } //println!("Got {} boards and {} inv maps elements.", boards.len(), inverse.len()); for x in numbers.into_iter() { for (board_num, idx) in inverse.get(&x).unwrap().into_iter() { //println!("Marking ({}, {}) on board {}", idx[0], idx[1], board_num); let board: &mut Matrix = boards.index_mut(*board_num); board[idx].0 = true; if is_board_winning(board, *idx) { println!("{}", board_score(board)*x); return; } } } }