2021-12-29 14:12:01 +01:00
|
|
|
use std::env;
|
|
|
|
use std::fs;
|
|
|
|
|
2021-12-29 19:14:40 +01:00
|
|
|
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
|
|
|
pub const ANSI_BOLD: &str = "\x1b[1m";
|
|
|
|
pub const ANSI_RESET: &str = "\x1b[0m";
|
2021-12-29 14:36:48 +01:00
|
|
|
|
|
|
|
#[macro_export]
|
2021-12-29 19:14:40 +01:00
|
|
|
macro_rules! solve {
|
2021-12-29 14:36:48 +01:00
|
|
|
($input:expr, $part_one:ident, $part_two:ident) => {{
|
|
|
|
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
|
|
|
|
use std::fmt::Display;
|
|
|
|
use std::time::Instant;
|
|
|
|
|
|
|
|
fn print_result<T: Display>(func: impl FnOnce(&str) -> T, input: &str) {
|
|
|
|
let timer = Instant::now();
|
|
|
|
let result = func(input);
|
2021-12-30 11:34:27 +01:00
|
|
|
let elapsed = timer.elapsed();
|
2021-12-29 14:36:48 +01:00
|
|
|
println!(
|
|
|
|
"{} {}(elapsed: {:.2?}){}",
|
2021-12-30 11:34:27 +01:00
|
|
|
result, ANSI_ITALIC, elapsed, ANSI_RESET
|
2021-12-29 14:36:48 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("🎄 {}Part 1{} 🎄", ANSI_BOLD, ANSI_RESET);
|
|
|
|
println!("");
|
|
|
|
print_result($part_one, $input);
|
|
|
|
println!("");
|
|
|
|
println!("🎄 {}Part 2{} 🎄", ANSI_BOLD, ANSI_RESET);
|
|
|
|
println!("");
|
|
|
|
print_result($part_two, $input);
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2021-12-29 14:12:01 +01:00
|
|
|
pub fn read_file(folder: &str, day: u8) -> String {
|
|
|
|
let cwd = env::current_dir().unwrap();
|
|
|
|
|
2021-12-29 14:36:48 +01:00
|
|
|
let filepath = cwd.join("src").join(folder).join(format!("{:02}.txt", day));
|
2021-12-29 14:12:01 +01:00
|
|
|
|
|
|
|
let f = fs::read_to_string(filepath);
|
|
|
|
f.expect("could not open input file")
|
|
|
|
}
|
2021-12-29 19:14:40 +01:00
|
|
|
|
|
|
|
fn parse_time(val: &str, postfix: &str) -> f64 {
|
|
|
|
val.split(postfix).next().unwrap().parse().unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn parse_exec_time(output: &str) -> f64 {
|
|
|
|
output.lines().fold(0_f64, |acc, l| {
|
|
|
|
if !l.contains("elapsed:") {
|
|
|
|
acc
|
|
|
|
} else {
|
2021-12-31 13:05:23 +01:00
|
|
|
let timing = l.split("(elapsed: ").last().unwrap();
|
|
|
|
// use `contains` istd. of `ends_with`: string may contain ANSI escape sequences.
|
2022-04-26 09:11:57 +02:00
|
|
|
// possible time formats: see [rust/library/core/src/time.rs](https://github.com/rust-lang/rust/blob/1.57.0/library/core/src/time.rs#L1225-L1249).
|
2021-12-31 13:05:23 +01:00
|
|
|
if timing.contains("ns)") {
|
2021-12-29 19:14:40 +01:00
|
|
|
acc // range below rounding precision.
|
2021-12-31 13:05:23 +01:00
|
|
|
} else if timing.contains("µs)") {
|
2021-12-29 19:14:40 +01:00
|
|
|
acc + parse_time(timing, "µs") / 1000_f64
|
2021-12-31 13:05:23 +01:00
|
|
|
} else if timing.contains("ms)") {
|
2021-12-29 19:14:40 +01:00
|
|
|
acc + parse_time(timing, "ms")
|
2021-12-31 13:05:23 +01:00
|
|
|
} else if timing.contains("s)") {
|
2021-12-29 19:14:40 +01:00
|
|
|
acc + parse_time(timing, "s") * 1000_f64
|
|
|
|
} else {
|
|
|
|
acc
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
2022-04-26 09:11:57 +02:00
|
|
|
/// copied from: [rust/library/std/src/macros.rs](https://github.com/rust-lang/rust/blob/1.57.0/library/std/src/macros.rs#L311-L316)
|
2021-12-29 19:14:40 +01:00
|
|
|
macro_rules! assert_approx_eq {
|
|
|
|
($a:expr, $b:expr) => {{
|
|
|
|
let (a, b) = (&$a, &$b);
|
|
|
|
assert!(
|
|
|
|
(*a - *b).abs() < 1.0e-6,
|
|
|
|
"{} is not approximately equal to {}",
|
|
|
|
*a,
|
|
|
|
*b
|
|
|
|
);
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_parse_exec_time() {
|
|
|
|
assert_approx_eq!(
|
2021-12-31 13:05:23 +01:00
|
|
|
parse_exec_time(&format!(
|
|
|
|
"🎄 Part 1 🎄\n0 (elapsed: 74.13ns){}\n🎄 Part 2 🎄\n0 (elapsed: 50.00ns){}",
|
|
|
|
ANSI_RESET, ANSI_RESET
|
|
|
|
)),
|
2021-12-29 19:14:40 +01:00
|
|
|
0_f64
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_approx_eq!(
|
|
|
|
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 755µs)\n🎄 Part 2 🎄\n0 (elapsed: 700µs)"),
|
|
|
|
1.455_f64
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_approx_eq!(
|
|
|
|
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 70µs)\n🎄 Part 2 🎄\n0 (elapsed: 1.45ms)"),
|
|
|
|
1.52_f64
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_approx_eq!(
|
|
|
|
parse_exec_time(
|
|
|
|
"🎄 Part 1 🎄\n0 (elapsed: 10.3s)\n🎄 Part 2 🎄\n0 (elapsed: 100.50ms)"
|
|
|
|
),
|
|
|
|
10400.50_f64
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|