|
1 | 1 | use std::env; |
2 | 2 | use std::fs; |
3 | 3 |
|
4 | | -pub static ANSI_ITALIC: &str = "\x1b[3m"; |
5 | | -pub static ANSI_BOLD: &str = "\x1b[1m"; |
6 | | -pub static ANSI_RESET: &str = "\x1b[0m"; |
| 4 | +pub const ANSI_ITALIC: &str = "\x1b[3m"; |
| 5 | +pub const ANSI_BOLD: &str = "\x1b[1m"; |
| 6 | +pub const ANSI_RESET: &str = "\x1b[0m"; |
7 | 7 |
|
8 | 8 | #[macro_export] |
9 | | -macro_rules! solve_day { |
| 9 | +macro_rules! solve { |
10 | 10 | ($input:expr, $part_one:ident, $part_two:ident) => {{ |
11 | 11 | use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET}; |
12 | 12 | use std::fmt::Display; |
@@ -40,3 +40,78 @@ pub fn read_file(folder: &str, day: u8) -> String { |
40 | 40 | let f = fs::read_to_string(filepath); |
41 | 41 | f.expect("could not open input file") |
42 | 42 | } |
| 43 | + |
| 44 | +fn parse_time(val: &str, postfix: &str) -> f64 { |
| 45 | + val.split(postfix).next().unwrap().parse().unwrap() |
| 46 | +} |
| 47 | + |
| 48 | +pub fn parse_exec_time(output: &str) -> f64 { |
| 49 | + output.lines().fold(0_f64, |acc, l| { |
| 50 | + if !l.contains("elapsed:") { |
| 51 | + acc |
| 52 | + } else { |
| 53 | + let timing = l |
| 54 | + .split("(elapsed: ") |
| 55 | + .last() |
| 56 | + .unwrap(); |
| 57 | + |
| 58 | + // see [rust/library/core/src/time.rs](https://git.io/Jy1rI) |
| 59 | + if timing.ends_with("ns)") { |
| 60 | + acc // range below rounding precision. |
| 61 | + } else if timing.ends_with("µs)") { |
| 62 | + acc + parse_time(timing, "µs") / 1000_f64 |
| 63 | + } else if timing.ends_with("ms)") { |
| 64 | + acc + parse_time(timing, "ms") |
| 65 | + } else if timing.ends_with("s)") { |
| 66 | + acc + parse_time(timing, "s") * 1000_f64 |
| 67 | + } else { |
| 68 | + acc |
| 69 | + } |
| 70 | + } |
| 71 | + }) |
| 72 | +} |
| 73 | + |
| 74 | +#[cfg(test)] |
| 75 | +mod tests { |
| 76 | + use super::*; |
| 77 | + |
| 78 | + /// copied from: [rust/library/std/src/macros.rs](https://git.io/Jy1r7) |
| 79 | + macro_rules! assert_approx_eq { |
| 80 | + ($a:expr, $b:expr) => {{ |
| 81 | + let (a, b) = (&$a, &$b); |
| 82 | + assert!( |
| 83 | + (*a - *b).abs() < 1.0e-6, |
| 84 | + "{} is not approximately equal to {}", |
| 85 | + *a, |
| 86 | + *b |
| 87 | + ); |
| 88 | + }}; |
| 89 | + } |
| 90 | + |
| 91 | + #[test] |
| 92 | + fn test_parse_exec_time() { |
| 93 | + assert_approx_eq!( |
| 94 | + parse_exec_time( |
| 95 | + "🎄 Part 1 🎄\n0 (elapsed: 74.13ns)\n🎄 Part 2 🎄\n0 (elapsed: 50.00ns)" |
| 96 | + ), |
| 97 | + 0_f64 |
| 98 | + ); |
| 99 | + |
| 100 | + assert_approx_eq!( |
| 101 | + parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 755µs)\n🎄 Part 2 🎄\n0 (elapsed: 700µs)"), |
| 102 | + 1.455_f64 |
| 103 | + ); |
| 104 | + |
| 105 | + assert_approx_eq!( |
| 106 | + parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 70µs)\n🎄 Part 2 🎄\n0 (elapsed: 1.45ms)"), |
| 107 | + 1.52_f64 |
| 108 | + ); |
| 109 | + |
| 110 | + assert_approx_eq!( |
| 111 | + parse_exec_time( |
| 112 | + "🎄 Part 1 🎄\n0 (elapsed: 10.3s)\n🎄 Part 2 🎄\n0 (elapsed: 100.50ms)" |
| 113 | + ), |
| 114 | + 10400.50_f64 |
| 115 | + ); |
| 116 | + } |
| 117 | +} |
0 commit comments