#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::cmp::max; use std::cmp::min; use std::fs::File; use std::io::Read; fn transpose(original: Vec>) -> Vec> { assert!(!original.is_empty()); let mut transposed = (0..original[0].len()).map(|_| vec![]).collect::>(); for original_row in original { for (item, transposed_row) in original_row.into_iter().zip(&mut transposed) { transposed_row.push(item); } } transposed } fn insert_rows(m: Vec>) -> Vec> { let mut out = Vec::new(); for r in m { if r.iter().any(|x| *x) { out.push(r); } else { out.push(r.clone()); out.push(r); } } out } fn print_m(m: &Vec>) { for i in 0..m.len() { for j in 0..m[0].len() { if m[i][j] { print!("#"); } else { print!("."); } } println!(); } println!(); } fn get_pos(m: &Vec>) -> Vec<(i32, i32)> { let mut p = Vec::new(); for y in 0..m.len() { for x in 0..m[0].len() { if m[y][x] { p.push((x as i32, y as i32)); } } } p } fn main() { // let filename = "in/day11.ref"; let filename = "in/day11.pzl"; let mut f = File::open(filename).expect("cannot open file"); let mut content = String::new(); f.read_to_string(&mut content).expect("cannot read file"); let lines = content.trim_end().split('\n'); let mut m: Vec> = Vec::new(); for line in lines { let mut r: Vec = Vec::new(); for c in line.chars() { r.push(if c == '#' { true } else { false }); } m.push(r); } let m2 = m.clone(); let m2t = transpose(m.clone()); let p2 = get_pos(&m2); m = insert_rows(m); m = transpose(m); m = insert_rows(m); m = transpose(m); let p1 = get_pos(&m); let mut res1 = 0; let mut res2: i64 = 0; for i in 0..p1.len() { for j in i..p1.len() { if i != j { let (x1, y1) = p1[i]; let (x2, y2) = p1[j]; res1 += (x2 - x1).abs() + (y2 - y1).abs(); } } } let add = 1000000; for i in 0..p2.len() { for j in i..p2.len() { if i != j { let (x1, y1) = p2[i]; let (x2, y2) = p2[j]; let x_min = min(x1, x2); let x_max = max(x1, x2); let y_min = min(y1, y2); let y_max = max(y1, y2); for y in y_min..y_max { if m2[y as usize].iter().any(|a| *a) { res2 += 1; } else { res2 += add; } } for x in x_min..x_max { if m2t[x as usize].iter().any(|a| *a) { res2 += 1; } else { res2 += add; } } } } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 9681886); assert_eq!(res2, 791134099634); }