aoc/year2024/day25.rs
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
//! # Code Chronicle
//!
//! Efficiently checks if locks and keys overlap using bitwise logic. The ASCII character
//! `#` (35) is odd and `.` (46) is even so bitwise AND with 1 results in either 1 or 0.
//! The newline character `\n` (10) is even so will result in 0 and not contribute to matches.
//! There are 25 bits plus 4 newline bits so each lock or key can be stored in an `u32`.
//! For example:
//!
//! ```none
//! #####
//! ##.## 11011
//! .#.## 01011
//! ...## => 00011 => 110110_010110_000110_000100_00010
//! ...#. 00010
//! ...#. 00010
//! .....
//! ```
pub fn parse(input: &str) -> &str {
input
}
pub fn part1(input: &str) -> u32 {
let mut slice = input.as_bytes();
let mut locks = Vec::with_capacity(250);
let mut keys = Vec::with_capacity(250);
let mut result = 0;
while !slice.is_empty() {
let bits = slice[6..35].iter().fold(0, |bits, &n| (bits << 1) | (n & 1) as u32);
if slice[0] == b'#' {
locks.push(bits);
} else {
keys.push(bits);
}
slice = &slice[43.min(slice.len())..];
}
for lock in &locks {
for key in &keys {
result += (lock & key == 0) as u32;
}
}
result
}
pub fn part2(_input: &str) -> &'static str {
"n/a"
}