Compare commits
3 Commits
004591374c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
c35270a6a2
|
|||
|
845138dd2d
|
|||
|
fd6b0c846b
|
372
Cargo.lock
generated
372
Cargo.lock
generated
@@ -8,7 +8,7 @@ version = "0.8.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
@@ -72,15 +72,34 @@ dependencies = [
|
|||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"rstest",
|
"rstest",
|
||||||
|
"rustc_data_structures",
|
||||||
"wide",
|
"wide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.19.0"
|
version = "3.19.0"
|
||||||
@@ -126,6 +145,12 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
|
checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -211,6 +236,15 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ena"
|
||||||
|
version = "0.14.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -223,6 +257,22 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -278,6 +328,18 @@ dependencies = [
|
|||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.4",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"wasip2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -288,6 +350,12 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|||||||
name = "grid"
|
name = "grid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
@@ -305,12 +373,29 @@ version = "0.16.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
"rustc-rayon 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.12.1"
|
version = "2.12.1"
|
||||||
@@ -359,6 +444,16 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.83"
|
version = "0.3.83"
|
||||||
@@ -369,18 +464,54 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.178"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||||
|
dependencies = [
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.6"
|
version = "2.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memmap2"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@@ -407,12 +538,45 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.4",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@@ -458,6 +622,12 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "5.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@@ -478,6 +648,15 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.12.2"
|
version = "1.12.2"
|
||||||
@@ -530,7 +709,7 @@ version = "0.26.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0"
|
checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.4",
|
||||||
"glob",
|
"glob",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -542,6 +721,79 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-rayon"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9974ab223660e61c1b4e7b43b827379df286736ca988308ce7e16f59f2d89246"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"either",
|
||||||
|
"rustc-rayon-core 0.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-rayon"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cd9fb077db982d7ceb42a90471e5a69a990b58f71e06f0d8340bb2cf35eb751"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rustc-rayon-core 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-rayon-core"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "564bfd27be8db888d0fa76aa4335e7851aaed0c2c11ad1e93aeb9349f6b88500"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-rayon-core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f42932dcd3bcbe484b38a3ccf79b7906fac41c02d408b5b1bac26da3416efdb"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_data_structures"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a38bae9c6afa27015bcaa2869e03bb111ecf0d0e0edc2da559a91d4057174c9a"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
"ena",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
|
"memmap2",
|
||||||
|
"parking_lot",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustc-rayon 0.3.2",
|
||||||
|
"rustc-rayon-core 0.3.2",
|
||||||
|
"stable_deref_trait",
|
||||||
|
"tempfile",
|
||||||
|
"tracing",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -551,6 +803,19 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -572,6 +837,12 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
@@ -626,6 +897,18 @@ version = "0.4.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@@ -654,6 +937,19 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.17"
|
version = "2.0.17"
|
||||||
@@ -689,7 +985,7 @@ version = "0.23.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832"
|
checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.12.1",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"winnow",
|
"winnow",
|
||||||
@@ -704,6 +1000,37 @@ dependencies = [
|
|||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -728,13 +1055,22 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasip2"
|
||||||
|
version = "1.0.1+wasi-0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.106"
|
version = "0.2.106"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
@@ -793,6 +1129,28 @@ dependencies = [
|
|||||||
"safe_arch",
|
"safe_arch",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -817,6 +1175,12 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.31"
|
version = "0.8.31"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ misc = {path = "utils/misc"}
|
|||||||
rayon = "1.11.0"
|
rayon = "1.11.0"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
rstest = "0.26.1"
|
rstest = "0.26.1"
|
||||||
|
rustc_data_structures = "0.1.2"
|
||||||
wide = "1.0.2"
|
wide = "1.0.2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|||||||
100
src/day11.rs
100
src/day11.rs
@@ -1,11 +1,11 @@
|
|||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
use std::collections::{HashMap, HashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
type Edges = HashMap<String, Vec<String>>;
|
type Edges = FxHashMap<String, Vec<String>>;
|
||||||
|
|
||||||
#[aoc_generator(day11)]
|
#[aoc_generator(day11)]
|
||||||
fn parse(input: &str) -> Edges {
|
fn parse(input: &str) -> Edges {
|
||||||
let mut edges: Edges = HashMap::new();
|
let mut edges: Edges = FxHashMap::default();
|
||||||
for l in input.lines() {
|
for l in input.lines() {
|
||||||
let (k, rest) = l.split_once(": ").unwrap();
|
let (k, rest) = l.split_once(": ").unwrap();
|
||||||
for v in rest.split_ascii_whitespace() {
|
for v in rest.split_ascii_whitespace() {
|
||||||
@@ -30,8 +30,8 @@ fn find_path(cur: &str, goal: &str, edges: &Edges) -> u64 {
|
|||||||
fn mark_paths<'a>(
|
fn mark_paths<'a>(
|
||||||
cur: &'a str,
|
cur: &'a str,
|
||||||
edges: &'a Edges,
|
edges: &'a Edges,
|
||||||
mut reachable: HashSet<&'a str>,
|
mut reachable: FxHashSet<&'a str>,
|
||||||
) -> HashSet<&'a str> {
|
) -> FxHashSet<&'a str> {
|
||||||
reachable.insert(cur);
|
reachable.insert(cur);
|
||||||
if let Some(nexts) = edges.get(cur) {
|
if let Some(nexts) = edges.get(cur) {
|
||||||
for n in nexts {
|
for n in nexts {
|
||||||
@@ -43,12 +43,61 @@ fn mark_paths<'a>(
|
|||||||
reachable
|
reachable
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day11, part1)]
|
fn count_paths_impl<'a>(
|
||||||
|
cur: &'a str,
|
||||||
|
goal: &str,
|
||||||
|
edges: &'a Edges,
|
||||||
|
memo: &mut FxHashMap<&'a str, u64>,
|
||||||
|
) -> u64 {
|
||||||
|
if cur == goal {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if let Some(v) = memo.get(cur) {
|
||||||
|
return *v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(nexts) = edges.get(cur) {
|
||||||
|
let ret = nexts
|
||||||
|
.iter()
|
||||||
|
.map(|n| count_paths_impl(n, goal, edges, memo))
|
||||||
|
.sum();
|
||||||
|
memo.insert(cur, ret);
|
||||||
|
ret
|
||||||
|
} else {
|
||||||
|
memo.insert(cur, 0);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_paths(cur: &str, goal: &str, edges: &Edges) -> u64 {
|
||||||
|
let mut cache = FxHashMap::default();
|
||||||
|
count_paths_impl(cur, goal, edges, &mut cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part1, NaiveDfs)]
|
||||||
fn part1(fwd: &Edges) -> u64 {
|
fn part1(fwd: &Edges) -> u64 {
|
||||||
find_path("you", "out", fwd)
|
find_path("you", "out", fwd)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day11, part2)]
|
#[aoc(day11, part1, MemoDfs)]
|
||||||
|
fn part1_memo(fwd: &Edges) -> u64 {
|
||||||
|
count_paths("you", "out", fwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part2, MemoDfs)]
|
||||||
|
fn part2_memo(edges: &Edges) -> u64 {
|
||||||
|
// we assume all valid paths reach svr->fft->dac->out in that order. this holds on the example and the input.
|
||||||
|
// to handle both possible orderings, we need to sum paths fft->dac and dac->fft, and then partition the graph
|
||||||
|
// (just remove the node) at dac & fft before computing the sum of dac->out and fft->out.
|
||||||
|
//
|
||||||
|
// this is our performance implementation though and it's faster to not do that work. we do the posterity for the
|
||||||
|
// naive solution
|
||||||
|
count_paths("svr", "fft", edges)
|
||||||
|
* count_paths("fft", "dac", edges)
|
||||||
|
* count_paths("dac", "out", edges)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part2, NaiveDfs)]
|
||||||
fn part2(edges: &Edges) -> u64 {
|
fn part2(edges: &Edges) -> u64 {
|
||||||
let mut rev = Edges::from_iter(edges.keys().map(|k| (k.to_owned(), vec![])));
|
let mut rev = Edges::from_iter(edges.keys().map(|k| (k.to_owned(), vec![])));
|
||||||
for (from, tos) in edges {
|
for (from, tos) in edges {
|
||||||
@@ -56,17 +105,17 @@ fn part2(edges: &Edges) -> u64 {
|
|||||||
rev.entry(to.to_owned()).or_default().push(from.to_owned());
|
rev.entry(to.to_owned()).or_default().push(from.to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut reachable_dac = mark_paths("dac", edges, HashSet::new());
|
let mut reachable_dac = mark_paths("dac", edges, FxHashSet::default());
|
||||||
reachable_dac = mark_paths("dac", &rev, reachable_dac);
|
reachable_dac = mark_paths("dac", &rev, reachable_dac);
|
||||||
let mut reachable_fft = mark_paths("fft", edges, HashSet::new());
|
let mut reachable_fft = mark_paths("fft", edges, FxHashSet::default());
|
||||||
reachable_fft = mark_paths("fft", &rev, reachable_fft);
|
reachable_fft = mark_paths("fft", &rev, reachable_fft);
|
||||||
|
|
||||||
let reachable: HashSet<&str> = reachable_dac
|
let reachable: FxHashSet<&str> = reachable_dac
|
||||||
.intersection(&reachable_fft)
|
.intersection(&reachable_fft)
|
||||||
.copied()
|
.copied()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let unreachable: HashSet<&str> = HashSet::from_iter(edges.keys().map(|k| k.as_str()))
|
let unreachable: FxHashSet<&str> = FxHashSet::from_iter(edges.keys().map(|k| k.as_str()))
|
||||||
.difference(&reachable)
|
.difference(&reachable)
|
||||||
.copied()
|
.copied()
|
||||||
.collect();
|
.collect();
|
||||||
@@ -84,14 +133,17 @@ fn part2(edges: &Edges) -> u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a bit of a cheat from viewing the graph and realizing all paths are ordered this way.
|
// A real graph structure would probably notice that the graphs get split here
|
||||||
// However, knowing that fact that we can partition in this way, we could use a shortest-path algo
|
let mut reachable_edges_excl_fft = reachable_edges.clone();
|
||||||
// to determine which order fft and dac are in.
|
reachable_edges_excl_fft.remove("fft");
|
||||||
//
|
let mut reachable_edges_excl_dac = reachable_edges.clone();
|
||||||
// The assumption holds on my data and the example, so I think it's probably true of all inputs.
|
reachable_edges_excl_dac.remove("dac");
|
||||||
|
|
||||||
find_path("svr", "fft", &reachable_edges)
|
find_path("svr", "fft", &reachable_edges)
|
||||||
* find_path("fft", "dac", &reachable_edges)
|
// only svr->fft->dac->out paths appear in my input and in the example, but include the dac->fft ordering
|
||||||
* find_path("dac", "out", &reachable_edges)
|
// as well, for posterity. It ~doubles runtime.
|
||||||
|
* (find_path("fft", "dac", &reachable_edges) + find_path("dac", "fft", &reachable_edges))
|
||||||
|
* (find_path("dac", "out", &reachable_edges_excl_fft) + find_path("fft", "out", &reachable_edges_excl_dac))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -131,9 +183,21 @@ hhh: out";
|
|||||||
assert_eq!(part1(&parse(input)), expected);
|
assert_eq!(part1(&parse(input)), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(EXAMPLE, 5)]
|
||||||
|
fn part1_memo_example(#[case] input: &str, #[case] expected: u64) {
|
||||||
|
assert_eq!(part1_memo(&parse(input)), expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case(EXAMPLE2, 2)]
|
#[case(EXAMPLE2, 2)]
|
||||||
fn part2_example(#[case] input: &str, #[case] expected: u64) {
|
fn part2_example(#[case] input: &str, #[case] expected: u64) {
|
||||||
assert_eq!(part2(&parse(input)), expected);
|
assert_eq!(part2(&parse(input)), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(EXAMPLE2, 2)]
|
||||||
|
fn part2_memo_example(#[case] input: &str, #[case] expected: u64) {
|
||||||
|
assert_eq!(part2_memo(&parse(input)), expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
175
src/day12.rs
175
src/day12.rs
@@ -1,101 +1,64 @@
|
|||||||
use std::iter::repeat_n;
|
|
||||||
use std::{collections::BinaryHeap, f64::consts, fmt::Display};
|
|
||||||
|
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
use grid::{Coord2d, Grid, MirrorAxis};
|
use grid::{Coord2d, Grid, MirrorAxis};
|
||||||
use itertools::{Format, Itertools};
|
use itertools::Itertools;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::iter::repeat_n;
|
||||||
|
|
||||||
|
type CellType = bool;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct PresentShape {
|
struct PresentShape {
|
||||||
idx: u8,
|
variants: Vec<Grid<CellType>>,
|
||||||
shape: Grid<u8>,
|
|
||||||
variants: Vec<Grid<u8>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for PresentShape {
|
impl From<&str> for PresentShape {
|
||||||
fn from(value: &str) -> Self {
|
fn from(value: &str) -> Self {
|
||||||
let (idx, rest) = value.split_once(":\n").unwrap();
|
let (_idx, rest) = value.split_once(":\n").unwrap();
|
||||||
|
|
||||||
let shape: Grid<u8> = rest.parse().unwrap();
|
let shape_raw: Grid<u8> = rest.parse().unwrap();
|
||||||
|
let mut shape: Grid<CellType> = shape_raw.same_shape(false);
|
||||||
|
for pos in shape_raw.find_all(&b'#') {
|
||||||
|
shape.set(&pos, true);
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
idx: idx.parse().unwrap(),
|
|
||||||
variants: (0..4)
|
variants: (0..4)
|
||||||
.map(|rot| shape.rotated(rot))
|
.map(|rot| shape.rotated(rot))
|
||||||
.chain([MirrorAxis::X, MirrorAxis::Y].map(|axis| shape.mirrored(axis)))
|
.chain([MirrorAxis::X, MirrorAxis::Y].map(|axis| shape.mirrored(axis)))
|
||||||
.unique()
|
.unique()
|
||||||
.collect(),
|
.collect(),
|
||||||
shape,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PresentShape {
|
impl Display for PresentShape {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("{}:\n", self.idx))?;
|
f.write_fmt(format_args!("{}", self.variants[0]))
|
||||||
f.write_fmt(format_args!("{}", self.shape))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PresentShape {
|
impl PresentShape {
|
||||||
fn make(&self) -> Present {
|
|
||||||
Present {
|
|
||||||
shape: self.clone(),
|
|
||||||
location: None,
|
|
||||||
variant: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn popcount(&self) -> u64 {
|
fn popcount(&self) -> u64 {
|
||||||
self.shape.data.iter().filter(|c| **c != b'.').count() as u64
|
self.variants[0].count(&true) as u64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Present {
|
struct Present {
|
||||||
shape: PresentShape,
|
shape: usize,
|
||||||
location: Option<Coord2d>,
|
|
||||||
variant: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct ChristmasTree {
|
struct ChristmasTree {
|
||||||
area: Grid<u8>,
|
area: Grid<CellType>,
|
||||||
presents: Vec<Present>,
|
presents: Vec<Present>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChristmasTree {}
|
|
||||||
|
|
||||||
impl Display for ChristmasTree {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.write_fmt(format_args!("{}", self.area))?;
|
|
||||||
for (i, p) in self.presents.iter().enumerate() {
|
|
||||||
f.write_fmt(format_args!(" {i}: @{:?} rot {}\n", p.location, p.variant))?;
|
|
||||||
f.write_fmt(format_args!("{}", p.shape.variants[p.variant]))?;
|
|
||||||
}
|
|
||||||
std::fmt::Result::Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct PresentsProblem {
|
struct PresentsProblem {
|
||||||
shapes: Vec<PresentShape>,
|
|
||||||
trees: Vec<ChristmasTree>,
|
trees: Vec<ChristmasTree>,
|
||||||
}
|
shapes: Vec<PresentShape>,
|
||||||
|
|
||||||
impl PresentsProblem {
|
|
||||||
fn present(&self, idx: usize) -> Present {
|
|
||||||
Present {
|
|
||||||
shape: self.shapes[idx].clone(),
|
|
||||||
location: None,
|
|
||||||
variant: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn add_tree(&mut self, w: usize, h: usize, presents: Vec<Present>) {
|
|
||||||
self.trees.push(ChristmasTree {
|
|
||||||
area: Grid::with_shape(w, h, b'.'),
|
|
||||||
presents,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc_generator(day12)]
|
#[aoc_generator(day12)]
|
||||||
@@ -116,52 +79,63 @@ fn parse(input: &str) -> PresentsProblem {
|
|||||||
let presents = present_counts
|
let presents = present_counts
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(i, count)| repeat_n(shapes[i].make(), *count))
|
.flat_map(|(i, count)| repeat_n(Present { shape: i }, *count))
|
||||||
.collect();
|
.collect();
|
||||||
trees.push(ChristmasTree {
|
trees.push(ChristmasTree {
|
||||||
area: Grid::with_shape(w.parse().unwrap(), h.parse().unwrap(), b'.'),
|
area: Grid::with_shape(w.parse().unwrap(), h.parse().unwrap(), false),
|
||||||
presents,
|
presents,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PresentsProblem { shapes, trees }
|
PresentsProblem { trees, shapes }
|
||||||
}
|
}
|
||||||
|
|
||||||
// place b on a and test if any # overlap any non-.
|
// place b on a and test if any # overlap any non-.
|
||||||
fn overlaps(a: &Grid<u8>, b: &Grid<u8>, p: &Coord2d) -> bool {
|
// fn overlaps(a: &Grid<CellType>, b: &Grid<CellType>, p: &Coord2d) -> bool {
|
||||||
b.find_all(&b'#')
|
// b.find_all(&true)
|
||||||
.any(|c| a.get(&(c + p)).is_some_and(|c| *c != b'.'))
|
// .any(|c| a.get(&(c + p)).is_some_and(|c| *c))
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn place_shape(
|
impl PresentsProblem {
|
||||||
|
fn place_shape(
|
||||||
|
&self,
|
||||||
mut t: ChristmasTree,
|
mut t: ChristmasTree,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
pos: Coord2d,
|
pos: Coord2d,
|
||||||
variant: usize,
|
variant: usize,
|
||||||
) -> Option<ChristmasTree> {
|
) -> Option<ChristmasTree> {
|
||||||
let variant = &t.presents[idx].shape.variants[variant];
|
let variant = &self.shapes[t.presents[idx].shape].variants[variant];
|
||||||
|
|
||||||
if !overlaps(&t.area, variant, &pos) {
|
for xy in variant.find_all(&true) {
|
||||||
for xy in variant.find_all(&b'#') {
|
if let Some(was) = t.area.set(&(pos + &(xy)), true)
|
||||||
t.area.set(&(pos + &(xy)), b'0' + idx as u8).unwrap();
|
&& was
|
||||||
|
{
|
||||||
|
// overlapped
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(t)
|
Some(t)
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn place_next(mut t: ChristmasTree, cur: usize) -> Option<ChristmasTree> {
|
fn place_next(
|
||||||
|
&self,
|
||||||
|
t: ChristmasTree,
|
||||||
|
cur: usize,
|
||||||
|
cache: &mut HashSet<(usize, Grid<CellType>)>, // impossible shapes
|
||||||
|
) -> Option<ChristmasTree> {
|
||||||
if cur == t.presents.len() {
|
if cur == t.presents.len() {
|
||||||
|
// done
|
||||||
return Some(t);
|
return Some(t);
|
||||||
}
|
}
|
||||||
let variants = &t.presents[cur].shape.variants;
|
if cache.contains(&(cur, t.area.clone())) {
|
||||||
'variant: for (i, _v) in variants.iter().enumerate() {
|
// doomed
|
||||||
//make sure the longest 'bar' can fit
|
return None;
|
||||||
|
}
|
||||||
|
let variants = &self.shapes[t.presents[cur].shape].variants;
|
||||||
|
for (i, _v) in variants.iter().enumerate() {
|
||||||
for y in 0..&t.area.height() - 2 {
|
for y in 0..&t.area.height() - 2 {
|
||||||
for x in 0..&t.area.width() - 2 {
|
for x in 0..&t.area.width() - 2 {
|
||||||
if let Some(new_t) = place_shape(
|
if let Some(new_t) = self.place_shape(
|
||||||
t.clone(),
|
t.clone(),
|
||||||
cur,
|
cur,
|
||||||
Coord2d {
|
Coord2d {
|
||||||
@@ -170,34 +144,47 @@ fn place_next(mut t: ChristmasTree, cur: usize) -> Option<ChristmasTree> {
|
|||||||
},
|
},
|
||||||
i,
|
i,
|
||||||
) {
|
) {
|
||||||
if let Some(solution) = place_next(new_t, cur + 1) {
|
if let Some(solution) = self.place_next(new_t, cur + 1, cache) {
|
||||||
return Some(solution);
|
return Some(solution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cache.insert((cur, t.area.clone()));
|
||||||
None
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day12, part1)]
|
#[aoc(day12, part1)]
|
||||||
fn part1(input: &PresentsProblem) -> u64 {
|
fn part1(input: &PresentsProblem) -> u64 {
|
||||||
let input = input.clone();
|
let input = input.clone();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
// for t in input.trees[0..2].iter() {
|
|
||||||
// println!("trying:\n{t}");
|
|
||||||
// if let Some(r) = place_next(t.clone(), 0) {
|
|
||||||
// count += 1;
|
|
||||||
// println!("ok!\n{r}");
|
|
||||||
// } else {
|
|
||||||
// println!("failed :(");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
for t in input.trees.iter() {
|
for t in input.trees.iter() {
|
||||||
let area = (t.area.width() * t.area.height()) as u64;
|
let area = (t.area.width() * t.area.height()) as u64;
|
||||||
let occupied_area = t.presents.iter().map(|p| p.shape.popcount()).sum::<u64>();
|
let (occupied_area, present_count) = t
|
||||||
if occupied_area <= area {
|
.presents
|
||||||
count += 1
|
.iter()
|
||||||
|
.map(|p| (input.shapes[p.shape].popcount(), 1))
|
||||||
|
.reduce(|(o_a, pc_a), (o_b, pc_b)| (o_a + o_b, pc_a + pc_b))
|
||||||
|
.unwrap();
|
||||||
|
if occupied_area > area {
|
||||||
|
// definitely impossible
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let available_3x3s = (t.area.width() / 3) * (t.area.height() / 3);
|
||||||
|
if available_3x3s >= present_count {
|
||||||
|
// definitely_possible
|
||||||
|
count += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if input
|
||||||
|
.place_next(t.clone(), 0, &mut HashSet::new())
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
count += 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +192,7 @@ fn part1(input: &PresentsProblem) -> u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day12, part2)]
|
#[aoc(day12, part2)]
|
||||||
fn part2(input: &PresentsProblem) -> u64 {
|
fn part2(_input: &PresentsProblem) -> u64 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,14 +236,14 @@ mod tests {
|
|||||||
12x5: 1 0 1 0 3 2";
|
12x5: 1 0 1 0 3 2";
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case(EXAMPLE, 0)]
|
#[case(EXAMPLE, 2)]
|
||||||
fn part1_example(#[case] input: &str, #[case] expected: u64) {
|
fn part1_example(#[case] input: &str, #[case] expected: u64) {
|
||||||
assert_eq!(part1(&parse(EXAMPLE)), 2);
|
assert_eq!(part1(&parse(input)), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case(EXAMPLE, 0)]
|
#[case(EXAMPLE, 0)]
|
||||||
fn part2_example(#[case] input: &str, #[case] expected: u64) {
|
fn part2_example(#[case] input: &str, #[case] expected: u64) {
|
||||||
assert_eq!(part2(&parse(EXAMPLE)), 0);
|
assert_eq!(part2(&parse(input)), expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user