Compare commits

...

2 Commits

Author SHA1 Message Date
50f491c76f day11: perf 2025-12-12 11:46:29 -08:00
845138dd2d day12: cache and bool 2025-12-12 03:42:47 -08:00
4 changed files with 447 additions and 25 deletions

372
Cargo.lock generated
View File

@@ -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"

View File

@@ -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]

View File

@@ -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,55 @@ 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 {
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 +99,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 +127,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 +177,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);
}
} }

View File

@@ -146,13 +146,12 @@ impl PresentsProblem {
) { ) {
if let Some(solution) = self.place_next(new_t, cur + 1, cache) { if let Some(solution) = self.place_next(new_t, cur + 1, cache) {
return Some(solution); return Some(solution);
} else {
cache.insert((cur, t.area.clone()));
} }
} }
} }
} }
} }
cache.insert((cur, t.area.clone()));
None None
} }
} }
@@ -237,7 +236,7 @@ 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(input)), expected); assert_eq!(part1(&parse(input)), expected);
} }