Compare commits

..

7 Commits

Author SHA1 Message Date
6a8a7a9ad1
pre-commit update 2024-12-13 02:22:55 -08:00
1a6d37f4f3
clippies 2024-12-13 02:17:57 -08:00
35637cece1
readme 2024-12-13 02:15:41 -08:00
ebf5a0a489
day13: complete solution 2024-12-13 02:12:18 -08:00
4aa7e9f43c
day3: perf - branchless 2024-12-12 17:56:28 -08:00
a5439062a4
day3: performance - avoid converting &[u8] to &str 2024-12-12 17:38:42 -08:00
3658183deb
day7: performance. DFS with pruning. 2024-12-12 16:02:13 -08:00
36 changed files with 561 additions and 63 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ input
flamegraph.svg
perf.data*
guesses
.aoc_tiles/*
!.aoc_tiles/tiles/

17
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,17 @@
repos:
- repo: https://github.com/LiquidFun/aoc_tiles
rev: 0.6.2
hooks:
- id: aoc-tiles
# Optionally use these arguments. Auto add tiles to git adds the tiles to git,
# possibly amends your commit by creating the tile images and updating the README.
# Language sorting shows the preference of the order of the languages to use.
# Exclude paterns are globs which can be used to exclude files when creating
# the tiles. See the customization section in the README for more flags.
# Simply remove the comments (#) below for args and the flags you want.
args:
- --auto-add-tiles-to-git=amend
- --create-all-days
- --overwrite-year=2024
# - --language-sorting=jl,kt,py,rs
# - --exclude-patterns=2021/*/*.apl,2021/*/*.py,2021/*/*.cpp

272
Cargo.lock generated
View File

@ -2,6 +2,18 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -11,6 +23,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "aoc-runner"
version = "0.3.0"
@ -46,7 +64,9 @@ version = "0.1.0"
dependencies = [
"aoc-runner",
"aoc-runner-derive",
"atoi",
"bitflags",
"cached",
"grid",
"itertools",
"rayon",
@ -55,12 +75,66 @@ dependencies = [
"thread_local",
]
[[package]]
name = "atoi"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
dependencies = [
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "cached"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae"
dependencies = [
"ahash",
"cached_proc_macro",
"cached_proc_macro_types",
"hashbrown",
"once_cell",
"thiserror",
"web-time",
]
[[package]]
name = "cached_proc_macro"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]]
name = "cached_proc_macro_types"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -92,16 +166,73 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "darling"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.90",
]
[[package]]
name = "darling_macro"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.90",
]
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "grid"
version = "0.1.0"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "itertools"
version = "0.13.0"
@ -117,12 +248,37 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "js-sys"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.2"
@ -240,6 +396,12 @@ dependencies = [
"serde",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "1.0.109"
@ -262,6 +424,26 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]]
name = "thread_local"
version = "1.1.8"
@ -277,3 +459,93 @@ name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasm-bindgen"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn 2.0.90",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
]

View File

@ -6,7 +6,9 @@ edition = "2021"
[dependencies]
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
atoi = "2.0.0"
bitflags = "2.6.0"
cached = "0.54.0"
grid = { version = "0.1.0", path = "utils/grid" }
itertools = "0.13.0"
rayon = "1.10.0"

80
README.md Normal file
View File

@ -0,0 +1,80 @@
<!-- AOC TILES BEGIN -->
<h1 align="center">
2024 - 26 ⭐ - Rust
</h1>
<a href="src/day1.rs">
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
</a>
<a href="src/day2.rs">
<img src=".aoc_tiles/tiles/2024/02.png" width="161px">
</a>
<a href="src/day3.rs">
<img src=".aoc_tiles/tiles/2024/03.png" width="161px">
</a>
<a href="src/day4.rs">
<img src=".aoc_tiles/tiles/2024/04.png" width="161px">
</a>
<a href="src/day5.rs">
<img src=".aoc_tiles/tiles/2024/05.png" width="161px">
</a>
<a href="src/day6.rs">
<img src=".aoc_tiles/tiles/2024/06.png" width="161px">
</a>
<a href="src/day7.rs">
<img src=".aoc_tiles/tiles/2024/07.png" width="161px">
</a>
<a href="src/day8.rs">
<img src=".aoc_tiles/tiles/2024/08.png" width="161px">
</a>
<a href="src/day9.rs">
<img src=".aoc_tiles/tiles/2024/09.png" width="161px">
</a>
<a href="src/day10.rs">
<img src=".aoc_tiles/tiles/2024/10.png" width="161px">
</a>
<a href="src/day11.rs">
<img src=".aoc_tiles/tiles/2024/11.png" width="161px">
</a>
<a href="src/day12.rs">
<img src=".aoc_tiles/tiles/2024/12.png" width="161px">
</a>
<a href="src/day13.rs">
<img src=".aoc_tiles/tiles/2024/13.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/14.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/15.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/16.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/17.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/18.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/19.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/20.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/21.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/22.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/23.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/24.png" width="161px">
</a>
<a href="None">
<img src=".aoc_tiles/tiles/2024/25.png" width="161px">
</a>
<!-- AOC TILES END -->

