mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 17:45:02 +01:00
improve
This commit is contained in:
parent
eb8f0855bf
commit
3fb4bf282b
4 changed files with 189 additions and 98 deletions
|
|
@ -2,13 +2,46 @@ mod cmd;
|
|||
mod ext;
|
||||
mod hash;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::{borrow::Cow, fmt::Debug};
|
||||
|
||||
pub use self::cmd::main;
|
||||
pub use self::ext::*;
|
||||
pub use self::hash::*;
|
||||
|
||||
pub type Solution = fn(&str) -> u64;
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum Answer {
|
||||
U64(u64),
|
||||
String(String),
|
||||
}
|
||||
impl Debug for Answer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::U64(arg0) => Debug::fmt(arg0, f),
|
||||
Self::String(arg0) => Debug::fmt(arg0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Display for Answer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::U64(arg0) => Display::fmt(arg0, f),
|
||||
Self::String(arg0) => Display::fmt(arg0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<u64> for Answer {
|
||||
fn from(value: u64) -> Self {
|
||||
Answer::U64(value)
|
||||
}
|
||||
}
|
||||
impl From<String> for Answer {
|
||||
fn from(value: String) -> Self {
|
||||
Answer::String(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Solution = fn(&str) -> Answer;
|
||||
|
||||
pub trait Day {
|
||||
fn part1() -> Variants;
|
||||
|
|
@ -46,12 +79,13 @@ impl Variant {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn test_part1<D: Day>(inputs: &[(&str, &str, u64)]) {
|
||||
#[track_caller]
|
||||
pub fn test_part1<D: Day>(inputs: &[(&str, &str, Answer)]) {
|
||||
for variant in D::part1().variants {
|
||||
for input in inputs {
|
||||
let (path, input, expected) = *input;
|
||||
let (path, input, expected) = input;
|
||||
let actual = (variant.f)(input);
|
||||
if actual != expected {
|
||||
if actual != *expected {
|
||||
panic!(
|
||||
"failed: {}: {}: {} != {}",
|
||||
path, variant.name, actual, expected
|
||||
|
|
@ -61,12 +95,13 @@ pub fn test_part1<D: Day>(inputs: &[(&str, &str, u64)]) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn test_part2<D: Day>(inputs: &[(&str, &str, u64)]) {
|
||||
#[track_caller]
|
||||
pub fn test_part2<D: Day>(inputs: &[(&str, &str, Answer)]) {
|
||||
for variant in D::part2().variants {
|
||||
for input in inputs {
|
||||
let (path, input, expected) = *input;
|
||||
let (path, input, expected) = input;
|
||||
let actual = (variant.f)(input);
|
||||
if actual != expected {
|
||||
if actual != *expected {
|
||||
panic!(
|
||||
"failed: {}: {}: {} != {}",
|
||||
path, variant.name, actual, expected
|
||||
|
|
@ -120,7 +155,10 @@ macro_rules! construct_variants {
|
|||
( $day:ty; $( ($name:ident, $func:expr, [ $($_:tt)* ]) ),*) => {
|
||||
$crate::Variants {
|
||||
variants: vec![$(
|
||||
$crate::Variant::new(stringify!($name), std::hint::black_box($func))
|
||||
$crate::Variant::new(stringify!($name), |input| {
|
||||
let answer = $func(input);
|
||||
$crate::Answer::from(answer)
|
||||
})
|
||||
),*]
|
||||
}
|
||||
};
|
||||
|
|
@ -173,41 +211,32 @@ macro_rules! _define_benchmarks {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! _test_name_to_file {
|
||||
(small) => {
|
||||
"../input_small.txt"
|
||||
};
|
||||
(default) => {
|
||||
"../input.txt"
|
||||
};
|
||||
($path:expr) => {
|
||||
$path
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! tests {
|
||||
(
|
||||
$day_small:ident $day:ident;
|
||||
part1 {
|
||||
small => $p1small:expr;
|
||||
default => $p1default:expr;
|
||||
}
|
||||
part2 {
|
||||
small => $p2small:expr;
|
||||
default => $p2default:expr;
|
||||
}
|
||||
) => {
|
||||
$crate::tests! {
|
||||
$day_small $day;
|
||||
part1 {
|
||||
"../input_small.txt" => $p1small;
|
||||
"../input.txt" => $p1default;
|
||||
}
|
||||
part2 {
|
||||
"../input_small.txt" => $p2small;
|
||||
"../input.txt" => $p2default;
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
$day_small:ident $day:ident;
|
||||
part1 {
|
||||
$(
|
||||
$file1:literal => $p1:expr;
|
||||
$file1:tt => $p1:expr;
|
||||
)*
|
||||
}
|
||||
part2 {
|
||||
$(
|
||||
$file2:literal => $p2:expr;
|
||||
$file2:tt => $p2:expr;
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
|
|
@ -217,7 +246,7 @@ macro_rules! tests {
|
|||
fn part1() {
|
||||
helper::test_part1::<super::$day>(&[
|
||||
$(
|
||||
($file1, include_str!($file1), $p1),
|
||||
($crate::_test_name_to_file!($file1), include_str!($crate::_test_name_to_file!($file1)), $crate::Answer::from($p1)),
|
||||
)*
|
||||
]);
|
||||
}
|
||||
|
|
@ -226,7 +255,7 @@ macro_rules! tests {
|
|||
fn part2() {
|
||||
helper::test_part2::<super::$day>(&[
|
||||
$(
|
||||
($file2, include_str!($file2), $p2),
|
||||
($crate::_test_name_to_file!($file2), include_str!($crate::_test_name_to_file!($file2)), $crate::Answer::from($p2)),
|
||||
)*
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue