2023 - Day 15
This commit is contained in:
parent
6416c98c73
commit
9004a8c891
1
2023/input/15/input
Normal file
1
2023/input/15/input
Normal file
File diff suppressed because one or more lines are too long
1
2023/input/15/test-1
Normal file
1
2023/input/15/test-1
Normal file
|
@ -0,0 +1 @@
|
|||
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
|
159
2023/src/bin/day15.rs
Normal file
159
2023/src/bin/day15.rs
Normal file
|
@ -0,0 +1,159 @@
|
|||
#![feature(test)]
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use anyhow::Result;
|
||||
use aoc::Solver;
|
||||
|
||||
// -- Runners --
|
||||
fn main() -> Result<()> {
|
||||
Day::solve()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn part1_test1() -> Result<()> {
|
||||
Day::test(Day::part1, "test-1", 1320)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_solution() -> Result<()> {
|
||||
Day::test(Day::part1, "input", 511416)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_test1() -> Result<()> {
|
||||
Day::test(Day::part2, "test-1", 145)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_solution() -> Result<()> {
|
||||
Day::test(Day::part2, "input", 290779)
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
extern crate test;
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part1_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part1, b)
|
||||
}
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part2_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part2, b)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Action<'a> {
|
||||
Add { label: &'a str, focal_length: usize },
|
||||
Remove { label: &'a str },
|
||||
}
|
||||
|
||||
impl<'a> Action<'a> {
|
||||
fn index(&self) -> usize {
|
||||
match self {
|
||||
Action::Add { label, .. } | Action::Remove { label } => label
|
||||
.chars()
|
||||
.map(|c| c as usize)
|
||||
.fold(0, |acc, num| ((acc + num) * 17) % 256),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Solution --
|
||||
pub struct Day;
|
||||
impl aoc::Solver for Day {
|
||||
type Output1 = usize;
|
||||
type Output2 = usize;
|
||||
|
||||
fn day() -> u8 {
|
||||
15
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> Self::Output1 {
|
||||
input
|
||||
.trim()
|
||||
.split(',')
|
||||
.map(|sequence| {
|
||||
sequence
|
||||
.chars()
|
||||
.map(|c| c as usize)
|
||||
.fold(0, |acc, num| ((acc + num) * 17) % 256)
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> Self::Output2 {
|
||||
let actions: Vec<_> = input
|
||||
.trim()
|
||||
.split(',')
|
||||
.map(|sequence| {
|
||||
if sequence.ends_with('-') {
|
||||
let label = sequence.split_once('-').unwrap().0;
|
||||
|
||||
Action::Remove { label }
|
||||
} else {
|
||||
let (label, focal_length) = sequence.split_once('=').unwrap();
|
||||
|
||||
let focal_length = focal_length.parse().unwrap();
|
||||
|
||||
Action::Add {
|
||||
label,
|
||||
focal_length,
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut boxes: [Vec<(&str, usize)>; 256] = std::array::from_fn(|_| Vec::new());
|
||||
|
||||
for action in &actions {
|
||||
let index = action.index();
|
||||
|
||||
match action {
|
||||
Action::Add {
|
||||
label,
|
||||
focal_length,
|
||||
} => {
|
||||
// NOTE: Using a library like OrderedMap would make this trivially easy
|
||||
if let Some(position) = boxes[index]
|
||||
.iter()
|
||||
.position(|lens| lens.0.cmp(label) == Ordering::Equal)
|
||||
{
|
||||
// If a lens with this label is already in the box, replace it
|
||||
boxes[index][position].1 = *focal_length;
|
||||
} else {
|
||||
// Otherwise add it to the end of the box
|
||||
boxes[index].push((label, *focal_length));
|
||||
}
|
||||
}
|
||||
Action::Remove { label } => {
|
||||
if let Some(position) = boxes[index]
|
||||
.iter()
|
||||
.position(|lens| lens.0.cmp(label) == Ordering::Equal)
|
||||
{
|
||||
// A lens with the label exists, remove it
|
||||
boxes[index].remove(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boxes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, b)| {
|
||||
b.iter()
|
||||
.enumerate()
|
||||
.map(|(position, (_, focal_length))| {
|
||||
(1 + index) * (1 + position) * focal_length
|
||||
})
|
||||
.sum::<usize>()
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user