#[path = "../lib.rs"] mod lib; fn parse_input() -> Vec> { let mut patterns = vec![]; let mut rows = vec![]; for line in lib::iter_input() { if line.len() == 0 { patterns.push(rows); rows = vec![]; } else { assert!(line.len() < 32); let mut row = 0; for (i, b) in line.bytes().enumerate() { if b == b'#' { row |= 1 << i; } } rows.push(row); } } return patterns; } fn turn(pattern: &Vec) -> Vec { let mut rows = vec![]; for i in 0.. { if pattern.iter().all(|x| x >> i == 0) { break; } let mut row = 0; for (j, x) in pattern.iter().enumerate() { row |= ((x >> i) & 1) << j; } rows.push(row); } return rows; } fn get_smudges(a: u32, b: u32) -> u32 { let mut x = a ^ b; if x == 0 { return 0; } while x & 1 == 0 { x >>= 1; } return x; } fn count) -> bool>(pattern: &Vec, check: F) -> usize { let n = pattern.len(); for i in 0..(n - 1) { let pairs = (0..=(i.min(n - i - 2))) .map(|j| (pattern[i - j], pattern[i + 1 + j])) .collect(); if check(&pairs) { return (i + 1) * 100; } } return count(&turn(pattern), check) / 100; } fn main() { let mut sum1 = 0; let mut sum2 = 0; let patterns = parse_input(); for pattern in patterns.iter() { sum1 += count(pattern, |pairs| pairs.iter().all(|&(a, b)| a == b)); sum2 += count(pattern, |pairs| { let mut sum = 0; for (a, b) in pairs.iter() { sum += get_smudges(*a, *b); if sum > 1 { return false; } } return sum == 1; }); } println!("part1: {}", sum1); println!("part2: {}", sum2); }