aoc/src/year2022/day03.rs

48 lines
1.3 KiB
Rust

/// Number of trailing zeros tells us which bit is set and there should only be one set
/// Do some math to convert to the needed priority
fn bits_to_priority(b: u64) -> u32 {
let trailing = b.trailing_zeros();
match trailing {
0..=25 => trailing + 27,
32..=57 => trailing - 31,
_ => unreachable!(""),
}
}
/// For each byte in the string offset it towards 0
/// to make it fit in u64 and set a bit at the position of its value
fn to_bits(s: &str) -> u64 {
s.bytes().fold(0, |a, v| a | 1 << (v - 65))
}
pub fn part1(input: &str) -> impl std::fmt::Display {
input
.lines()
.map(|l| l.split_at(l.len() / 2))
.map(|(l, r)| bits_to_priority(to_bits(l) & to_bits(r)))
.sum::<u32>()
}
pub fn part2(input: &str) -> impl std::fmt::Display {
let mut lines = input.lines();
let mut sum = 0;
while let Some(l1) = lines.next() {
let l2 = lines.next().expect("second is guaranteed to be there");
let l3 = lines.next().expect("third is guaranteed to be there");
sum += bits_to_priority(to_bits(l1) & to_bits(l2) & to_bits(l3));
}
sum
}
#[test]
fn test_part1() {
assert_eq!("15", part1("A Y\nB X\nC Z").to_string())
}
#[test]
fn test_part2() {
assert_eq!("12", part2("A Y\nB X\nC Z").to_string())
}