This commit is contained in:
Shoofle 2024-12-13 10:55:51 -05:00
parent 14c1e412eb
commit dda3e2d511
3 changed files with 108 additions and 2 deletions

View File

@ -190,6 +190,7 @@ fn spread_over_side_and_cache(
// look at each side in the wavefront // look at each side in the wavefront
for x in &wavefront { for x in &wavefront {
// if it's in a side that we already have cached, then we're done. // if it's in a side that we already have cached, then we're done.
// this loop is what makes this slow i bet
for existing_side in &cache { for existing_side in &cache {
if existing_side.contains(x) { if existing_side.contains(x) {
// return the cache unchanged. // return the cache unchanged.
@ -217,8 +218,8 @@ fn spread_over_side_and_cache(
} }
// add all the siddes in the wavefront to the accumulator. // add all the siddes in the wavefront to the accumulator.
for x in wavefront.drain() { for x in &wavefront {
accumulator.insert(x); accumulator.insert(*x);
} }
wavefront = new_wavefront; wavefront = new_wavefront;

7
day13/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "day13"
version = "0.1.0"
edition = "2021"
[dependencies]
regex = "1.11.1"

98
day13/src/main.rs Normal file
View File

@ -0,0 +1,98 @@
use regex::Regex;
use std::env;
use std::fs;
#[derive(Debug, Copy, Clone)]
struct Problem {
ax: i128, ay: i128,
bx: i128, by: i128,
px: i128, py: i128
}
fn main() {
println!("Hello, AoC day 13!");
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("wrong number of arguments!");
std::process::exit(1);
}
let file_path = &args[1];
let binding = fs::read_to_string(file_path)
.expect("should be able to read the file");
let records = binding
.split("\n\n");
let find_record = Regex::new(r"Button A: X\+([0-9]+), Y\+([0-9]+)
Button B: X\+([0-9]+), Y\+([0-9]+)
Prize: X=([0-9]+), Y=([0-9]+)").unwrap();
let mut games: Vec<Problem> = Vec::new();
for record in records {
let Some(caps) = find_record.captures(record) else {
continue;
};
games.push(Problem {
ax: caps[1].parse().unwrap(), ay: caps[2].parse().unwrap(),
bx: caps[3].parse().unwrap(), by: caps[4].parse().unwrap(),
px: caps[5].parse().unwrap(), py: caps[6].parse().unwrap()});
}
// part a
let mut sum = 0;
for p in &games {
let Some(cost) = solve_b(*p) else { continue; };
sum += cost;
}
println!("total coins required is {sum}");
// part b
for p in &mut games {
p.px += 10000000000000;
p.py += 10000000000000;
}
let mut sum = 0;
for p in &games {
let Some(cost) = solve_b(*p) else { continue; };
sum += cost;
}
println!("total coins required is {sum}");
}
fn solve(problem: Problem) -> Option<i128> {
let mut sol = 30_000;
for a in 0..100 {
for b in 0..100 {
if a * problem.ax + b * problem.bx == problem.px &&
a* problem.ay + b * problem.by == problem.py {
if 3*a + b < sol {
sol = 3*a + b;
}
}
}
}
if sol == 30_000 { return None; }
return Some(sol);
}
fn solve_b(p: Problem) -> Option<i128> {
let det_ab = p.ax*p.by - p.bx*p.ay;
if det_ab == 0 { return None; }
let a = (p.by*p.px - p.bx*p.py) / det_ab;
let b = (-p.ay*p.px+ p.ax*p.py) / det_ab;
if check((a, b), p) && a >= 0 && b >= 0 {
return Some(3*a + b);
}
return None;
}
fn check(s: (i128, i128), p: Problem) -> bool {
return s.0*p.ax + s.1*p.bx == p.px && s.0*p.ay + s.1*p.by == p.py;
}