141
src/day13.rs Normal file
View File

@ -0,0 +1,141 @@
use std::io::{BufRead, Lines};
use aoc_runner_derive::{aoc, aoc_generator};
use itertools::Itertools;
use regex::Regex;
#[derive(Debug, Clone)]
pub struct MachineAction(i64, i64);
#[derive(Debug, Clone)]
struct ClawMachine {
button_a: MachineAction,
button_b: MachineAction,
prize: (i64, i64),
}
impl ClawMachine {
fn consume_from_input<T: BufRead>(input: &mut Lines<T>) -> Option<Self> {
// consume any empty lines at the front
let ofs_re = Regex::new(r"X([+-]\d+), Y([+-]\d+)").unwrap();
let prize_re = Regex::new(r"X=(\d+), Y=(\d+)").unwrap();
// consume 3 lines - a, b, prize
if let Some((a_line, b_line, prize_line)) = input
.filter(|l| l.as_ref().is_ok_and(|l| !l.is_empty()))
.take(3)
.map(|l| l.unwrap())
.collect_tuple()
{
let a_caps = ofs_re.captures(&a_line).unwrap();
let b_caps = ofs_re.captures(&b_line).unwrap();
let prize_caps = prize_re.captures(&prize_line).unwrap();
let button_a = MachineAction(
a_caps.get(1).unwrap().as_str().parse().unwrap(),
a_caps.get(2).unwrap().as_str().parse().unwrap(),
);
let button_b = MachineAction(
b_caps.get(1).unwrap().as_str().parse().unwrap(),
b_caps.get(2).unwrap().as_str().parse().unwrap(),
);
let prize = (
prize_caps.get(1).unwrap().as_str().parse().unwrap(),
prize_caps.get(2).unwrap().as_str().parse().unwrap(),
);
Some(Self {
button_a,
button_b,
prize,
})
} else {
None
}
}
fn cost(moves: (i64, i64)) -> i64 {
moves.0 * 3 + moves.1
}
fn cheapest_prize(&self) -> Option<i64> {
let remainder_a = (self.button_b.0 * self.prize.1 - self.button_b.1 * self.prize.0)
% (self.button_b.0 * self.button_a.1 - self.button_a.0 * self.button_b.1);
let a = (self.button_b.0 * self.prize.1 - self.button_b.1 * self.prize.0)
/ (self.button_b.0 * self.button_a.1 - self.button_a.0 * self.button_b.1);
let remainder_b = (self.prize.0 - (self.button_a.0 * a)) % self.button_b.0;
let b = (self.prize.0 - (self.button_a.0 * a)) / self.button_b.0;
if remainder_a == 0 && remainder_b == 0 {
Some(Self::cost((a, b)))
} else {
None
}
}
fn offset(&mut self, offset: i64) {
self.prize = (self.prize.0 + offset, self.prize.1 + offset)
}
}
#[derive(Debug, Clone)]
struct ClawMachines {
machines: Vec<ClawMachine>,
}
impl From<&[u8]> for ClawMachines {
fn from(input: &[u8]) -> Self {
let mut machines = Vec::new();
let mut lines = input.lines();
while let Some(machine) = ClawMachine::consume_from_input(&mut lines) {
machines.push(machine);
}
Self { machines }
}
}
#[aoc_generator(day13)]
fn parse(input: &[u8]) -> ClawMachines {
ClawMachines::from(input)
}
#[aoc(day13, part1)]
fn part1(machines: &ClawMachines) -> i64 {
machines.machines.iter().filter_map(|m| m.cheapest_prize()).sum()
}
#[aoc(day13, part2)]
fn part2(machines: &ClawMachines) -> i64 {
let mut machines = machines.clone();
machines
.machines
.iter_mut()
.filter_map(|m| {
m.offset(10000000000000);
m.cheapest_prize()
})
.sum()
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE: &[u8] = b"Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EXAMPLE)), 480);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EXAMPLE)), 875318608908);
}
}

View File

