···66# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7788[dependencies]
99+indicatif = "0.17.9"
910regex = "1.10.2"
+62-1
advent_core/src/day.rs
···11use std::time::Instant;
2233+use indicatif::ProgressStyle;
44+35#[macro_export]
46macro_rules! ex_for_day {
57 ($day:literal, $part:literal) => {
···3436 }
3537}
36383939+const BENCH_SECS: u64 = 5;
4040+const PROGRESS_TEMPLATE: &str = "{spinner} {wide_msg} [{bar:100.green/cyan}]";
4141+const PROGRESS_CHARS: &str = "=>-";
4242+4343+macro_rules! bench {
4444+ ($t:expr) => {{
4545+ let outer_instant = std::time::Instant::now();
4646+ let mut times = Vec::<std::time::Duration>::with_capacity(1000);
4747+ let mut res = None;
4848+ let style = ProgressStyle::with_template(PROGRESS_TEMPLATE)
4949+ .unwrap()
5050+ .progress_chars(PROGRESS_CHARS);
5151+ let progress = indicatif::ProgressBar::new(BENCH_SECS);
5252+ progress.set_style(style);
5353+ let mut i = 0;
5454+ while outer_instant.elapsed().as_secs() <= BENCH_SECS {
5555+ let instant = std::time::Instant::now();
5656+ let r = $t;
5757+ if res.is_none() {
5858+ res = Some(r)
5959+ }
6060+ times.push(instant.elapsed());
6161+ i += 1;
6262+ progress.set_message(format!("{i} Runs"));
6363+ progress.set_position(outer_instant.elapsed().as_secs());
6464+ }
6565+ (
6666+ times.iter().sum::<std::time::Duration>() / (times.len() as u32),
6767+ times.len(),
6868+ res.unwrap(),
6969+ )
7070+ }};
7171+}
7272+3773/// A trait for a day of Advent of Code.
3874///
3975/// This trait is implemented for each day of Advent of Code.
···4682/// Then, any runner can use `run_part` to run a part of the day with a given input or the example input.
4783///
4884pub trait Day {
4949- type Input;
8585+ type Input: Clone;
50865187 const DAY: usize = 0;
5288···81117 instant.elapsed()
82118 );
83119 solution
120120+ }
121121+122122+ fn bench_part(part: usize, input: Option<&str>) {
123123+ let input = input.unwrap_or_else(|| Self::get_example_input(part));
124124+ let (parse_time, sample_size, input) = bench!(Self::parse_input(input));
125125+ println!(
126126+ "Day {} Parse Func: {:?} (N = {})",
127127+ Self::DAY,
128128+ parse_time,
129129+ sample_size
130130+ );
131131+132132+ let (part_time, sample_size, _output) = match part {
133133+ 1 => bench!(Self::part_1(input.clone())),
134134+ 2 => bench!(Self::part_2(input.clone())),
135135+ _ => panic!("Invalid Part Number"),
136136+ };
137137+138138+ println!(
139139+ "Day {} Part {}: {:?} (N = {})",
140140+ Self::DAY,
141141+ part,
142142+ part_time,
143143+ sample_size
144144+ );
84145 }
8514686147 fn run_all_parts(extra_indent: &str) {
···1122_default:
33- cargo run --release -- solve *
33+ @just --list --unsorted --justfile {{justfile()}}
4455year := `date +%Y`
66day := `nu -c 'date now | format date "%_d" | str trim'`
7788+# Run a specific part of today's problem
89p P in="":
910 cargo run --release -- solve {{year}}:{{day}}:{{P}} {{in}}
10111212+# Run a specific day and part of this year
1113dp DP in="":
1214 cargo run --release -- solve {{year}}:{{DP}} {{in}}
13151616+# Run a specific year's day's part
1417dyp DYP in="":
1518 cargo run --release -- solve {{DYP}} {{in}}
16192020+# Create a new year crate
1721prep:
1822 cargo run --release -- new {{year}}
19232424+# Test today's solution against examples
2525+test:
2626+ cargo test -p y_{{year}} --release day_{{day}}_part_
2727+2828+# Test all of this year's solutions against examples
2929+test-all:
3030+ cargo test -p y_{{year}} --release
3131+3232+# Open VSCodium to today's file
2033start:
2134 codium . --goto years/{{year}}/src/day_{{day}}.rs