solution: day4
This commit is contained in:
98
src/bin/04.rs
Normal file
98
src/bin/04.rs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
use hashbrown::HashMap;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
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::<String>();
|
||||||
|
|
||||||
|
if order == code {
|
||||||
|
res += id.parse::<u32>().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
pub fn part_two(input: &str) -> Option<usize> {
|
||||||
|
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::<String>();
|
||||||
|
|
||||||
|
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::<String>()
|
||||||
|
})
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/examples/04.txt
Normal file
4
src/examples/04.txt
Normal file
@@ -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]
|
||||||
Reference in New Issue
Block a user