aoc_next/
solution.rs

1// SPDX-FileCopyrightText: 2020 Florian Warzecha <liketechnik@disroot.org>
2//
3// SPDX-License-Identifier: MPL-2.0
4
5use crate::Aoc;
6use std::marker::PhantomData;
7use std::time::Instant;
8
9use anyhow::Result;
10
11use crate::input::get_input;
12use crate::parser::Parsing;
13
14/// A container that can get input, parse it and execute a solver.
15///
16/// Implemented by [`Solution`].
17pub trait Solvable {
18    fn run(&self, aoc: &Aoc) -> Result<()>;
19    fn day(&self) -> u8;
20}
21
22/// A solution for a specific exercise.
23pub struct Solution<P, S, I, O: std::fmt::Display>
24where
25    P: Parsing<I>,
26    S: Fn(I) -> O,
27{
28    /// The day of the exercise; used to determine the input to use.
29    pub day: u8,
30    /// The parser for the input.
31    pub parser: P,
32    /// The solver of the exercise.
33    pub solver: Solver<S, I, O>,
34}
35
36impl<P, S, I, O: std::fmt::Display> Solvable for Solution<P, S, I, O>
37where
38    P: Parsing<I>,
39    S: Fn(I) -> O,
40{
41    fn run(&self, aoc: &Aoc) -> Result<()> {
42        let input = get_input(aoc, self.day)?;
43
44        print!(
45            "Day {} - {} with {}: ",
46            self.day,
47            self.solver.name,
48            self.parser.name()
49        );
50
51        let parse_start = Instant::now();
52        let parsed_input = self.parser.run(&input);
53        let parse_end = Instant::now();
54
55        match parsed_input {
56            Ok(parsed_input) => {
57                let run_start = Instant::now();
58                let result = (self.solver.run)(parsed_input);
59                let run_end = Instant::now();
60
61                println!("{}", result);
62                println!("\tparser: {:?}", parse_end - parse_start);
63                println!("\tsolver: {:?}", run_end - run_start);
64            }
65            Err(e) => eprintln!("Parser failed: {}", e),
66        }
67
68        Ok(())
69    }
70
71    fn day(&self) -> u8 {
72        self.day
73    }
74}
75
76/// Container for a solving function.
77///
78/// The contained function solves a specific
79/// exercise.
80pub struct Solver<F, I, O: std::fmt::Display>
81where
82    F: Fn(I) -> O,
83{
84    pub marker: PhantomData<I>,
85    pub name: &'static str,
86    pub run: F,
87}