@ -1,4 +1,5 @@
use aoc_runner_derive::{aoc, aoc_generator};
use atoi::FromRadix10;
use regex::bytes::Regex;
use std::io::BufRead;
@ -9,36 +10,33 @@ pub fn get_input(input: &[u8]) -> Vec<String> {
// PROBLEM 1 solution
#[aoc(day3, part1)]
pub fn part1(input: &Vec<String>) -> u64 {
let mut sum = 0u64;
pub fn part1(input: &[String]) -> u64 {
let re = Regex::new(r"(?-u)mul\((\d+),(\d+)\)").unwrap();
for line in input {
let line = line.as_bytes();
for m in re.captures_iter(line) {
sum += std::str::from_utf8(&m[1]).unwrap().parse::<u64>().unwrap()
* std::str::from_utf8(&m[2]).unwrap().parse::<u64>().unwrap();
}
}
sum
input
.iter()
.map(|line| {
re.captures_iter(line.as_bytes())
.map(|m| u64::from_radix_10(&m[1]).0 * u64::from_radix_10(&m[2]).0)
.sum::<u64>()
})
.sum()
}
// PROBLEM 2 solution
#[aoc(day3, part2)]
pub fn part2(input: &Vec<String>) -> u64 {
pub fn part2(input: &[String]) -> u64 {
let mut sum = 0u64;
let mut do_mul = true;
let mut do_mul: u64 = 1;
let re = Regex::new(r"(?-u)(do\(\)|don't\(\)|mul\((\d+),(\d+)\))").unwrap();
for line in input {
let line = line.as_bytes();
for m in re.captures_iter(line) {
match std::str::from_utf8(&m[1]).unwrap() {
"do()" => do_mul = true,
"don't()" => do_mul = false,
_ if do_mul => {
sum += std::str::from_utf8(&m[2]).unwrap().parse::<u64>().unwrap()
* std::str::from_utf8(&m[3]).unwrap().parse::<u64>().unwrap()
match &m[1] {
b"do()" => do_mul = 1,
b"don't()" => do_mul = 0,
_ => {
sum += u64::from_radix_10(&m[2]).0 * u64::from_radix_10(&m[3]).0 * do_mul;
}
_ => {}
}
}
}

View File

@ -65,10 +65,7 @@ impl OrderingRules {
}
}
fn is_sorted(&self, a: u64, b: u64) -> bool {
match self.pairs.get(&(a, b)) {
Some(Ordering::Less) | Some(Ordering::Equal) => true,
_ => false,
}
matches!(self.pairs.get(&(a, b)), Some(Ordering::Less) | Some(Ordering::Equal))
}
}

View File

@ -1,5 +1,4 @@
use aoc_runner_derive::{aoc, aoc_generator};
use itertools::Itertools;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use std::io::{BufRead, Lines};
@ -27,7 +26,6 @@ impl From<&str> for Calibration {
#[derive(Debug)]
pub struct Calibrations {
cals: Vec<Calibration>,
longest_cal: usize,
}
#[derive(Debug, Copy, Clone)]
@ -49,64 +47,51 @@ impl Operator {
impl<T: BufRead> From<Lines<T>> for Calibrations {
fn from(input: Lines<T>) -> Self {
let mut cals = Vec::new();
let mut longest_cal = 0;
for line in input.map(|l| l.unwrap()) {
let cal: Calibration = line.as_str().into();
longest_cal = std::cmp::max(longest_cal, cal.numbers.len());
cals.push(cal);
}
Self { cals, longest_cal }
let cals = input.map(|l| l.unwrap().as_str().into()).collect();
Self { cals }
}
}
impl Calibrations {
fn make_operator_sets(operators: &[Operator], n_opers: usize) -> Vec<Vec<Vec<Operator>>> {
(0..n_opers)
.map(|k| {
std::iter::repeat_n(operators.iter().copied(), k)
.multi_cartesian_product()
.collect()
})
.collect()
}
fn check_oper_set(cal: &Calibration, oper_set: &[Operator]) -> bool {
let accum = oper_set
.iter()
.zip(cal.numbers.iter().skip(1))
.fold(cal.numbers[0], |accum, (oper, val)| oper.exec(accum, *val));
accum == cal.result
}
fn possible(&self, operators: &[Operator]) -> u64 {
let operator_sets = Calibrations::make_operator_sets(operators, self.longest_cal);
self.cals
.par_iter()
.map(|cal| {
let n_opers = cal.numbers.len() - 1;
if operator_sets[n_opers]
.par_iter()
.find_any(|oper_set| Self::check_oper_set(cal, oper_set))
.is_some()
{
return cal.result;
}
0
})
.map(|cal| eval_calibration(operators, cal.result, cal.numbers[0], &cal.numbers[1..]))
.map(|result| result.unwrap_or(0))
.sum()
}
}
fn eval_calibration(operators: &[Operator], expect: u64, left: u64, right: &[u64]) -> Option<u64> {
if left > expect {
// all operations make the number larger, so this branch is hopeless, early exit
return None;
}
if right.is_empty() {
// base case - no further operations
if left == expect {
return Some(left);
} else {
return None;
}
}
operators
.iter()
.map(|oper| eval_calibration(operators, expect, oper.exec(left, right[0]), &right[1..]))
.find_map(|result| result)
}
// PROBLEM 1 solution
#[aoc(day7, part1)]
pub fn part1(cals: &Calibrations) -> u64 {
let operators = [Operator::Add, Operator::Multiply];
let operators = [Operator::Multiply, Operator::Add];
cals.possible(&operators)
}
// PROBLEM 2 solution
#[aoc(day7, part2)]
pub fn part2(cals: &Calibrations) -> u64 {
let operators = [Operator::Add, Operator::Multiply, Operator::Concatenate];
let operators = [Operator::Multiply, Operator::Add, Operator::Concatenate];
cals.possible(&operators)
}

View File

@ -12,5 +12,6 @@ pub mod day9;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;
aoc_lib! { year = 2024 }

3
src/main.rs Normal file
View File

@ -0,0 +1,3 @@
use aoc_runner_derive::aoc_main;
aoc_main!{ lib = aoc2024 }