Day 15 Complete -> Nice and easy :)

This commit is contained in:
Luke Else 2023-12-15 08:45:08 +00:00
parent 505ea3771a
commit 0bead087c3
5 changed files with 95 additions and 10 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

View File

@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

View File

@ -22,7 +22,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
Box::new(day12::Day12 {}),
Box::new(day13::Day13 {}),
Box::new(day14::Day14 {}),
// Box::new(day15::Day15 {}),
Box::new(day15::Day15 {}),
// Box::new(day16::Day16 {}),
// Box::new(day17::Day17 {}),
// Box::new(day18::Day18 {}),

View File

@ -1,3 +1,5 @@
use std::str;
use super::Solution;
pub struct Day15 {}
@ -5,16 +7,42 @@ pub struct Day15 {}
impl Solution for Day15 {
fn part1(
&self,
_input: &mut Vec<String>,
input: &mut Vec<String>,
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
Ok(Box::new("Ready"))
}
let pre_hashes = input[0].split(',').collect::<Vec<_>>();
let ans = pre_hashes
.iter()
.map(|h| self.hash(h, 17, 256))
.sum::<u32>();
Ok(Box::new(ans))
}
fn part2(
&self,
_input: &mut Vec<String>,
input: &mut Vec<String>,
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
Ok(Box::new("Ready"))
let pre_hashes = input[0].split(',').collect::<Vec<_>>();
let mut boxes: Vec<Vec<(String, u32)>> = vec![vec![]; 256];
pre_hashes
.iter()
.for_each(|ins| self.sort_lenses(&mut boxes, ins));
let ans = boxes
.iter()
.enumerate()
.map(|(box_num, lenses)| {
lenses
.iter()
.enumerate()
.map(|(lens_num, (_, focal_length))| {
self.get_focussing_power(box_num + 1, lens_num + 1, *focal_length)
})
.sum::<u32>()
})
.sum::<u32>();
Ok(Box::new(ans))
}
fn get_day(&self) -> u8 {
@ -22,7 +50,53 @@ impl Solution for Day15 {
}
}
impl Day15 {}
impl Day15 {
/// function to generate the predefined hash outlined in the challenge
fn hash(&self, input: &str, seed: u32, divisor: u32) -> u32 {
let mut hash = 0u32;
for c in input.bytes() {
hash += c as u32;
hash *= seed;
hash = hash % divisor;
}
hash
}
/// Sort the lenses in the boxes based in instructions given
fn sort_lenses(&self, boxes: &mut Vec<Vec<(String, u32)>>, instruction: &str) {
let bytes = instruction.as_bytes();
// '-' Logic or '=' Logic
if bytes[bytes.len() - 1] == b'-' {
let label = str::from_utf8(&bytes[..bytes.len() - 1 as usize]).unwrap();
let hash = self.hash(label, 17, 256);
boxes[hash as usize].retain(|(lens, _)| lens != label);
} else {
let mut parts = instruction.split("=");
let label = parts.next().unwrap();
let focal_length = parts.next().unwrap().parse::<u32>().unwrap();
let hash = self.hash(label, 17, 256);
let old_position = boxes[hash as usize]
.iter()
.position(|(existing_label, _)| existing_label == label);
if let Some(old_position) = old_position {
boxes[hash as usize][old_position] = (label.to_string(), focal_length);
} else {
boxes[hash as usize].push((label.to_string(), focal_length));
}
}
}
/// Function that determines the focussing power of a lens given its box,
/// position and focal length
fn get_focussing_power(&self, box_num: usize, slot_num: usize, focal_length: u32) -> u32 {
box_num as u32 * slot_num as u32 * focal_length
}
}
/// Test from puzzle input
#[cfg(test)]
@ -44,7 +118,7 @@ mod test {
.unwrap()
.to_string();
assert_eq!(answer, "Ready");
assert_eq!(answer, "1320");
}
#[test]
@ -61,6 +135,14 @@ mod test {
.unwrap()
.to_string();
assert_eq!(answer, "Ready");
assert_eq!(answer, "145");
}
#[test]
fn hash_test() {
let challenge = day15::Day15 {};
// Test the hash
assert_eq!(challenge.hash("HASH", 17, 256), 52);
}
}