diff --git a/Cargo.lock b/Cargo.lock index dc466c3..cf0d25f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "once_cell", "version_check", "zerocopy", @@ -72,15 +72,34 @@ dependencies = [ "rayon", "regex", "rstest", + "rustc_data_structures", "wide", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "bumpalo" version = "3.19.0" @@ -126,6 +145,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.4" @@ -211,6 +236,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -223,6 +257,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "fnv" version = "1.0.7" @@ -278,6 +328,18 @@ dependencies = [ "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]] name = "glob" version = "0.3.3" @@ -288,6 +350,12 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" name = "grid" version = "0.1.0" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.5" @@ -305,12 +373,29 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "indexmap" version = "2.12.1" @@ -359,6 +444,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "js-sys" version = "0.3.83" @@ -369,18 +464,54 @@ dependencies = [ "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.178" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memmap2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -407,12 +538,45 @@ dependencies = [ "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]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "pin-project-lite" version = "0.2.16" @@ -458,6 +622,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rayon" version = "1.11.0" @@ -478,6 +648,15 @@ dependencies = [ "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]] name = "regex" version = "1.12.2" @@ -530,7 +709,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "glob", "proc-macro-crate", "proc-macro2", @@ -542,6 +721,79 @@ dependencies = [ "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]] name = "rustc_version" version = "0.4.1" @@ -551,6 +803,19 @@ dependencies = [ "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]] name = "rustversion" version = "1.0.22" @@ -572,6 +837,12 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "semver" version = "1.0.27" @@ -626,6 +897,18 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "strsim" version = "0.11.1" @@ -654,6 +937,19 @@ dependencies = [ "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]] name = "thiserror" version = "2.0.17" @@ -689,7 +985,7 @@ version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" dependencies = [ - "indexmap", + "indexmap 2.12.1", "toml_datetime", "toml_parser", "winnow", @@ -704,6 +1000,37 @@ dependencies = [ "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]] name = "unicode-ident" version = "1.0.22" @@ -728,13 +1055,22 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "wasm-bindgen" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "once_cell", "rustversion", "wasm-bindgen-macro", @@ -793,6 +1129,28 @@ dependencies = [ "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]] name = "windows-link" version = "0.2.1" @@ -817,6 +1175,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "zerocopy" version = "0.8.31" diff --git a/Cargo.toml b/Cargo.toml index c34d956..b82ea82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ misc = {path = "utils/misc"} rayon = "1.11.0" regex = "1.11.1" rstest = "0.26.1" +rustc_data_structures = "0.1.2" wide = "1.0.2" [profile.release] diff --git a/src/day11.rs b/src/day11.rs index 013edb8..4cb87bb 100644 --- a/src/day11.rs +++ b/src/day11.rs @@ -1,11 +1,11 @@ use aoc_runner_derive::{aoc, aoc_generator}; -use std::collections::{HashMap, HashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -type Edges = HashMap>; +type Edges = FxHashMap>; #[aoc_generator(day11)] fn parse(input: &str) -> Edges { - let mut edges: Edges = HashMap::new(); + let mut edges: Edges = FxHashMap::default(); for l in input.lines() { let (k, rest) = l.split_once(": ").unwrap(); 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>( cur: &'a str, edges: &'a Edges, - mut reachable: HashSet<&'a str>, -) -> HashSet<&'a str> { + mut reachable: FxHashSet<&'a str>, +) -> FxHashSet<&'a str> { reachable.insert(cur); if let Some(nexts) = edges.get(cur) { for n in nexts { @@ -43,12 +43,55 @@ fn mark_paths<'a>( 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 { 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 { let mut rev = Edges::from_iter(edges.keys().map(|k| (k.to_owned(), vec![]))); 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()); } } - 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); - 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); - let reachable: HashSet<&str> = reachable_dac + let reachable: FxHashSet<&str> = reachable_dac .intersection(&reachable_fft) .copied() .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) .copied() .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. - // However, knowing that fact that we can partition in this way, we could use a shortest-path algo - // to determine which order fft and dac are in. - // - // The assumption holds on my data and the example, so I think it's probably true of all inputs. + // A real graph structure would probably notice that the graphs get split here + let mut reachable_edges_excl_fft = reachable_edges.clone(); + reachable_edges_excl_fft.remove("fft"); + let mut reachable_edges_excl_dac = reachable_edges.clone(); + reachable_edges_excl_dac.remove("dac"); + find_path("svr", "fft", &reachable_edges) - * find_path("fft", "dac", &reachable_edges) - * find_path("dac", "out", &reachable_edges) + // only svr->fft->dac->out paths appear in my input and in the example, but include the dac->fft ordering + // 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)] @@ -131,9 +177,21 @@ hhh: out"; 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] #[case(EXAMPLE2, 2)] fn part2_example(#[case] input: &str, #[case] expected: u64) { 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); + } }