This commit is contained in:
sepia 2024-12-13 14:50:19 -06:00
parent 04f4adc410
commit a91b120155
5 changed files with 255 additions and 1 deletions

144
Cargo.lock generated
View File

@ -23,6 +23,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"dotenvy", "dotenvy",
"itertools", "itertools",
"pest",
"pest_derive",
"rayon", "rayon",
"regex", "regex",
"reqwest", "reqwest",
@ -76,6 +78,15 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.16.0" version = "3.16.0"
@ -119,6 +130,15 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.8.5" version = "0.8.5"
@ -144,6 +164,26 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.5" version = "0.2.5"
@ -278,6 +318,16 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.15" version = "0.2.15"
@ -750,6 +800,51 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.15" version = "0.2.15"
@ -1034,6 +1129,17 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
@ -1148,6 +1254,26 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "thiserror"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.7.6" version = "0.7.6"
@ -1238,6 +1364,18 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.14" version = "1.0.14"
@ -1279,6 +1417,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "want" name = "want"
version = "0.3.1" version = "0.3.1"

View File

@ -6,6 +6,8 @@ edition = "2021"
[dependencies] [dependencies]
dotenvy = "0.15.7" dotenvy = "0.15.7"
itertools = "0.13.0" itertools = "0.13.0"
pest = "2.7.15"
pest_derive = "2.7.15"
rayon = "1.10.0" rayon = "1.10.0"
regex = "1.11.1" regex = "1.11.1"
reqwest = { version = "0.12.9", features = ["blocking"] } reqwest = { version = "0.12.9", features = ["blocking"] }

95
src/day13.rs Normal file
View File

@ -0,0 +1,95 @@
use itertools::Itertools;
use pest::{
iterators::{Pair, Pairs},
Parser,
};
const OFFSETS: (u64, u64) = (10000000000000, 10000000000000);
pub fn day13() {
let cost: f64 = parse_machines(&crate::input(13))
.iter()
.filter_map(|machine| {
let (c, d) = machine.prize;
let (a, b) = &machine.buttons;
let bn = (d - c * a.y / a.x) / (b.y - b.x * a.y / a.x);
let an = (c - bn * b.x) / a.x;
// Both solutions must be whole numbers
let winnable = [an, bn]
.iter()
.all(|&n| n >= -0.01 && (n.round() - n).abs() <= 0.01);
if winnable {
Some(an.round() * a.cost + bn.round() * b.cost)
} else {
None
}
})
.sum();
println!("Minimum Cost: {:?}", cost);
}
struct Machine {
buttons: (Button, Button),
prize: (f64, f64),
}
struct Button {
cost: f64,
x: f64,
y: f64,
}
#[derive(pest_derive::Parser)]
#[grammar = "grammars/day13.pest"]
struct MachinesParser {}
fn parse_machines(input: &str) -> Vec<Machine> {
MachinesParser::parse(Rule::machines, input)
.unwrap()
.nth(0)
.unwrap()
.into_inner()
.map(Pair::<'_, Rule>::into_inner)
.map(Machine::parse)
.collect()
}
impl Machine {
fn parse(input: Pairs<'_, Rule>) -> Self {
let (a, b, prize) = input.map(|p| p.into_inner()).collect_tuple().unwrap();
let buttons = [a, b]
.into_iter()
.map(Button::parse)
.collect_tuple()
.unwrap();
let prize = prize
.map(|n| n.as_str().parse::<u64>().unwrap())
.collect_tuple()
.map(|(x, y)| ((x + OFFSETS.0) as f64, (y + OFFSETS.1) as f64))
.unwrap();
Self { buttons, prize }
}
}
impl Button {
fn parse(input: Pairs<'_, Rule>) -> Self {
let (t, x, y) = input.collect_tuple().unwrap();
let cost = match t.as_str() {
"A" => 3.,
"B" => 1.,
_ => unreachable!(),
};
Self {
x: x.as_str().parse::<f64>().unwrap(),
y: y.as_str().parse::<f64>().unwrap(),
cost,
}
}
}

11
src/grammars/day13.pest Normal file
View File

@ -0,0 +1,11 @@
_WHITESPACE = _{ " " }
newline = _{ "\n" }
number = { ASCII_DIGIT+ }
button_type = { "A" | "B" }
button = { "Button " ~ button_type ~ ": X+" ~ number ~ ", Y+" ~ number ~ newline }
prize = { "Prize: X=" ~ number ~ ", Y=" ~ number ~ newline }
machine = { button ~ button ~ prize ~ newline? }
eoi = _{ !ANY }
machines = { SOI ~ machine+ ~ eoi }

View File

@ -22,10 +22,12 @@ mod day9;
mod day10; mod day10;
#[allow(dead_code)] #[allow(dead_code)]
mod day11; mod day11;
#[allow(dead_code)]
mod day12; mod day12;
mod day13;
fn main() { fn main() {
day12::day12(); day13::day13();
} }
pub fn input(day: u8) -> String { pub fn input(day: u8) -> String {