#![allow(dead_code)] 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 lines_mirrored(arr: &Vec>, start: usize) -> bool { for (i, j) in (0..=start).rev().zip(start + 1..arr.len()) { if arr[i] != arr[j] { return false; } } return true; } fn mirror_horizontal_line(arr: &Vec>) -> Vec { let mut out = Vec::new(); for i in 0..arr.len() - 1 { if lines_mirrored(arr, i) { out.push(i + 1); } } if out.len() == 0 { out.push(0); } out } fn print_arr(arr: &Vec>) { for i in 0..arr.len() { for j in 0..arr[0].len() { if arr[i][j] == true { print!("#"); } else { print!("."); } } println!(""); } println!(""); } fn main() { // let filename = "in/day13.ref"; let filename = "in/day13.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 groups = content.trim_end().split("\n\n"); let mut res1 = 0; let mut res2 = 0; for group in groups { let mut arr: Vec> = Vec::new(); for line in group.split("\n") { let mut l: Vec = Vec::new(); for c in line.chars() { l.push(if c == '#' { true } else { false }); } arr.push(l); } let (x1, y1) = ( mirror_horizontal_line(&transpose(arr.clone()))[0], mirror_horizontal_line(&arr)[0], ); res1 += x1 + 100 * y1; if x1 != 0 && y1 != 0 { panic!("asdf"); } if x1 == 0 && y1 == 0 { panic!("asdf"); } // print_arr(&arr); 'outer: for i in 0..arr.len() { for j in 0..arr[0].len() { let mut a = arr.clone(); a[i][j] ^= true; let (x2, y2) = ( mirror_horizontal_line(&transpose(a.clone())) .into_iter() .filter(|x| *x != x1) .next() .unwrap_or(0), mirror_horizontal_line(&a) .into_iter() .filter(|y| *y != y1) .next() .unwrap_or(0), ); if x1 == 0 { if (y1 != y2) && (y2 != 0) { res2 += 100 * y2; break 'outer; } else if x2 != 0 { res2 += x2; break 'outer; } } else if y1 == 0 { if y2 != 0 { res2 += 100 * y2; break 'outer; } else if (x1 != x2) && (x2 != 0) { res2 += x2; break 'outer; } } } } } println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, 37975); assert_eq!(res2, 32497); }