diff --git a/src/bin/04.rs b/src/bin/04.rs new file mode 100644 index 0000000000..36dbaa9 --- /dev/null +++ b/src/bin/04.rs @@ -0,0 +1,98 @@ +use hashbrown::HashMap; +use itertools::Itertools; + +pub fn part_one(input: &str) -> Option { + let mut res = 0; + + for room in input.lines() { + if let Some((checksum, code)) = room.split('-').collect_vec().split_last() { + let mut letters = HashMap::new(); + + for word in code.iter() { + for letter in word.chars() { + *letters.entry(letter).or_insert(0) += 1; + } + } + + let checksum = checksum.replace(']', "").to_string(); + + let (id, order) = checksum.split_once('[').unwrap(); + let code = letters + .into_iter() + .sorted_by(|kv1, kv2| kv2.1.cmp(&kv1.1).then_with(|| kv1.0.cmp(&kv2.0))) + .take(5) + .map(|(k, _)| k) + .collect::(); + + if order == code { + res += id.parse::().unwrap(); + } + } + } + + Some(res) +} +pub fn part_two(input: &str) -> Option { + for room in input.lines() { + if let Some((checksum, codes)) = room.split('-').collect_vec().split_last() { + let mut letters = HashMap::new(); + + for word in codes.iter() { + for letter in word.chars() { + *letters.entry(letter).or_insert(0) += 1; + } + } + + let checksum = checksum.replace(']', "").to_string(); + + let (id, order) = checksum.split_once('[').unwrap(); + let id = id.parse().unwrap(); + + let code = letters + .into_iter() + .sorted_by(|kv1, kv2| kv2.1.cmp(&kv1.1).then_with(|| kv1.0.cmp(&kv2.0))) + .take(5) + .map(|(k, _)| k) + .collect::(); + + if order == code { + let decrypted = codes + .iter() + .map(|x| { + x.chars() + .map(|x| { + let index = ('a'..='z').position(|y| y == x).unwrap(); + ('a'..='z').cycle().nth(index + id).unwrap() + }) + .collect::() + }) + .collect_vec() + .join(" "); + if decrypted == "northpole object storage" { + return Some(id); + } + } + } + } + + None +} +fn main() { + let input = &aoc::read_file("inputs", 4); + aoc::solve!(1, part_one, input); + aoc::solve!(2, part_two, input); +} +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + let input = aoc::read_file("examples", 4); + assert_eq!(part_one(&input), Some(1514)); + } + #[test] + fn test_part_two() { + let input = aoc::read_file("examples", 4); + assert_eq!(part_two(&input), None); + } +} diff --git a/src/examples/04.txt b/src/examples/04.txt new file mode 100644 index 0000000000..1d296af --- /dev/null +++ b/src/examples/04.txt @@ -0,0 +1,4 @@ +aaaaa-bbb-z-y-x-123[abxyz] +a-b-c-d-e-f-g-h-987[abcde] +not-a-real-room-404[oarel] +totally-real-room-200[decoy]