codetrotter_aoc_2019_solutions 0.9.0

Advent of Code 2019 Solutions
Documentation
/*
 * Copyright (c) 2019, 2020 Erik Nordstrøm <erik@nordstroem.no>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

//! ## Advent of Code 2019 Solutions
//!
//! My solutions for [Advent of Code 2019](https://adventofcode.com/2019/) in Rust.
//!
//! Source on GitHub: [https://github.com/ctsrc/aoc-2019](https://github.com/ctsrc/aoc-2019)

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 mod day_10;
pub mod day_11;
pub mod day_12;
pub mod day_13;
pub mod day_14;
pub mod day_15;
pub mod day_16;
pub mod day_17;
pub mod day_18;
pub mod day_19;
pub mod day_20;
pub mod day_21;
pub mod day_22;
pub mod day_23;
pub mod day_24;
pub mod day_25;
*/

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",
    }))
  }
}