use std::fs::read_to_string; use std::iter; use std::cmp; use std::time::Instant; fn encode_mirror_row(row: &[u8]) -> u32 { let mut result: u32 = 0; for &c in row { result = (result << 1) | (c as u32 & 1); // match c { // b'#' => result = (result << 1) | 1, // _ => result = result << 1 // } } result } fn encode_mirror_col(rows: &Vec<&[u8]>, index: usize) -> u32 { let mut result = 0; for &row in rows { result = (result << 1) | (row[index] as u32 & 1); // match row[index] { // b'#' => result = (result << 1) | 1, // _ => result = result << 1 // } } result } fn test_mirror_dim(mirror_dim: &Vec, index: usize) -> bool { let span = cmp::min(index, mirror_dim.len() - index); for i in 0..span { if mirror_dim[index - i - 1] != mirror_dim[index + i] { return false; } } return true; } fn test_mirror_dim_smudge(mirror_dim: &Vec, index: usize) -> bool { let span = cmp::min(index, mirror_dim.len() - index); let mut num_errors = 0; for i in 0..span { let diff = mirror_dim[index - i - 1] ^ mirror_dim[index + i]; num_errors += u32::count_ones(diff) } num_errors == 1 } fn solution(input_str: &str) -> (u32, u32) { let mut sum1 = 0; let mut sum2 = 0; let mut current_mirror: Vec<&[u8]> = vec![]; let mut current_mirror_rows: Vec = vec![]; let mut current_mirror_cols: Vec = vec![]; for line in input_str.lines().chain(iter::once("")) { if !line.is_empty() { let as_bytes = line.as_bytes(); current_mirror.push(as_bytes); current_mirror_rows.push(encode_mirror_row(as_bytes)); } else { current_mirror_cols.extend((0..current_mirror[0].len()).map( |index| encode_mirror_col(¤t_mirror, index) )); // Task 1 let mut found = false; for i in 1..current_mirror_rows.len() { if test_mirror_dim(¤t_mirror_rows, i) { sum1 += i as u32 * 100; found = true; break; } } if !found { for i in 1..current_mirror_cols.len() { if test_mirror_dim(¤t_mirror_cols, i) { sum1 += i as u32; break; } } } // Task 2 found = false; for i in 1..current_mirror_rows.len() { if test_mirror_dim_smudge(¤t_mirror_rows, i) { sum2 += i as u32 * 100; found = true; break; } } if !found { for i in 1..current_mirror_cols.len() { if test_mirror_dim_smudge(¤t_mirror_cols, i) { sum2 += i as u32; break; } } } current_mirror.clear(); current_mirror_rows.clear(); current_mirror_cols.clear(); } } (sum1, sum2) } fn main() { let time_start = Instant::now(); let input_str = read_to_string("input.txt").unwrap(); let time_start_no_io = Instant::now(); let mut sum1 = 0; let mut sum2 = 0; // For performance measurement for _ in 0..1 { (sum1, sum2) = solution(&input_str); } let elapsed = time_start.elapsed().as_micros(); let elapsed_no_io = time_start_no_io.elapsed().as_micros(); println!("Time: {}us", elapsed); println!("Time without file i/o: {}us", elapsed_no_io); println!("Sum1: {}", sum1); println!("Sum2: {}", sum2); }