elvish_core/
solution.rs

1//! Traits for declaring solutions of advent of code puzzles, and functions for running them. 
2
3use std::fmt::Display;
4
5/// A solution of a part of an advent of code puzzle. 
6///
7/// It takes the input as a string slice and returns some output that can be converted to a string.
8pub trait Part<const PART: u8, const DAY: u8> {
9    /// Solves the puzzle for that part. 
10    fn solve(input: &str) -> impl Display;
11}
12
13/// Solution for both parts of a day 
14///
15/// It is auto-implemented for any type that implements [`Part`] for both parts of
16/// a day. 
17pub trait Day<const DAY: u8>: Part<1, DAY> + Part<2, DAY> {
18    /// Solves the puzzle for that part 1 of the day. 
19    fn part1(input: &str) -> impl Display;
20
21    /// Solves the puzzle for that part 2 of the day. 
22    fn part2(input: &str) -> impl Display;
23}
24
25// Auto implement the `Day` trait for any type that implements the `Part` trait for a day
26impl<T, const DAY: u8> Day<DAY> for T
27where
28    T: Part<1, DAY> + Part<2, DAY>,
29{
30    fn part1(input: &str) -> impl Display {
31        <T as Part<1, DAY>>::solve(input)
32    }
33
34    fn part2(input: &str) -> impl Display {
35        <T as Part<1, DAY>>::solve(input)
36    }
37}
38
39// Nicer API
40/// Run the solution of a given part for the given day, returning the result as a string. 
41///
42/// It is mostly used as a nicer way to not need to specify `<Solution as Part<X,
43/// Y>>::solve(input).to_string()`.
44///
45/// See also [`run_day`] to run the entire day. 
46pub fn run_day_part<Solutions: Part<PART, DAY>, const DAY: u8, const PART: u8>(
47    input: &str,
48) -> String {
49    Solutions::solve(input).to_string()
50}
51
52/// Run the solution of both parts for a given day, returning the result as a string. 
53///
54/// See also [`run_day_part`] to run an individual part. 
55pub fn run_day<Solutions: Day<DAY>, const DAY: u8>(input: &str) -> [String; 2] {
56    let part1 = run_day_part::<Solutions, DAY, 1>(input);
57    let part2 = run_day_part::<Solutions, DAY, 2>(input);
58
59    [part1, part2]
60}
61
62/// Run a day dynamically (with the day itself specified at runtime).
63///
64/// Assumes there is a full advent of code solution. 
65pub fn run<
66    Solutions: Day<1>
67        + Day<2>
68        + Day<3>
69        + Day<4>
70        + Day<5>
71        + Day<6>
72        + Day<7>
73        + Day<8>
74        + Day<9>
75        + Day<10>
76        + Day<11>
77        + Day<12>
78        + Day<13>
79        + Day<14>
80        + Day<15>
81        + Day<16>
82        + Day<17>
83        + Day<18>
84        + Day<19>
85        + Day<20>
86        + Day<21>
87        + Day<22>
88        + Day<23>
89        + Day<24>
90        + Day<25>,
91>(
92    input: &str,
93    day: u8,
94) -> [String; 2] {
95    match day {
96        1 => run_day::<Solutions, 1>(input),
97        2 => run_day::<Solutions, 2>(input),
98        3 => run_day::<Solutions, 3>(input),
99        4 => run_day::<Solutions, 4>(input),
100        5 => run_day::<Solutions, 5>(input),
101        6 => run_day::<Solutions, 6>(input),
102        7 => run_day::<Solutions, 7>(input),
103        8 => run_day::<Solutions, 8>(input),
104        9 => run_day::<Solutions, 9>(input),
105        10 => run_day::<Solutions, 10>(input),
106        11 => run_day::<Solutions, 11>(input),
107        12 => run_day::<Solutions, 12>(input),
108        13 => run_day::<Solutions, 13>(input),
109        14 => run_day::<Solutions, 14>(input),
110        15 => run_day::<Solutions, 15>(input),
111        16 => run_day::<Solutions, 16>(input),
112        17 => run_day::<Solutions, 17>(input),
113        18 => run_day::<Solutions, 18>(input),
114        19 => run_day::<Solutions, 19>(input),
115        20 => run_day::<Solutions, 20>(input),
116        21 => run_day::<Solutions, 21>(input),
117        22 => run_day::<Solutions, 22>(input),
118        23 => run_day::<Solutions, 23>(input),
119        24 => run_day::<Solutions, 24>(input),
120        25 => run_day::<Solutions, 25>(input),
121        _ => panic!("Day should be between 1 and 25 (inclusive)"),
122    }
123}