1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
//! # `impl Solution<'_, Day25, Part2> for AdventOfCode2021<Day25>`
//!
//! ## What is this?
//!
//! This is [`advent_of_code_traits`](https://github.com/drmason13/advent_of_code_traits), a set of traits to implement solutions to Advent of Code in Rust.
//!
//! It takes a trait-based approach using const-generics and autoderef specialization.
//!
//! It's basically an excuse to play with rust's type system.
//!
//! ## Usage
//!
//! Please see also the [examples](https://github.com/drmason13/advent_of_code_traits/tree/main/examples).
//!
//! Implement traits with your solutions to each day of Advent of Code.
//!
//! ### Import the machinery:
//!
//! ```
//! use advent_of_code_traits::{days::*, MissingPartTwo, Part1, Part2, ParseInput, run, Solution, SolutionRunner};
//! ```
//!
//! ### Implement [`Solution`] for your struct.
//!
//! ```
//! # use advent_of_code_traits::{days::*, MissingPartTwo, Part1, Part2, ParseInput, run, Solution, SolutionRunner};
//! pub struct AdventOfCode2021<const DAY: u32>;
//!
//! impl Solution<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! type Input = Vec<u32>;
//! type Output = u32;
//!
//! fn solve(&self, input: &Self::Input) -> Self::Output {
//! // your solution to Part1 here...
//! # 1
//! }
//! }
//!
//! # impl ParseInput<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! # type Parsed = Vec<u32>; // <-- the input to both PartOne and PartTwo for Solution<Day1>
//! #
//! # fn parse_input(&self, input: &str) -> Self::Parsed {
//! # input
//! # .lines()
//! # .map(|s| s.parse().expect("invalid integer"))
//! # .collect()
//! # }
//! # }
//! # impl MissingPartTwo<Day25> for AdventOfCode2021<Day25> {}
//! ```
//!
//! That's how we solve the solution given a nicely typed `Vec<u32>`, but Advent of Code gives us plaintext input.
//!
//! So first we need to parse the input...
//!
//! ### Implement [`ParseInput`] for your struct
//!
//! ```
//! # use advent_of_code_traits::{days::*, MissingPartTwo, Part1, Part2, ParseInput, run, Solution, SolutionRunner};
//! # pub struct AdventOfCode2021<const DAY: u32>;
//! #
//! # impl Solution<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! # type Input = Vec<u32>;
//! # type Output = u32;
//! #
//! # fn solve(&self, input: &Vec<u32>) -> u32 {
//! # // your solution to Part1 here...
//! # 1
//! # }
//! # }
//! // ..continued from above
//!
//! impl ParseInput<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! type Parsed = Vec<u32>; // <-- the input type fed to Solution::solve
//!
//! fn parse_input(&self, input: &'_ str) -> Self::Parsed {
//! input
//! .lines()
//! .map(|s| s.parse().expect("invalid integer"))
//! .collect()
//! }
//! }
//! # let input = "1\n2\n3";
//! # impl MissingPartTwo<Day25> for AdventOfCode2021<Day25> {}
//! # let prb = AdventOfCode2021::<Day25>;
//! # let parsed = &prb.parse_input(&input);
//! # let ans = prb.solve(&parsed);
//! # assert_eq!(1, ans);
//! ```
//!
//! ### Mark Part2 as missing
//!
//! To run only Part1 of a day of Advent of Code, you currently need to impl `MissingPartTwo` to help disambiguate the specialization:
//! ```no_run
//! impl MissingPartTwo<Day25> for AdventOfCode2021<Day25> {}
//! ```
//!
//! If you don't do this (and haven't implemented Solution for Part2) you'll see an error like:
//! ```text
//! the method `run` exists for reference `&&&AdventOfCode2021<25_u32>`, but its trait bounds were not satisfied
//! the following trait bounds were not satisfied:
//! `AdventOfCode2021<25_u32>: MissingPartTwo<25_u32>`
//! which is required by `AdventOfCode2021<25_u32>: SolutionRunner<25_u32, 1_u16>`rustcE0599
//! ```
//!
//! Please refer to the [examples](https://github.com/drmason13/advent_of_code_traits/tree/main/examples) for more demonstrations.
//!
//! ### Run from `main.rs`
//!
//! Here comes the part where we actually run our solution!
//! ```
//! # use advent_of_code_traits::{days::*, MissingPartTwo, Part1, Part2, ParseInput, run, Solution, SolutionRunner};
//! # pub struct AdventOfCode2021<const DAY: u32>;
//! #
//! # impl Solution<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! # type Input = Vec<u32>;
//! # type Output = u32;
//! #
//! # fn solve(&self, input: &Vec<u32>) -> u32 {
//! # // your solution to Part1 here...
//! # 1
//! # }
//! # }
//! # impl ParseInput<'_, Day25, Part1> for AdventOfCode2021<Day25> {
//! # type Parsed = Vec<u32>; // <-- the input to both PartOne and PartTwo for Solution<Day1>
//! #
//! # fn parse_input(&self, input: &str) -> Self::Parsed {
//! # input
//! # .lines()
//! # .map(|s| s.parse().expect("invalid integer"))
//! # .collect()
//! # }
//! # }
//! # impl MissingPartTwo<Day25> for AdventOfCode2021<Day25> {}
//! # // for test purposes, circumvent the example code
//! # if false {
//! let input = std::fs::read_to_string("./input/2021/day25.txt").expect("failed to read input");
//! # }
//! # let input = "1\n2\n3";
//! run!(AdventOfCode2021::<Day25>, &input);
//! ```
//! This reads input from a file and passes it to your struct to parse and then solve.
//! It will print the output of your solution (which must impl Debug).
//!
//! [`run`] is currently a humble `macro_rules!` declarative macro and is *very* simple.
//! It's main purpose is to veil the use of autoderef [`specialization`].
use std::fmt::Debug;
pub mod days;
#[allow(non_upper_case_globals)]
pub const Part1: u8 = 1;
#[allow(non_upper_case_globals)]
pub const Part2: u8 = 2;
/// Implement this trait with your solution to the Advent of Code problem for a particular day and part.
///
/// Remember: Day, then Part.
///
/// The compiler will complain about u32 (days) vs u8 (parts) if you mix this up.
pub trait Solution<'a, const DAY: u32, const PART: u8> {
type Input;
type Output: Debug;
fn solve(&'a self, input: &Self::Input) -> Self::Output;
}
/// Implement this trait to parse the raw input into a more useful type for your [`Solution`] to use as input.
///
/// See [`Solution::Input`]
pub trait ParseInput<'a, const DAY: u32, const PART: u8> {
type Parsed;
fn parse_input(&'a self, input: &'a str) -> Self::Parsed;
}
/// Import this trait to run your advent of code solutions once they implement [`Solution`].
///
/// This trait doesn't need to be implemented outside of this crate.
///
/// Blanket implementations are provided that specialize if your solutions share a parsed input type or if [`MissingPartTwo`] is implemented.
pub trait SolutionRunner<'a, const DAY: u32, const IMPL: u16> {
fn run(&'a self, input: &'a str);
}
/// The [`run`] macro expands
/// ```ignore
/// run!(AdventOfCode2021::<Day25>, &input);
/// ```
/// to
/// ```ignore
/// {
/// let problem = AdventOfCode2021::<Day25>;
/// (&&&problem).run(&input)
/// }
/// ```
/// and that's it!
///
/// What's with all the `&`s? It's autoderef specialization, see [`specialization`].
#[macro_export]
macro_rules! run {
($day: expr, $input: expr) => {{
let problem = $day;
(&&&problem).run($input)
}};
}
/// [`MissingPartTwo`] is a marker trait to tell the compiler that your struct doesn't impl Solution for Part2.
///
/// Implementing this is required in order to run only Part1 using [`SolutionRunner::run`] without specifying which SolutionRunner impl to use manually.
///
/// Why? It's to guide the specialization by ensuring that each impl is unique. See [`specialization`] for more details.
/// ```
/// # use advent_of_code_traits::{days::Day1, MissingPartTwo, ParseInput, Part1, Solution, SolutionRunner };
/// struct AdventOfCode2021<const DAY: u32>;
///
/// impl<'a> Solution<'a, Day1, Part1> for AdventOfCode2021<Day1> {
/// // your solution to part 1
/// # type Input = u32; type Output = u32;
/// # fn solve(&'a self, _input: &Self::Input) -> Self::Output { 1 }
/// }
/// # impl<'a> ParseInput<'a, Day1, Part1> for AdventOfCode2021::<Day1> {
/// # type Parsed = u32;
/// # fn parse_input(&'a self, input: &'a str) -> Self::Parsed { 1 }
/// # }
///
/// // add this to be able to .run() AdventOfCode2021::<Day25> without an implemention for Part2
/// impl MissingPartTwo<Day1> for AdventOfCode2021<Day1> {}
///
/// # let input: &'static str = "fake input";
/// # let problem = AdventOfCode2021::<Day1>;
/// // ...
/// problem.run(&input);
/// ```
pub trait MissingPartTwo<const DAY: u32> {}
pub mod specialization;