use std::fs::File; use std::io::{ self, BufRead, BufReader }; type Grid = Vec>; const N: usize = 20; fn read_grid_lines() -> io::Lines> { let file = File::open("grid.txt").unwrap(); return io::BufReader::new(file).lines(); } fn get_grid() -> Grid { let lines = read_grid_lines(); let mut grid: Grid = Vec::new(); for line in lines { let s = line.unwrap(); let ns: Vec<_> = s.split(" ") .map(|x| x.parse::().unwrap()) .collect(); grid.push(ns); } return grid; } fn g(grid: &Grid, i: usize, j: usize) -> u32 { return u32::from(grid.get(i).unwrap().get(j).unwrap().clone()); } fn best_h(grid: &Grid) -> u32 { let mut best_pr = 1; for i in 0..N { for j in 0..N-3 { let a = g(&grid, i, j); let b = g(&grid, i, j + 1); let c = g(&grid, i, j + 2); let d = g(&grid, i, j + 3); let pr = a * b * c * d; if pr > best_pr { best_pr = pr; } } } return best_pr; } fn best_v(grid: &Grid) -> u32 { let mut best_pr = 1; for i in 0..N-3 { for j in 0..N { let a = g(&grid, i, j); let b = g(&grid, i + 1, j); let c = g(&grid, i + 2, j); let d = g(&grid, i + 3, j); let pr = a * b * c * d; if pr > best_pr { best_pr = pr; } } } return best_pr; } fn best_dr(grid: &Grid) -> u32 { let mut best_pr = 1; for i in 0..N-3 { for j in 0..N-3 { let a = g(&grid, i, j); let b = g(&grid, i + 1, j + 1); let c = g(&grid, i + 2, j + 2); let d = g(&grid, i + 3, j + 3); let pr = a * b * c * d; if pr > best_pr { best_pr = pr; } } } return best_pr; } fn best_dl(grid: &Grid) -> u32 { let mut best_pr = 1; for i in 3..N { for j in 0..N-3 { let a = g(&grid, i, j); let b = g(&grid, i - 1, j + 1); let c = g(&grid, i - 2, j + 2); let d = g(&grid, i - 3, j + 3); let pr = a * b * c * d; if pr > best_pr { best_pr = pr; } } } return best_pr; } fn best(grid: &Grid) -> u32 { let a = best_h(&grid); let b = best_v(&grid); let c = best_dr(&grid); let d = best_dl(&grid); println!("{} {} {} {}", a, b, c, d); return best_h(&grid).max(best_v(&grid)).max(best_dr(&grid)).max(best_dl(grid)); } fn main() { let grid = get_grid(); let n = best(&grid); println!("{}", n); }