-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathday13.rs
More file actions
66 lines (58 loc) · 2.01 KB
/
Copy pathday13.rs
File metadata and controls
66 lines (58 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! # Point of Incidence
//!
//! We store each row of a grid as a binary number. For example `#.##..##.` becomes `101100110`.
//! Then to count smudges we bitwise XOR the respective rows together and count one bits
//! using the [`count_ones`] function.
//!
//! For example:
//! ```none
//! ..##..### 001100111 ^ 000100111 = 00100000 => 1
//! v#####.##.v => 111110110 ^ 111110110 = 00000000 => 0
//! ^#####.##.^
//! ...#..###
//! ```
//!
//! To handle columns we transpose the grid then convert into integers the same way. For part one
//! we look for a reflection axis with 0 smudges and for part two 1 smudge, allowing the same
//! code to be reused.
//!
//! [`count_ones`]: u32::count_ones
type Input = Vec<(Vec<u32>, Vec<u32>)>;
pub fn parse(input: &str) -> Input {
input
.split("\n\n")
.map(|block| {
let grid: Vec<_> = block.lines().map(str::as_bytes).collect();
let (width, height) = (grid[0].len(), grid.len());
let bit = |x: usize, y: usize| u32::from(grid[y][x] == b'#');
let rows =
(0..height).map(|y| (0..width).fold(0, |n, x| (n << 1) | bit(x, y))).collect();
let columns =
(0..width).map(|x| (0..height).fold(0, |n, y| (n << 1) | bit(x, y))).collect();
(rows, columns)
})
.collect()
}
pub fn part1(input: &Input) -> usize {
reflect(input, 0)
}
pub fn part2(input: &Input) -> usize {
reflect(input, 1)
}
fn reflect(input: &Input, target: u32) -> usize {
input
.iter()
.map(|(rows, columns)| {
reflect_axis(columns, target)
.unwrap_or_else(|| 100 * reflect_axis(rows, target).unwrap())
})
.sum()
}
fn reflect_axis(axis: &[u32], target: u32) -> Option<usize> {
(1..axis.len()).find(|&i| {
// Zip stops when either side reaches the boundary of the grid.
let smudges: u32 =
axis[..i].iter().rev().zip(&axis[i..]).map(|(a, b)| (a ^ b).count_ones()).sum();
smudges == target
})
}