macro_rules! solution_printer {
($day_n: expr, $printer_name: ident, $input_generator: ident, $input: ident, $solver_part_1: ident, $solver_part_2: ident) =>
{
use std::io::Write;
pub fn $printer_name (part: crate::Part) -> std::io::Result<()>
{
if part == crate::Part::Both
{
$printer_name(crate::Part::One)?;
return $printer_name(crate::Part::Two);
}
let stdout = std::io::stdout();
writeln!(stdout.lock(), "Day {}, part {}", $day_n, part)?;
let t0 = std::time::Instant::now();
let mut input = $input_generator($input);
let t1 = std::time::Instant::now();
let solution: String = match part
{
crate::Part::One => format!("{}", $solver_part_1(&mut input)),
crate::Part::Two => format!("{}", $solver_part_2(&mut input)),
crate::Part::Both => unreachable!(),
};
let t2 = std::time::Instant::now();
let mut handle = stdout.lock();
writeln!(handle, " - Input generator: {:?}", t1 - t0)?;
writeln!(handle, " - Solver: {:?}", t2 - t1)?;
let mut solution_lines = solution.lines();
let solution_first_line = solution_lines.next().unwrap();
writeln!(handle, " - Solution: {}", solution_first_line)?;
while let Some(solution_line) = solution_lines.next()
{
writeln!(handle, " {}", solution_line)?;
};
Ok(())
}
};
}
use chrono::prelude::*;
#[macro_export]
macro_rules! debug_log {
($log_entry: expr) =>
{
let ts = crate::Utc::now();
let stdout = std::io::stdout();
writeln!(stdout.lock(), "{} -- {}", ts, $log_entry)
};
}
pub mod day_01;
pub mod day_02;
pub mod day_03;
pub mod day_04;
pub mod day_05;
pub mod day_06;
pub mod day_07;
pub mod day_08;
pub mod day_09;
pub const AOC_SOLUTION_PRINTERS: &[fn(Part) -> std::io::Result<()>] =
&[
day_01::print_solution,
day_02::print_solution,
day_03::print_solution,
day_04::print_solution,
day_05::print_solution,
day_06::print_solution,
day_07::print_solution,
day_08::print_solution,
day_09::print_solution,
];
#[derive(PartialEq)]
pub enum Part
{
One,
Two,
Both,
}
impl std::convert::From<&str> for Part
{
fn from (part_num_str: &str) -> Self
{
match part_num_str
{
"1" => Self::One,
"2" => Self::Two,
_ => panic!("Unknown part {}", part_num_str),
}
}
}
impl std::fmt::Display for Part
{
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>
{
f.write_fmt(format_args!("{}", match self
{
Part::One => "1",
Part::Two => "2",
Part::Both => "Both",
}))
}
}