diff --git a/2023/src/bin/day12.rs b/2023/src/bin/day12.rs index 0daaf91..3d102a8 100644 --- a/2023/src/bin/day12.rs +++ b/2023/src/bin/day12.rs @@ -30,7 +30,7 @@ fn part1(lines: &Parsed) -> usize { .iter() .map(|(springs, expected)| { let mut cache = FnvHashMap::default(); - valid_combinations(&springs, &expected, CallState::default(), &mut cache) + valid_combinations(springs, expected, CallState::default(), &mut cache) }) .sum() } diff --git a/2023/src/bin/day13.rs b/2023/src/bin/day13.rs index 1f1b639..0459120 100644 --- a/2023/src/bin/day13.rs +++ b/2023/src/bin/day13.rs @@ -3,20 +3,20 @@ extern crate test; use aoc2023::{boilerplate, common::*}; const DAY: usize = 13; -type Parsed<'a> = Vec>>; +type Parsed = Vec>>; fn parse_input(raw: &str) -> Parsed { - raw.split("\n\n").map(|block| block.lines().map(|l| l.as_bytes().to_vec()).collect()).collect() + raw.split("\n\n").map(|block| block.lines().map(|l| l.bytes().map(|b| b == b'#').collect()).collect()).collect() } -fn find_reflection(block: &[Vec]) -> Option { +fn find_reflection(block: &[Vec], blacklist: Option) -> Option { 'outer: for i in 0..block.len() - 1 { let mut offset = 0; loop { match try { (block.get(i.checked_sub(offset)?)?, block.get(i + 1 + offset)?) } { - None => return Some(i + 1), + None if Some(i) != blacklist => return Some(i + 1), Some((a, b)) if a == b => offset += 1, - Some(_) => continue 'outer, + _ => continue 'outer, } } } @@ -24,12 +24,16 @@ fn find_reflection(block: &[Vec]) -> Option { } fn part1(blocks: &Parsed) -> usize { - blocks.iter().map(|block| find_reflection(block).map(|n| n * 100).or_else(|| find_reflection(&transpose(&block))).unwrap()).sum() + blocks + .iter() + .map(|block| find_reflection(block, None).map(|n| n * 100).or_else(|| find_reflection(&transpose(block), None)).unwrap()) + .sum() } -fn transpose(orig: &[Vec]) -> Vec> { - let mut out = vec![vec![0; orig.len()]; orig[0].len()]; +fn transpose(orig: &[Vec]) -> Vec> { + let mut out = vec![vec![false; orig.len()]; orig[0].len()]; for i in 0..orig.len() { + #[allow(clippy::needless_range_loop)] for j in 0..orig[0].len() { out[j][i] = orig[i][j]; } @@ -37,8 +41,30 @@ fn transpose(orig: &[Vec]) -> Vec> { out } -fn part2(parsed: &Parsed) -> usize { - unimplemented!() +fn part2(blocks: &Parsed) -> usize { + blocks + .iter() + .map(|block| { + let mut block = block.to_owned(); + let mut transposed = transpose(&block); + let p1 = find_reflection(&block, None).map(|n| n - 1); + let p1_transposed = find_reflection(&transposed, None).map(|n| n - 1); + for i in 0..block.len() { + for j in 0..block[0].len() { + block[i][j] ^= true; + transposed[j][i] ^= true; + if let Some(reflection) = + find_reflection(&block, p1).map(|n| n * 100).or_else(|| find_reflection(&transposed, p1_transposed)) + { + return reflection; + } + block[i][j] ^= true; + transposed[j][i] ^= true; + } + } + unreachable!() + }) + .sum() } boilerplate! { @@ -63,9 +89,12 @@ boilerplate! { TEST_INPUT_HORIZONTAL => 400, TEST_INPUT_VERTICAL => 5, }, - part2: { TEST_INPUT_VERTICAL => 0 }, + part2: { + TEST_INPUT_HORIZONTAL => 100, + TEST_INPUT_VERTICAL => 300, + }, }, bench1 == 37561, - bench2 == 0, + bench2 == 31108, bench_parse: Vec::len => 100, }