This commit is contained in:
2024-12-05 12:54:39 +01:00
parent 05c88e5e56
commit 4dcf7001ee
4 changed files with 1121 additions and 0 deletions

119
y2016/src/days/d4.rs Normal file
View File

@@ -0,0 +1,119 @@
use std::collections::HashMap;
pub fn process_part1(input: &str) -> u32 {
input
.lines()
.map(|line| {
let name = get_name(line);
let id = get_id(line);
let checksum = get_checksum(line);
let stats = get_freq_and_position(&name);
let mut sorted_stats = stats.into_iter().collect::<Vec<(char, i32)>>();
sorted_stats.sort_by(|(a, a_freq), (b, b_freq)| match b_freq.cmp(a_freq) {
std::cmp::Ordering::Less => std::cmp::Ordering::Less,
std::cmp::Ordering::Greater => std::cmp::Ordering::Greater,
std::cmp::Ordering::Equal => a.cmp(b),
});
for (char, _stats) in sorted_stats.into_iter().take(5) {
if !checksum.contains(char) {
return 0;
}
}
id
})
.sum()
}
pub fn process_part2(input: &str) -> String {
input
.lines()
.filter(|line| {
let name = get_name(line);
let checksum = get_checksum(line);
let stats = get_freq_and_position(&name);
let mut sorted_stats = stats.into_iter().collect::<Vec<(char, i32)>>();
sorted_stats.sort_by(|(a, a_freq), (b, b_freq)| match b_freq.cmp(a_freq) {
std::cmp::Ordering::Less => std::cmp::Ordering::Less,
std::cmp::Ordering::Greater => std::cmp::Ordering::Greater,
std::cmp::Ordering::Equal => a.cmp(b),
});
for (char, _stats) in sorted_stats.into_iter().take(5) {
if !checksum.contains(char) {
return false;
}
}
true
})
.map(|line| {
let name = get_name(line);
let id = get_id(line);
format!("{}: {id}", rot(&name, id))
})
.collect::<Vec<String>>()
.join("\n")
}
fn rot(name: &str, count: u32) -> String {
let mut decrypted = Vec::new();
for &byte in name.as_bytes() {
if byte == b'-' {
decrypted.push(b' ');
continue;
}
let shift = (byte - b'a') as u32 + count;
decrypted.push((shift % 26) as u8 + b'a');
}
String::from_utf8(decrypted).unwrap()
}
fn get_name(room: &str) -> String {
room.rsplit_once("-").unwrap().0.to_string()
}
fn get_id(room: &str) -> u32 {
let id_start = room.rfind("-").unwrap() + 1;
let id_end = room.find("[").unwrap();
room[id_start..id_end].parse().unwrap()
}
fn get_checksum(room: &str) -> String {
let id_start = room.find("[").unwrap() + 1;
room[id_start..room.len() - 1].to_string()
}
fn get_freq_and_position(name: &str) -> HashMap<char, i32> {
let mut freq = HashMap::new();
for char in name.chars() {
if char == '-' {
continue;
}
freq.entry(char)
.and_modify(|count| {
*count += 1;
})
.or_insert(1);
}
freq
}
#[cfg(test)]
mod tests {
use super::{rot, *};
const INPUT: &str = "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]";
#[test]
fn part1() {
let result = process_part1(INPUT);
assert_eq!(result, 1514);
}
#[test]
fn part2() {
let res = rot("qzmt-zixmtkozy-ivhz", 343);
assert_eq!(res, "very encrypted name".to_string());
}
}

View File

@@ -3,3 +3,5 @@ pub mod d1;
pub mod d2;
pub mod d3;
pub mod d4;