Advent of Code solutions

Add Benching

bwc9876.dev 65dbf078 1f36f8fb

verified
+406 -7
+276
Cargo.lock
··· 15 15 name = "advent_core" 16 16 version = "0.1.0" 17 17 dependencies = [ 18 + "indicatif", 18 19 "regex", 19 20 ] 20 21 ··· 28 29 ] 29 30 30 31 [[package]] 32 + name = "bumpalo" 33 + version = "3.16.0" 34 + source = "registry+https://github.com/rust-lang/crates.io-index" 35 + checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 36 + 37 + [[package]] 38 + name = "cfg-if" 39 + version = "1.0.0" 40 + source = "registry+https://github.com/rust-lang/crates.io-index" 41 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 42 + 43 + [[package]] 44 + name = "console" 45 + version = "0.15.8" 46 + source = "registry+https://github.com/rust-lang/crates.io-index" 47 + checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" 48 + dependencies = [ 49 + "encode_unicode", 50 + "lazy_static", 51 + "libc", 52 + "unicode-width 0.1.14", 53 + "windows-sys", 54 + ] 55 + 56 + [[package]] 57 + name = "encode_unicode" 58 + version = "0.3.6" 59 + source = "registry+https://github.com/rust-lang/crates.io-index" 60 + checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 61 + 62 + [[package]] 63 + name = "indicatif" 64 + version = "0.17.9" 65 + source = "registry+https://github.com/rust-lang/crates.io-index" 66 + checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" 67 + dependencies = [ 68 + "console", 69 + "number_prefix", 70 + "portable-atomic", 71 + "unicode-width 0.2.0", 72 + "web-time", 73 + ] 74 + 75 + [[package]] 76 + name = "js-sys" 77 + version = "0.3.74" 78 + source = "registry+https://github.com/rust-lang/crates.io-index" 79 + checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" 80 + dependencies = [ 81 + "once_cell", 82 + "wasm-bindgen", 83 + ] 84 + 85 + [[package]] 86 + name = "lazy_static" 87 + version = "1.5.0" 88 + source = "registry+https://github.com/rust-lang/crates.io-index" 89 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 90 + 91 + [[package]] 92 + name = "libc" 93 + version = "0.2.167" 94 + source = "registry+https://github.com/rust-lang/crates.io-index" 95 + checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" 96 + 97 + [[package]] 98 + name = "log" 99 + version = "0.4.22" 100 + source = "registry+https://github.com/rust-lang/crates.io-index" 101 + checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 102 + 103 + [[package]] 31 104 name = "macros" 32 105 version = "0.1.0" 33 106 dependencies = [ ··· 41 114 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 42 115 43 116 [[package]] 117 + name = "number_prefix" 118 + version = "0.4.0" 119 + source = "registry+https://github.com/rust-lang/crates.io-index" 120 + checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 121 + 122 + [[package]] 123 + name = "once_cell" 124 + version = "1.20.2" 125 + source = "registry+https://github.com/rust-lang/crates.io-index" 126 + checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 127 + 128 + [[package]] 129 + name = "portable-atomic" 130 + version = "1.10.0" 131 + source = "registry+https://github.com/rust-lang/crates.io-index" 132 + checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" 133 + 134 + [[package]] 135 + name = "proc-macro2" 136 + version = "1.0.92" 137 + source = "registry+https://github.com/rust-lang/crates.io-index" 138 + checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 139 + dependencies = [ 140 + "unicode-ident", 141 + ] 142 + 143 + [[package]] 144 + name = "quote" 145 + version = "1.0.37" 146 + source = "registry+https://github.com/rust-lang/crates.io-index" 147 + checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 148 + dependencies = [ 149 + "proc-macro2", 150 + ] 151 + 152 + [[package]] 44 153 name = "regex" 45 154 version = "1.11.1" 46 155 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 68 177 version = "0.8.5" 69 178 source = "registry+https://github.com/rust-lang/crates.io-index" 70 179 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 180 + 181 + [[package]] 182 + name = "syn" 183 + version = "2.0.90" 184 + source = "registry+https://github.com/rust-lang/crates.io-index" 185 + checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 186 + dependencies = [ 187 + "proc-macro2", 188 + "quote", 189 + "unicode-ident", 190 + ] 191 + 192 + [[package]] 193 + name = "unicode-ident" 194 + version = "1.0.14" 195 + source = "registry+https://github.com/rust-lang/crates.io-index" 196 + checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 197 + 198 + [[package]] 199 + name = "unicode-width" 200 + version = "0.1.14" 201 + source = "registry+https://github.com/rust-lang/crates.io-index" 202 + checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 203 + 204 + [[package]] 205 + name = "unicode-width" 206 + version = "0.2.0" 207 + source = "registry+https://github.com/rust-lang/crates.io-index" 208 + checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 71 209 72 210 [[package]] 73 211 name = "utils" 74 212 version = "0.1.0" 213 + 214 + [[package]] 215 + name = "wasm-bindgen" 216 + version = "0.2.97" 217 + source = "registry+https://github.com/rust-lang/crates.io-index" 218 + checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" 219 + dependencies = [ 220 + "cfg-if", 221 + "once_cell", 222 + "wasm-bindgen-macro", 223 + ] 224 + 225 + [[package]] 226 + name = "wasm-bindgen-backend" 227 + version = "0.2.97" 228 + source = "registry+https://github.com/rust-lang/crates.io-index" 229 + checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" 230 + dependencies = [ 231 + "bumpalo", 232 + "log", 233 + "once_cell", 234 + "proc-macro2", 235 + "quote", 236 + "syn", 237 + "wasm-bindgen-shared", 238 + ] 239 + 240 + [[package]] 241 + name = "wasm-bindgen-macro" 242 + version = "0.2.97" 243 + source = "registry+https://github.com/rust-lang/crates.io-index" 244 + checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" 245 + dependencies = [ 246 + "quote", 247 + "wasm-bindgen-macro-support", 248 + ] 249 + 250 + [[package]] 251 + name = "wasm-bindgen-macro-support" 252 + version = "0.2.97" 253 + source = "registry+https://github.com/rust-lang/crates.io-index" 254 + checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" 255 + dependencies = [ 256 + "proc-macro2", 257 + "quote", 258 + "syn", 259 + "wasm-bindgen-backend", 260 + "wasm-bindgen-shared", 261 + ] 262 + 263 + [[package]] 264 + name = "wasm-bindgen-shared" 265 + version = "0.2.97" 266 + source = "registry+https://github.com/rust-lang/crates.io-index" 267 + checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" 268 + 269 + [[package]] 270 + name = "web-time" 271 + version = "1.1.0" 272 + source = "registry+https://github.com/rust-lang/crates.io-index" 273 + checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 274 + dependencies = [ 275 + "js-sys", 276 + "wasm-bindgen", 277 + ] 278 + 279 + [[package]] 280 + name = "windows-sys" 281 + version = "0.52.0" 282 + source = "registry+https://github.com/rust-lang/crates.io-index" 283 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 284 + dependencies = [ 285 + "windows-targets", 286 + ] 287 + 288 + [[package]] 289 + name = "windows-targets" 290 + version = "0.52.6" 291 + source = "registry+https://github.com/rust-lang/crates.io-index" 292 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 293 + dependencies = [ 294 + "windows_aarch64_gnullvm", 295 + "windows_aarch64_msvc", 296 + "windows_i686_gnu", 297 + "windows_i686_gnullvm", 298 + "windows_i686_msvc", 299 + "windows_x86_64_gnu", 300 + "windows_x86_64_gnullvm", 301 + "windows_x86_64_msvc", 302 + ] 303 + 304 + [[package]] 305 + name = "windows_aarch64_gnullvm" 306 + version = "0.52.6" 307 + source = "registry+https://github.com/rust-lang/crates.io-index" 308 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 309 + 310 + [[package]] 311 + name = "windows_aarch64_msvc" 312 + version = "0.52.6" 313 + source = "registry+https://github.com/rust-lang/crates.io-index" 314 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 315 + 316 + [[package]] 317 + name = "windows_i686_gnu" 318 + version = "0.52.6" 319 + source = "registry+https://github.com/rust-lang/crates.io-index" 320 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 321 + 322 + [[package]] 323 + name = "windows_i686_gnullvm" 324 + version = "0.52.6" 325 + source = "registry+https://github.com/rust-lang/crates.io-index" 326 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 327 + 328 + [[package]] 329 + name = "windows_i686_msvc" 330 + version = "0.52.6" 331 + source = "registry+https://github.com/rust-lang/crates.io-index" 332 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 333 + 334 + [[package]] 335 + name = "windows_x86_64_gnu" 336 + version = "0.52.6" 337 + source = "registry+https://github.com/rust-lang/crates.io-index" 338 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 339 + 340 + [[package]] 341 + name = "windows_x86_64_gnullvm" 342 + version = "0.52.6" 343 + source = "registry+https://github.com/rust-lang/crates.io-index" 344 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 345 + 346 + [[package]] 347 + name = "windows_x86_64_msvc" 348 + version = "0.52.6" 349 + source = "registry+https://github.com/rust-lang/crates.io-index" 350 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 75 351 76 352 [[package]] 77 353 name = "y_2024"
+5
Cargo.toml
··· 22 22 [[bin]] 23 23 name = "advent" 24 24 path = "src/main.rs" 25 + 26 + [profile.release] 27 + panic = "abort" 28 + lto = true 29 + opt-level = 3
+1
advent_core/Cargo.toml
··· 6 6 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 7 8 8 [dependencies] 9 + indicatif = "0.17.9" 9 10 regex = "1.10.2"
+62 -1
advent_core/src/day.rs
··· 1 1 use std::time::Instant; 2 2 3 + use indicatif::ProgressStyle; 4 + 3 5 #[macro_export] 4 6 macro_rules! ex_for_day { 5 7 ($day:literal, $part:literal) => { ··· 34 36 } 35 37 } 36 38 39 + const BENCH_SECS: u64 = 5; 40 + const PROGRESS_TEMPLATE: &str = "{spinner} {wide_msg} [{bar:100.green/cyan}]"; 41 + const PROGRESS_CHARS: &str = "=>-"; 42 + 43 + macro_rules! bench { 44 + ($t:expr) => {{ 45 + let outer_instant = std::time::Instant::now(); 46 + let mut times = Vec::<std::time::Duration>::with_capacity(1000); 47 + let mut res = None; 48 + let style = ProgressStyle::with_template(PROGRESS_TEMPLATE) 49 + .unwrap() 50 + .progress_chars(PROGRESS_CHARS); 51 + let progress = indicatif::ProgressBar::new(BENCH_SECS); 52 + progress.set_style(style); 53 + let mut i = 0; 54 + while outer_instant.elapsed().as_secs() <= BENCH_SECS { 55 + let instant = std::time::Instant::now(); 56 + let r = $t; 57 + if res.is_none() { 58 + res = Some(r) 59 + } 60 + times.push(instant.elapsed()); 61 + i += 1; 62 + progress.set_message(format!("{i} Runs")); 63 + progress.set_position(outer_instant.elapsed().as_secs()); 64 + } 65 + ( 66 + times.iter().sum::<std::time::Duration>() / (times.len() as u32), 67 + times.len(), 68 + res.unwrap(), 69 + ) 70 + }}; 71 + } 72 + 37 73 /// A trait for a day of Advent of Code. 38 74 /// 39 75 /// This trait is implemented for each day of Advent of Code. ··· 46 82 /// Then, any runner can use `run_part` to run a part of the day with a given input or the example input. 47 83 /// 48 84 pub trait Day { 49 - type Input; 85 + type Input: Clone; 50 86 51 87 const DAY: usize = 0; 52 88 ··· 81 117 instant.elapsed() 82 118 ); 83 119 solution 120 + } 121 + 122 + fn bench_part(part: usize, input: Option<&str>) { 123 + let input = input.unwrap_or_else(|| Self::get_example_input(part)); 124 + let (parse_time, sample_size, input) = bench!(Self::parse_input(input)); 125 + println!( 126 + "Day {} Parse Func: {:?} (N = {})", 127 + Self::DAY, 128 + parse_time, 129 + sample_size 130 + ); 131 + 132 + let (part_time, sample_size, _output) = match part { 133 + 1 => bench!(Self::part_1(input.clone())), 134 + 2 => bench!(Self::part_2(input.clone())), 135 + _ => panic!("Invalid Part Number"), 136 + }; 137 + 138 + println!( 139 + "Day {} Part {}: {:?} (N = {})", 140 + Self::DAY, 141 + part, 142 + part_time, 143 + sample_size 144 + ); 84 145 } 85 146 86 147 fn run_all_parts(extra_indent: &str) {
+14
advent_core/src/year.rs
··· 7 7 8 8 fn solve_day(day: usize, part: usize, input: Option<&str>) -> Option<String>; 9 9 10 + fn bench_day(day: usize, part: usize, input: Option<&str>); 11 + 10 12 fn solve_day_both_parts(day: usize, extra_indent: &str); 11 13 12 14 fn solve_all_days() { ··· 29 31 Self::solve_day(day, part, input); 30 32 } 31 33 }, 34 + } 35 + } 36 + 37 + fn bench_dp(input: Option<&str>, dp: DP) { 38 + match dp.day { 39 + Selection::Single(day) => match dp.part { 40 + Selection::Single(part) => { 41 + Self::bench_day(day, part, input); 42 + } 43 + _ => panic!("Cannot bench all parts, sorry :("), 44 + }, 45 + _ => panic!("Cannot bench all days, sorry :("), 32 46 } 33 47 } 34 48 }
+14 -1
justfile
··· 1 1 2 2 _default: 3 - cargo run --release -- solve * 3 + @just --list --unsorted --justfile {{justfile()}} 4 4 5 5 year := `date +%Y` 6 6 day := `nu -c 'date now | format date "%_d" | str trim'` 7 7 8 + # Run a specific part of today's problem 8 9 p P in="": 9 10 cargo run --release -- solve {{year}}:{{day}}:{{P}} {{in}} 10 11 12 + # Run a specific day and part of this year 11 13 dp DP in="": 12 14 cargo run --release -- solve {{year}}:{{DP}} {{in}} 13 15 16 + # Run a specific year's day's part 14 17 dyp DYP in="": 15 18 cargo run --release -- solve {{DYP}} {{in}} 16 19 20 + # Create a new year crate 17 21 prep: 18 22 cargo run --release -- new {{year}} 19 23 24 + # Test today's solution against examples 25 + test: 26 + cargo test -p y_{{year}} --release day_{{day}}_part_ 27 + 28 + # Test all of this year's solutions against examples 29 + test-all: 30 + cargo test -p y_{{year}} --release 31 + 32 + # Open VSCodium to today's file 20 33 start: 21 34 codium . --goto years/{{year}}/src/day_{{day}}.rs
+18 -4
macros/src/lib.rs
··· 47 47 48 48 fn get_solve_day() -> String { 49 49 let inner = make_day_match("Day{day}::run_part(part, input)"); 50 + let inner2 = make_day_match("{Day{day}::bench_part(part, input);}"); 50 51 format!( 51 52 " 52 53 fn solve_day(day: usize, part: usize, input: Option<&str>) -> Option<String> {{ ··· 54 55 {inner} 55 56 _ => None, 56 57 }} 57 - }}", 58 - inner = inner 58 + }} 59 + fn bench_day(day: usize, part: usize, input: Option<&str>) {{ 60 + match day {{ 61 + {inner2} 62 + _ => panic!(\"Invalid Day\"), 63 + }} 64 + }}" 59 65 ) 60 66 } 61 67 ··· 181 187 182 188 fn make_run_year(years: &[&str]) -> String { 183 189 let inner = make_year_match(years, "Year{year}::run_dp(input.as_deref(), dp)"); 190 + let inner2 = make_year_match(years, "Year{year}::bench_dp(input.as_deref(), dp)"); 184 191 format!( 185 192 " 186 193 fn run_year(year: usize, dp: DP, input: Option<&str>) {{ ··· 190 197 println!(\"Unknown year: {{year}}\"); 191 198 }} 192 199 }} 193 - }}", 194 - inner = inner 200 + }} 201 + fn bench_year(year: usize, dp: DP, input: Option<&str>) {{ 202 + match year {{ 203 + {inner2} 204 + _ => {{ 205 + println!(\"Unknown year: {{year}}\"); 206 + }} 207 + }} 208 + }}" 195 209 ) 196 210 } 197 211
+16 -1
src/main.rs
··· 16 16 } 17 17 } 18 18 19 + fn bench_ydp(ydp: YDP, input: Option<String>) { 20 + let dp = ydp.to_dp(); 21 + 22 + match ydp.year { 23 + Selection::Single(year) => { 24 + bench_year(year, dp, input.as_deref()); 25 + } 26 + _ => panic!("Cannot Bench All Years"), 27 + } 28 + } 29 + 19 30 fn main() { 20 31 let args = std::env::args().skip(1).collect::<Vec<_>>(); 21 32 ··· 31 42 let (ydp, input) = get_ydp_and_input(args[1..].to_vec()); 32 43 run_ydp(ydp, input); 33 44 } 45 + "bench" => { 46 + let (ydp, input) = get_ydp_and_input(args[1..].to_vec()); 47 + bench_ydp(ydp, input); 48 + } 34 49 _ => { 35 50 println!("Unknown command: {}", command); 36 - println!("Available commands: new, solve"); 51 + println!("Available commands: new, solve, bench"); 37 52 } 38 53 }, 39 54 None => {