Compare commits

...

2 Commits

Author SHA1 Message Date
Drew Galbraith c3262996fa Reduce complexity of day 15. Runtime 4s -> 0.01s 2023-12-15 14:36:49 -08:00
Drew Galbraith 9df32a9067 Day 15 works. 2023-12-15 14:23:15 -08:00
5 changed files with 116 additions and 0 deletions

18
Cargo.lock generated
View File

@ -5,3 +5,21 @@ version = 3
[[package]] [[package]]
name = "aoc23" name = "aoc23"
version = "0.1.0" version = "0.1.0"
dependencies = [
"itertools",
]
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
itertools = "0.12.0"

1
input/day15.txt Normal file

File diff suppressed because one or more lines are too long

93
src/day15.rs Normal file
View File

@ -0,0 +1,93 @@
use std::collections::HashMap;
use std::io;
fn hash(s: &str) -> u64 {
let mut acc = 0;
for c in s.chars() {
acc += (c as u8) as u64;
acc *= 17;
acc %= 256;
}
acc as u64
}
pub fn hash_sequence() -> u64 {
let mut buffer = String::new();
io::stdin().read_line(&mut buffer).unwrap();
buffer.trim().split(',').map(hash).sum()
}
enum Op<'a> {
Add(&'a str, u64),
Rem(&'a str),
}
fn parseop<'a>(op: &'a str) -> Op<'a> {
if op.ends_with('-') {
Op::Rem(&op[0..op.len() - 1])
} else {
let ind = op.find('=').unwrap();
Op::Add(&op[0..ind], op[ind + 1..].parse().expect("Could not parse"))
}
}
fn parse<'a>(ops: &Vec<&'a str>) -> Vec<Op<'a>> {
ops.iter().map(|s| parseop(*s)).collect()
}
fn condense<'a>(ops: &Vec<Op<'a>>) -> Vec<Op<'a>> {
let mut last_delete_map = HashMap::new();
ops.iter().enumerate().for_each(|(i, op)| {
if let Op::Rem(opstr) = op {
last_delete_map.insert(opstr, i);
}
});
let remove_deletes = ops.iter().enumerate().filter(|(i, op)| match op {
Op::Rem(_) => false,
Op::Add(opstr, _) => !last_delete_map.get(opstr).is_some_and(|j| j > i),
});
let mut last_value_map = HashMap::new();
remove_deletes.clone().for_each(|(_, op)| {
if let Op::Add(s, v) = op {
last_value_map.insert(s, v);
}
});
let map_to_last = remove_deletes.filter_map(|(_, op)| {
if let Op::Add(opstr, _) = op {
match last_value_map.remove(opstr) {
Some(v) => Some(Op::Add(opstr, *v)),
None => None,
}
} else {
None
}
});
map_to_last.collect()
}
fn perform_ops(ops: &Vec<&str>) -> u64 {
let reduced = condense(&parse(ops));
let mut sum = 0;
let mut boxes = vec![1; 256];
for r in reduced {
if let Op::Add(op, val) = r {
let h = hash(op);
let slot = boxes[h as usize];
boxes[h as usize] += 1;
sum += (h + 1) * slot * val;
}
}
sum
}
pub fn hash_map() -> u64 {
let mut buffer = String::new();
io::stdin().read_line(&mut buffer).unwrap();
perform_ops(&buffer.trim().split(',').collect())
}

View File

@ -6,6 +6,7 @@ mod day11;
mod day12; mod day12;
mod day13; mod day13;
mod day14; mod day14;
mod day15;
mod day2; mod day2;
mod day3; mod day3;
mod day4; mod day4;
@ -50,6 +51,8 @@ fn main() {
"day13b" => println!("Summary: {}", day13::summarize(true)), "day13b" => println!("Summary: {}", day13::summarize(true)),
"day14a" => println!("Load: {}", day14::total_load()), "day14a" => println!("Load: {}", day14::total_load()),
"day14b" => println!("Load: {}", day14::total_load_many_cycles()), "day14b" => println!("Load: {}", day14::total_load_many_cycles()),
"day15a" => println!("Sum: {}", day15::hash_sequence()),
"day15b" => println!("Sum: {}", day15::hash_map()),
_ => println!("Unrecognized day: {}", args[1]), _ => println!("Unrecognized day: {}", args[1]),
} }
} }