repo setup for 2025

This commit is contained in:
2025-11-30 22:48:56 -08:00
commit 5587b3c0f4
11 changed files with 1425 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
**/target
input
flamegraph.svg
perf.data*
guesses
.aoc_tiles/*
!.aoc_tiles/tiles/

725
Cargo.lock generated Normal file
View File

@@ -0,0 +1,725 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d21ef9204ad206a5a3e918e9920da04e1118ad91ce4f23570be964b9d6b9dfcb"
[[package]]
name = "aoc-runner-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba8b944269d3fee645d281b1335e1797044db497bb02d0098cc3fdb8900069cc"
dependencies = [
"aoc-runner-internal",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "aoc-runner-internal"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "274b0ba7f3669a45ec0aaacf94eb032a749de880ab776091576cca94037c9982"
dependencies = [
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "aoc2025"
version = "0.1.0"
dependencies = [
"aoc-runner",
"aoc-runner-derive",
"atoi",
"bitflags",
"cached",
"colored",
"grid",
"indicatif",
"itertools",
"lazy_static",
"misc",
"nom",
"rayon",
"regex",
"rustc-hash",
"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.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "bumpalo"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[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.111",
]
[[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.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "colored"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
"windows-sys",
]
[[package]]
name = "console"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width",
"windows-sys",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "darling"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.111",
]
[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
"syn 2.0.111",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[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 = "indicatif"
version = "0.17.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
dependencies = [
"console",
"number_prefix",
"portable-atomic",
"rayon",
"unicode-width",
"web-time",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "misc"
version = "0.1.0"
dependencies = [
"num-traits",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "portable-atomic"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "regex"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "serde_json"
version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
"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.111",
]
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[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.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.111",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
dependencies = [
"unicode-ident",
]
[[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 = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]

27
Cargo.toml Normal file
View File

@@ -0,0 +1,27 @@
[package]
name = "aoc2025"
edition = "2021"
version = "0.1.0"
[dependencies]
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
atoi = "2.0.0"
bitflags = "2.6.0"
cached = "0.54.0"
colored = "2.1.0"
grid = {version = "0.1.0", path = "utils/grid"}
indicatif = { version = "0.17.9", features = ["rayon"] }
itertools = "0.13.0"
lazy_static = "1.5.0"
misc = {path = "utils/misc"}
nom = "7.1.3"
rayon = "1.10.0"
regex = "1.11.1"
rustc-hash = "2.1.0"
thread_local = "1.1.8"
[profile.release]
lto = true
opt-level = 3
overflow-checks = false

5
src/lib.rs Normal file
View File

@@ -0,0 +1,5 @@
pub mod day1;
use aoc_runner_derive::aoc_lib;
aoc_lib! { year = 2025 }

3
src/main.rs Normal file
View File

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

7
utils/grid/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "grid"
version = "0.1.0"

9
utils/grid/Cargo.toml Normal file
View File

@@ -0,0 +1,9 @@
[package]
name = "grid"
version = "0.1.0"
edition = "2021"
[dependencies]
[lib]
path = "lib.rs"

512
utils/grid/lib.rs Normal file
View File

@@ -0,0 +1,512 @@
use std::{
fmt::{Debug, Display, Formatter, Write},
io::{BufRead, Cursor},
iter::repeat_n,
mem::swap,
ops::{Add, AddAssign, Sub},
str::FromStr,
};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Coord2d {
pub x: i64,
pub y: i64,
}
pub trait AsCoord2d {
fn to_coord(self) -> Coord2d;
fn x(&self) -> i64;
fn y(&self) -> i64;
}
impl<T: AsCoord2d> Sub<T> for &Coord2d {
type Output = Coord2d;
fn sub(self, rhs: T) -> Self::Output {
Coord2d {
x: self.x() - rhs.x(),
y: self.y() - rhs.y(),
}
}
}
impl<T: AsCoord2d> Add<T> for &Coord2d {
type Output = Coord2d;
fn add(self, rhs: T) -> Self::Output {
Coord2d {
x: self.x() + rhs.x(),
y: self.y() + rhs.y(),
}
}
}
impl<T: AsCoord2d> Add<&T> for Coord2d {
type Output = Coord2d;
fn add(self, rhs: &T) -> Self::Output {
Coord2d {
x: self.x() + rhs.x(),
y: self.y() + rhs.y(),
}
}
}
impl AsCoord2d for Coord2d {
fn to_coord(self) -> Coord2d {
self
}
fn x(&self) -> i64 {
self.x
}
fn y(&self) -> i64 {
self.y
}
}
impl AsCoord2d for &Coord2d {
fn to_coord(self) -> Coord2d {
self.to_owned()
}
fn x(&self) -> i64 {
self.x
}
fn y(&self) -> i64 {
self.y
}
}
impl<T> AsCoord2d for (T, T)
where
T: Copy + TryInto<i64>,
<T as TryInto<i64>>::Error: Debug,
{
fn to_coord(self) -> Coord2d {
Coord2d {
x: self.0.try_into().unwrap(),
y: self.1.try_into().unwrap(),
}
}
fn x(&self) -> i64 {
self.0.try_into().unwrap()
}
fn y(&self) -> i64 {
self.1.try_into().unwrap()
}
}
impl<T> AsCoord2d for &(T, T)
where
T: Copy + TryInto<i64>,
<T as TryInto<i64>>::Error: Debug,
{
fn to_coord(self) -> Coord2d {
Coord2d {
x: self.0.try_into().unwrap(),
y: self.1.try_into().unwrap(),
}
}
fn x(&self) -> i64 {
self.0.try_into().unwrap()
}
fn y(&self) -> i64 {
self.1.try_into().unwrap()
}
}
impl From<Coord2d> for (i64, i64) {
fn from(value: Coord2d) -> Self {
(value.x, value.y)
}
}
#[derive(Debug)]
pub struct GridRowIter<'a, T> {
iter: std::slice::Iter<'a, T>,
}
impl<'a, T: Clone + Eq + PartialEq + Debug> GridRowIter<'a, T> {
fn new(grid: &'a Grid<T>, y: i64) -> Self {
let iter = grid.data[y as usize * grid.width()..(y as usize + 1) * grid.width()].iter();
Self { iter }
}
}
impl<'a, T> Iterator for GridRowIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[derive(Debug)]
pub struct CoordIter<'a, T> {
pos: usize,
grid: &'a Grid<T>,
}
impl<'a, T: Clone + Eq + PartialEq + Debug> Iterator for CoordIter<'a, T> {
type Item = Coord2d;
fn next(&mut self) -> Option<Self::Item> {
if self.pos < self.grid.data.len() {
self.grid.coord(self.pos as i64).into()
} else {
None
}
}
}
#[derive(Debug)]
pub struct GridColIter<'a, T> {
grid: &'a Grid<T>,
stride: usize,
cur: usize,
}
impl<'a, T: Clone + Eq + PartialEq + Debug> GridColIter<'a, T> {
fn new(grid: &'a Grid<T>, x: i64) -> Self {
Self {
grid,
stride: grid.width(),
cur: x as usize,
}
}
}
impl<'a, T: Clone + Eq + PartialEq + Debug> Iterator for GridColIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let cur = self.cur;
self.cur += self.stride;
if cur < self.grid.data.len() {
Some(&self.grid.data[cur])
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.grid.height() - 1, Some(self.grid.height() - 1))
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Grid<T> {
pub data: Vec<T>,
width: i64,
}
impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
/// Returns a new [Grid] with the same shape (width x height) as `self`, filled with `fill`
pub fn same_shape<NT: Clone + Eq + PartialEq + Debug>(&self, fill: NT) -> Grid<NT> {
Grid::with_shape(self.width(), self.height(), fill)
}
/// Returns a new [Grid] with the given shape (width x height), filled with `fill`
pub fn with_shape(width: usize, height: usize, fill: T) -> Self {
Self {
data: Vec::from_iter(repeat_n(fill, width * height)),
width: width as i64,
}
}
pub fn width(&self) -> usize {
self.width as usize
}
pub fn height(&self) -> usize {
self.data.len() / self.width()
}
pub fn pos<C: AsCoord2d>(&self, c: &C) -> i64 {
c.y() * self.width + c.x()
}
pub fn coord(&self, pos: i64) -> Option<Coord2d> {
if pos < 0 || pos >= self.data.len() as i64 {
None
} else {
Some(Coord2d {
x: pos % self.width,
y: pos / self.width,
})
}
}
// pub fn coord_iter(&self) -> CoordIter<_> {
// CoordIter { pos: 0, grid: self }
// }
pub fn is_valid<C: AsCoord2d>(&self, c: &C) -> bool {
if c.x() < 0 || c.x() >= self.width {
return false;
}
if c.y() < 0 || c.y() as usize >= self.height() {
return false;
}
return true;
}
fn valid_pos<C: AsCoord2d>(&self, c: &C) -> Option<usize> {
if c.x() < 0 || c.x() >= self.width {
return None;
}
if c.y() < 0 || c.y() as usize >= self.height() {
return None;
}
let pos = self.pos(c);
if pos < 0 || pos as usize >= self.data.len() {
return None;
}
self.pos(c).try_into().ok()
}
pub fn get<C: AsCoord2d>(&self, c: &C) -> Option<&T> {
match self.valid_pos(c) {
Some(pos) => Some(&self.data[pos]),
None => None,
}
}
pub fn get_mut<C: AsCoord2d>(&mut self, c: &C) -> Option<&mut T> {
match self.valid_pos(c) {
Some(pos) => Some(self.data.get_mut(pos).unwrap()),
None => None,
}
}
pub fn set<C: AsCoord2d>(&mut self, c: &C, mut val: T) -> Option<T> {
match self.valid_pos(c) {
Some(pos) => {
swap(&mut self.data[pos], &mut val);
Some(val)
}
None => None,
}
}
pub fn increment<'a, A, C: AsCoord2d>(&'a mut self, c: &C, i: A) -> Option<&'a T>
where
T: AddAssign<A>,
{
match self.valid_pos(c) {
Some(pos) => {
self.data[pos] += i;
Some(&self.data[pos])
}
None => None,
}
}
pub fn row(&self, y: i64) -> Option<&[T]> {
if y < self.height() as i64 && y >= 0 {
Some(&self.data[self.pos(&(0, y)) as usize..self.pos(&(self.width, y)) as usize])
} else {
None
}
}
pub fn row_iter(&self, y: i64) -> Option<GridRowIter<T>> {
if (y as usize) < self.height() {
Some(GridRowIter::new(self, y))
} else {
None
}
}
pub fn col(&self, x: i64) -> Option<Vec<&T>> {
if let Some(iter) = self.col_iter(x) {
Some(iter.collect())
} else {
None
}
}
pub fn col_iter(&self, x: i64) -> Option<GridColIter<T>> {
if (x as usize) < self.width() {
Some(GridColIter::new(self, x))
} else {
None
}
}
pub fn find(&self, haystack: &T) -> Option<Coord2d> {
self.coord(
self.data
.iter()
.enumerate()
.find_map(|(pos, val)| if val == haystack { Some(pos as i64) } else { None })
.unwrap_or(-1),
)
}
pub fn count(&self, haystack: &T) -> usize {
self.data.iter().filter(|item| *item == haystack).count()
}
pub fn forward_slice<C: AsCoord2d>(&self, start: &C, len: i64) -> Option<&[T]> {
let pos = (self.valid_pos(start), self.valid_pos(&(start.x() + len - 1, start.y())));
match pos {
(Some(pos1), Some(pos2)) => Some(&self.data[pos1..pos2 + 1]),
_ => None,
}
}
pub fn swap<A: AsCoord2d, B: AsCoord2d>(&mut self, a: A, b: B) {
if let (Some(a), Some(b)) = (self.valid_pos(&a), self.valid_pos(&b)) {
self.data.swap(a, b)
}
}
// fn window_compare_impl<const REV: bool>(&self, needle: &[T]) -> Vec<(i64, i64)> {
// if (self.width as usize) < needle.len() {
// return Vec::new();
// }
// let mut res = Vec::new();
// for y in 0..self.height() as i64 {
// let mut windows_tmp = self.row(y).unwrap().windows(needle.len());
// let windows = if REV {
// windows_tmp.rev()
// } else {
// windows_tmp
// };
// res.extend(
// windows
// .enumerate()
// .filter_map(|(x, w)| if w == needle { Some((x as i64, y)) } else { None }),
// );
// }
// res
// }
}
impl<T: BufRead> From<T> for Grid<u8> {
fn from(input: T) -> Grid<u8> {
let mut data = Vec::new();
let mut width = 0;
for line in input.split(b'\n').map(|i| i.unwrap()) {
if width == 0 {
width = line.len() as i64
} else if line.len() as i64 != width {
panic!("Grids must have fixed length rows")
}
data.extend_from_slice(&line);
}
Grid { data, width }
}
}
// Should be Grid<char>?
impl FromStr for Grid<u8> {
type Err = Box<dyn std::error::Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Cursor::new(s).into())
}
}
// impl<T: Copy + Eq + PartialEq + Display + Debug + Into<char>> Display for Grid<T> {
// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
// for y in 0..self.height() {
// for x in 0..self.width() {
// f.write_fmt(format_args!("{}",self.get(x as i64, y as i64).unwrap() as char))?;
// }
// f.write_char('\n')?;
// }
// f.write_char('\n')
// }
// }
impl Display for Grid<u8> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
for y in 0..self.height() {
for x in 0..self.width() {
f.write_fmt(format_args!("{}", *self.get(&(x as i64, y as i64)).unwrap() as char))?;
}
f.write_char('\n')?;
}
f.write_char('\n')
}
}
impl Display for Grid<bool> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
for y in 0..self.height() {
for x in 0..self.width() {
f.write_fmt(format_args!(
"{}",
match *self.get(&(x as i64, y as i64)).unwrap() {
true => '.',
false => '#',
}
))?;
}
f.write_char('\n')?;
}
f.write_char('\n')
}
}
#[cfg(test)]
mod tests {
use super::*;
static TEST_VECTOR: &[u8] = b"ABCD
EFGH
IJKL
FBCG";
static TEST_VECTOR_S: &str = "ABCD
EFGH
IJKL
FBCG";
fn unchecked_load() -> Grid<u8> {
Grid::from(TEST_VECTOR)
}
#[test]
fn from_string() {
let grid = unchecked_load();
assert_eq!(grid.data, "ABCDEFGHIJKLFBCG".as_bytes());
assert_eq!(
TEST_VECTOR_S.parse::<Grid<u8>>().unwrap().data,
"ABCDEFGHIJKLFBCG".as_bytes()
);
}
#[test]
fn indexing() {
let grid = unchecked_load();
assert_eq!(grid.get(&(0, 0)), Some(b'A').as_ref());
assert_eq!(grid.get(&(3, 3)), Some(b'G').as_ref());
assert_eq!(grid.get(&(-1, 0)), None);
assert_eq!(grid.get(&(0, -1)), None);
assert_eq!(grid.get(&(5, 0)), None);
assert_eq!(grid.get(&(0, 5)), None);
}
#[test]
fn forward_slice() {
let grid = unchecked_load();
assert_eq!(grid.forward_slice(&(0, 0), 2), Some(b"AB".as_slice()));
assert_eq!(grid.forward_slice(&(2, 0), 2), Some(b"CD".as_slice()));
assert_eq!(grid.forward_slice(&(2, 0), 3), None);
assert_eq!(grid.forward_slice(&(0, 2), 4), Some(b"IJKL".as_slice()));
}
#[test]
fn row_iter() {
let grid = unchecked_load();
assert_eq!(
grid.row_iter(2).unwrap().collect::<Vec<_>>(),
[&b'I', &b'J', &b'K', &b'L']
);
assert!(grid.row_iter(-1).is_none());
assert!(grid.row_iter(4).is_none());
}
#[test]
fn col_iter() {
let grid = unchecked_load();
assert_eq!(
grid.col_iter(2).unwrap().collect::<Vec<_>>(),
[&b'C', &b'G', &b'K', &b'C']
);
assert!(grid.col_iter(-1).is_none());
assert!(grid.col_iter(4).is_none());
}
// #[test]
// fn window_compare() {
// let grid = unchecked_load();
// assert_eq!(grid.window_compare(b"IJKL"), &[(0, 2)]);
// assert_eq!(grid.window_compare(b"BC"), &[(1, 0), (1, 3)]);
// assert_eq!(grid.window_compare(b"LF").len(), 0);
// }
}

25
utils/misc/Cargo.lock generated Normal file
View File

@@ -0,0 +1,25 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "misc"
version = "0.1.0"
dependencies = [
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]

7
utils/misc/Cargo.toml Normal file
View File

@@ -0,0 +1,7 @@
[package]
name = "misc"
version = "0.1.0"
edition = "2021"
[dependencies]
num-traits = "0.2.19"

98
utils/misc/src/lib.rs Normal file
View File

@@ -0,0 +1,98 @@
use num_traits::Signed;
use std::fmt::Display;
use std::ops::{Add, AddAssign};
/// Wrapped signed integer with custom upper bound with wrapping of 0s to the upper bound
#[derive(Eq, Clone, Copy)]
pub struct CustomWrapped<T: Signed + Copy> {
pub val: T,
pub bound: T,
}
impl<T: Signed + Copy> Add<T> for CustomWrapped<T> {
type Output = CustomWrapped<T>;
fn add(self, rhs: T) -> Self::Output {
Self {
val: ((self.val + rhs % self.bound) + self.bound) % self.bound,
bound: self.bound,
}
}
}
impl<T: Signed + Copy> Add<T> for &CustomWrapped<T> {
type Output = CustomWrapped<T>;
fn add(self, rhs: T) -> Self::Output {
CustomWrapped {
val: ((self.val + rhs % self.bound) + self.bound) % self.bound,
bound: self.bound,
}
}
}
impl<T: Signed + Copy> AddAssign<T> for CustomWrapped<T> {
fn add_assign(&mut self, rhs: T) {
self.val = ((self.val + rhs % self.bound) + self.bound) % self.bound
}
}
impl<T: Signed + Copy> CustomWrapped<T> {
pub fn new(val: T, bound: T) -> Self {
Self { val, bound }
}
}
impl<T: Signed + Copy + PartialEq> PartialEq for CustomWrapped<T> {
fn eq(&self, other: &Self) -> bool {
self.val.eq(&other.val)
}
}
impl<T: Signed + PartialOrd + Copy> PartialOrd for CustomWrapped<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.val.partial_cmp(&other.val)
}
}
impl<T: Signed + Ord + Copy> Ord for CustomWrapped<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.val.cmp(&other.val)
}
}
impl<T: Signed + PartialEq + Copy> PartialEq<T> for CustomWrapped<T> {
fn eq(&self, other: &T) -> bool {
self.val == *other
}
}
impl<T: Signed + PartialOrd + Copy> PartialOrd<T> for CustomWrapped<T> {
fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
self.val.partial_cmp(other)
}
}
impl<T: Display + Signed + Copy> Display for CustomWrapped<T>
where
T: Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.val.fmt(f)
}
}
// impl<T> Into<T> for CustomWrapped<T> {
// fn into(self) -> T {
// self.val
// }
// }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}