1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
mod tensor;
use std::io::{BufRead};
use std::collections::{HashMap, HashSet};
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<Matrix> {
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::<u64>().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<u64> = {
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<Matrix> = Vec::new();
let mut inverse: HashMap<u64, Vec<(usize, Index)>> = 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());
let mut boards_not_yet_won: HashSet<usize> = HashSet::new();
boards_not_yet_won.extend(0..boards.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) {
boards_not_yet_won.remove(board_num);
if boards_not_yet_won.is_empty() {
println!("{}", board_score(board)*x);
return;
}
//winning_boards.push((*board_num, board_score(board)*x));
}
}
}
}
|