Compare commits
7 Commits
38cba37b06
...
6a8a7a9ad1
Author | SHA1 | Date | |
---|---|---|---|
6a8a7a9ad1 | |||
1a6d37f4f3 | |||
35637cece1 | |||
ebf5a0a489 | |||
4aa7e9f43c | |||
a5439062a4 | |||
3658183deb |
BIN
.aoc_tiles/tiles/2024/01.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
.aoc_tiles/tiles/2024/02.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
.aoc_tiles/tiles/2024/03.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
.aoc_tiles/tiles/2024/04.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
.aoc_tiles/tiles/2024/05.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
.aoc_tiles/tiles/2024/06.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
.aoc_tiles/tiles/2024/07.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
.aoc_tiles/tiles/2024/08.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
.aoc_tiles/tiles/2024/09.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
.aoc_tiles/tiles/2024/10.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
.aoc_tiles/tiles/2024/11.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
.aoc_tiles/tiles/2024/12.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
.aoc_tiles/tiles/2024/13.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
.aoc_tiles/tiles/2024/14.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
.aoc_tiles/tiles/2024/15.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
.aoc_tiles/tiles/2024/16.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
.aoc_tiles/tiles/2024/17.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
.aoc_tiles/tiles/2024/18.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
.aoc_tiles/tiles/2024/19.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
.aoc_tiles/tiles/2024/20.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
.aoc_tiles/tiles/2024/21.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
.aoc_tiles/tiles/2024/22.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
.aoc_tiles/tiles/2024/23.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
.aoc_tiles/tiles/2024/24.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
.aoc_tiles/tiles/2024/25.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
2
.gitignore
vendored
@ -3,3 +3,5 @@ input
|
||||
flamegraph.svg
|
||||
perf.data*
|
||||
guesses
|
||||
.aoc_tiles/*
|
||||
!.aoc_tiles/tiles/
|
||||
|
17
.pre-commit-config.yaml
Normal 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
@ -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",
|
||||
]
|
||||
|
@ -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
@ -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
@ -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);
|
||||
}
|
||||
}
|
36
src/day3.rs
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
65
src/day7.rs
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
@ -0,0 +1,3 @@
|
||||
use aoc_runner_derive::aoc_main;
|
||||
|
||||
aoc_main!{ lib = aoc2024 }
|