mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement 2023 day 15 part 1
This commit is contained in:
@@ -9,6 +9,7 @@ edition = "2021"
|
|||||||
aho-corasick = "1.1.2"
|
aho-corasick = "1.1.2"
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
clap = { version = "4.4.8", features = ["derive"] }
|
clap = { version = "4.4.8", features = ["derive"] }
|
||||||
|
linked-hash-map = "0.5.6"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
num-integer = "0.1.45"
|
num-integer = "0.1.45"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
use linked_hash_map::LinkedHashMap;
|
||||||
|
use nom::branch::alt;
|
||||||
|
use nom::bytes::complete::tag;
|
||||||
|
use nom::bytes::complete::take_till;
|
||||||
|
|
||||||
|
use nom::combinator::map;
|
||||||
|
use nom::multi::separated_list1;
|
||||||
|
use nom::sequence::separated_pair;
|
||||||
|
use nom::sequence::terminated;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
use crate::common::parse_input;
|
||||||
|
|
||||||
fn trim(input: &[u8]) -> &[u8] {
|
fn trim(input: &[u8]) -> &[u8] {
|
||||||
let whitespace = input
|
let whitespace = input
|
||||||
.iter()
|
.iter()
|
||||||
@@ -8,10 +21,10 @@ fn trim(input: &[u8]) -> &[u8] {
|
|||||||
&input[..(input.len() - whitespace)]
|
&input[..(input.len() - whitespace)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash(input: &[u8]) -> u32 {
|
fn hash(input: &[u8]) -> u8 {
|
||||||
input
|
input
|
||||||
.iter()
|
.iter()
|
||||||
.fold(0, |cur, &c| ((cur + u32::from(c)) * 17) % 256)
|
.fold(0, |cur, &c| cur.wrapping_add(c).wrapping_mul(17))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> anyhow::Result<String> {
|
pub fn part1(input: &[u8]) -> anyhow::Result<String> {
|
||||||
@@ -19,13 +32,57 @@ pub fn part1(input: &[u8]) -> anyhow::Result<String> {
|
|||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.split(|&c| c == b',')
|
.split(|&c| c == b',')
|
||||||
.map(hash)
|
.map(|word| u32::from(hash(word)))
|
||||||
.sum::<u32>()
|
.sum::<u32>()
|
||||||
.to_string())
|
.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> anyhow::Result<String> {
|
enum Command<'a> {
|
||||||
anyhow::bail!("Not implemented")
|
Add(&'a [u8], u32),
|
||||||
|
Remove(&'a [u8]),
|
||||||
|
}
|
||||||
|
fn parse_commands(i: &[u8]) -> IResult<&[u8], Vec<Command>> {
|
||||||
|
fn is_op(c: u8) -> bool {
|
||||||
|
c == b'=' || c == b'-'
|
||||||
|
}
|
||||||
|
|
||||||
|
separated_list1(
|
||||||
|
tag(","),
|
||||||
|
alt((
|
||||||
|
map(
|
||||||
|
separated_pair(take_till(is_op), tag("="), nom::character::complete::u32),
|
||||||
|
|(a, b)| Command::Add(a, b),
|
||||||
|
),
|
||||||
|
map(terminated(take_till(is_op), tag("-")), Command::Remove),
|
||||||
|
)),
|
||||||
|
)(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: &[u8]) -> anyhow::Result<String> {
|
||||||
|
let commands = parse_input(trim(input), parse_commands)?;
|
||||||
|
let mut boxes = [(); 256].map(|_| LinkedHashMap::new());
|
||||||
|
|
||||||
|
for command in &commands {
|
||||||
|
match command {
|
||||||
|
Command::Add(identifier, focal_len) => {
|
||||||
|
*boxes[hash(identifier) as usize]
|
||||||
|
.entry(*identifier)
|
||||||
|
.or_default() = *focal_len;
|
||||||
|
}
|
||||||
|
Command::Remove(identifier) => {
|
||||||
|
boxes[hash(identifier) as usize].remove(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut total = 0;
|
||||||
|
for (i, b) in boxes.iter().enumerate() {
|
||||||
|
for (slot, &focal_len) in b.values().enumerate() {
|
||||||
|
total += (i as u32 + 1) * (slot as u32 + 1) * focal_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(total.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -43,4 +100,9 @@ mod tests {
|
|||||||
fn sample_part1() {
|
fn sample_part1() {
|
||||||
assert_eq!("1320", part1(SAMPLE).unwrap());
|
assert_eq!("1320", part1(SAMPLE).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part2() {
|
||||||
|
assert_eq!("145", part2(SAMPLE).unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user