Skip to content

Commit

Permalink
2023 day 13 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter554 committed Dec 14, 2023
1 parent 13e4604 commit ca936c1
Showing 1 changed file with 42 additions and 23 deletions.
65 changes: 42 additions & 23 deletions 2023/rust/aoc/src/day13/mod.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
use anyhow::Result;
use std::{fs, path::Path};
use std::{collections::HashMap, fs, path::Path};

pub fn part1(input_path: &Path) -> Result<i64> {
let input = fs::read_to_string(input_path)?;
let patterns = parse_input(&input);
Ok(patterns
.into_iter()
.map(find_symmetry)
.map(|symmetry| match symmetry {
Symmetry::Row(row_idx) => 100 * (row_idx + 1) as i64,
Symmetry::Column(column_idx) => (column_idx + 1) as i64,
.map(get_reflection_error_counts)
.map(|hm| hm.get(&0).unwrap()[0].clone())
.map(|reflection_axis| match reflection_axis {
ReflectionAxis::Row(row_idx) => 100 * (row_idx + 1) as i64,
ReflectionAxis::Column(column_idx) => (column_idx + 1) as i64,
})
.sum())
}

pub fn part2(input_path: &Path) -> Result<i64> {
let input = fs::read_to_string(input_path)?;
let _ = input;
Ok(42)
let patterns = parse_input(&input);
Ok(patterns
.into_iter()
.map(get_reflection_error_counts)
.map(|hm| hm.get(&1).unwrap()[0].clone())
.map(|reflection_axis| match reflection_axis {
ReflectionAxis::Row(row_idx) => 100 * (row_idx + 1) as i64,
ReflectionAxis::Column(column_idx) => (column_idx + 1) as i64,
})
.sum())
}

fn parse_input(input: &str) -> Vec<Vec<Vec<bool>>> {
Expand All @@ -31,37 +40,47 @@ fn parse_input(input: &str) -> Vec<Vec<Vec<bool>>> {
.collect()
}

enum Symmetry {
#[derive(Debug, Clone)]
enum ReflectionAxis {
Row(usize),
Column(usize),
}

fn find_symmetry(pattern: Vec<Vec<bool>>) -> Symmetry {
// For every reflection axis compute the reflection error count
// (number of errors we see when reflecting about that axis).
// Return a mapping of error count to reflection axes with that error count.
fn get_reflection_error_counts(pattern: Vec<Vec<bool>>) -> HashMap<i64, Vec<ReflectionAxis>> {
let mut out: HashMap<i64, Vec<ReflectionAxis>> = HashMap::new();
for row_idx in 0..=pattern.len() - 2 {
if is_symmetric_about_row(&pattern, row_idx) {
return Symmetry::Row(row_idx);
}
let error_count = get_reflection_error_count_about_row(&pattern, row_idx);
out.entry(error_count)
.or_default()
.push(ReflectionAxis::Row(row_idx));
}
let transposed_pattern = transpose(&pattern);
for row_idx in 0..=transposed_pattern.len() - 2 {
if is_symmetric_about_row(&transposed_pattern, row_idx) {
return Symmetry::Column(row_idx);
}
let error_count = get_reflection_error_count_about_row(&transposed_pattern, row_idx);
out.entry(error_count)
.or_default()
.push(ReflectionAxis::Column(row_idx));
}
panic!()
out
}

fn is_symmetric_about_row(pattern: &[Vec<bool>], row_idx: usize) -> bool {
fn get_reflection_error_count_about_row(pattern: &[Vec<bool>], row_idx: usize) -> i64 {
let mut out = 0;
for idx in 0..=row_idx {
let reflected_idx = (row_idx + 1) + (row_idx - idx);
if reflected_idx > pattern.len() - 1 {
continue;
}
if pattern[idx] != pattern[reflected_idx] {
return false;
}
out += pattern[idx]
.iter()
.zip(pattern[reflected_idx].iter())
.map(|(a, b)| if a == b { 0 } else { 1 })
.sum::<i64>()
}
true
out
}

fn transpose(pattern: &[Vec<bool>]) -> Vec<Vec<bool>> {
Expand Down Expand Up @@ -91,9 +110,9 @@ mod tests {
#[test]
fn test_part2() {
let input_path = Path::new("./src/day13/sample");
assert_eq!(part2(input_path).unwrap(), 42);
assert_eq!(part2(input_path).unwrap(), 400);

let input_path = Path::new("./src/day13/input");
assert_eq!(part2(input_path).unwrap(), 42);
assert_eq!(part2(input_path).unwrap(), 30442);
}
}

0 comments on commit ca936c1

Please sign in to comment.