diff --git a/Cargo.lock b/Cargo.lock index bea35fd..145033c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,20 +11,145 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "aoc2024" version = "0.1.0" dependencies = [ + "ansi_term", + "clap", + "paste", "regex", "thiserror", ] +[[package]] +name = "clap" +version = "4.5.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "proc-macro2" version = "1.0.92" @@ -72,6 +197,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.90" @@ -108,3 +239,104 @@ name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 11a74ee..7d46e65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,8 @@ version = "0.1.0" [dependencies] + ansi_term = "0.12" + clap = { version = "4", features = ["derive"] } + paste = "1" regex = "1" thiserror = "2" diff --git a/src/lib.rs b/src/lib.rs index d952180..6184274 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ +pub mod cli; pub mod solutions; pub mod utils; diff --git a/src/main.rs b/src/main.rs index 3fd55f4..d12a638 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,36 @@ -use aoc2024::solutions::{day_5::AocDayFiveSolution, AocSolution}; +use ansi_term::enable_ansi_support; +use aoc2024::{ + cli::AocCli, + map_solution, + solutions::{ + AocDayFiveSolution, AocDayFourSolution, AocDayOneSolution, AocDayThreeSolution, + AocDayTwoSolution, AocSolution, + }, + utils::{Error, Result}, +}; +use clap::Parser; -fn main() { - let sol = AocDayFiveSolution; +fn main() -> Result<()> { + if let Err(e) = enable_ansi_support() { + println!("{e}"); + } - println!("p1: {}\np2: {}", sol.part_one(), sol.part_two()) + let cli = match AocCli::try_parse() { + Ok(cli) => cli, + Err(e) => { + println!("{}", e.render().ansi()); + return Ok(()); + } + }; + + println!("Solution for Day {}:", cli.day); + map_solution! {cli : + 1 => AocDayOneSolution, + 2 => AocDayTwoSolution, + 3 => AocDayThreeSolution, + 4 => AocDayFourSolution, + 5 => AocDayFiveSolution, + }; + + Ok(()) } diff --git a/src/solutions/day_1.rs b/src/solutions/day_1.rs index bd16b0d..8cd2e83 100644 --- a/src/solutions/day_1.rs +++ b/src/solutions/day_1.rs @@ -1,16 +1,23 @@ -use std::collections::HashMap; +use std::{collections::HashMap, fs::read_to_string, path::Path}; use super::AocSolution; +use crate::utils::Result; #[derive(Clone, Copy)] pub struct AocDayOneSolution; impl AocSolution for AocDayOneSolution { type Output = u64; - const INPUT: &str = include_str!("../../input/day1.txt"); - fn part_one(&self) -> Self::Output { - let (mut left, mut right) = Self::INPUT + fn get_input(&self, path: Option<&Path>) -> Result { + Ok(match path { + Some(p) => read_to_string(p)?, + None => read_to_string("./input/day_1.txt")?, + }) + } + + fn part_one(&self, input: &str) -> Result { + let (mut left, mut right) = input .lines() .filter_map(|s| s.split_once(' ').map(|(s, x)| (s.trim(), x.trim()))) .filter_map( @@ -28,16 +35,18 @@ impl AocSolution for AocDayOneSolution { left.sort(); right.sort(); - left.into_iter() + Ok(left + .into_iter() .zip(right) .map(|(l, r)| if l > r { l - r } else { r - l }) - .sum() + .sum()) } - fn part_two(&self) -> Self::Output { + + fn part_two(&self, input: &str) -> Result { let mut cache = HashMap::::new(); let mut similarity_score = 0; - let (left, right) = Self::INPUT + let (left, right) = input .lines() .filter_map(|s| s.split_once(' ').map(|(s, x)| (s.trim(), x.trim()))) .filter_map( @@ -62,6 +71,6 @@ impl AocSolution for AocDayOneSolution { } } - similarity_score + Ok(similarity_score) } } diff --git a/src/solutions/day_10.rs b/src/solutions/day_10.rs index e69de29..d1acc1a 100644 --- a/src/solutions/day_10.rs +++ b/src/solutions/day_10.rs @@ -0,0 +1 @@ +pub struct AocDayTenSolution; diff --git a/src/solutions/day_11.rs b/src/solutions/day_11.rs index e69de29..8b44a6c 100644 --- a/src/solutions/day_11.rs +++ b/src/solutions/day_11.rs @@ -0,0 +1 @@ +pub struct AocDayElevenSolution; diff --git a/src/solutions/day_12.rs b/src/solutions/day_12.rs index e69de29..872e4dd 100644 --- a/src/solutions/day_12.rs +++ b/src/solutions/day_12.rs @@ -0,0 +1 @@ +pub struct AocDayTwelveSolution; diff --git a/src/solutions/day_13.rs b/src/solutions/day_13.rs index e69de29..9f350d3 100644 --- a/src/solutions/day_13.rs +++ b/src/solutions/day_13.rs @@ -0,0 +1 @@ +pub struct AocDayThirteenSolution; diff --git a/src/solutions/day_14.rs b/src/solutions/day_14.rs index e69de29..36c7134 100644 --- a/src/solutions/day_14.rs +++ b/src/solutions/day_14.rs @@ -0,0 +1 @@ +pub struct AocDayFourteenSolution; diff --git a/src/solutions/day_15.rs b/src/solutions/day_15.rs index e69de29..487f2f6 100644 --- a/src/solutions/day_15.rs +++ b/src/solutions/day_15.rs @@ -0,0 +1 @@ +pub struct AocDayFifteenSolution; diff --git a/src/solutions/day_16.rs b/src/solutions/day_16.rs index e69de29..d3b8926 100644 --- a/src/solutions/day_16.rs +++ b/src/solutions/day_16.rs @@ -0,0 +1 @@ +pub struct AocDaySixteenSolution; diff --git a/src/solutions/day_17.rs b/src/solutions/day_17.rs index e69de29..ec16b6e 100644 --- a/src/solutions/day_17.rs +++ b/src/solutions/day_17.rs @@ -0,0 +1 @@ +pub struct AocDaySeventeenSolution; diff --git a/src/solutions/day_18.rs b/src/solutions/day_18.rs index e69de29..a2a725f 100644 --- a/src/solutions/day_18.rs +++ b/src/solutions/day_18.rs @@ -0,0 +1 @@ +pub struct AocDayEighteenSolution; diff --git a/src/solutions/day_19.rs b/src/solutions/day_19.rs index e69de29..63edac4 100644 --- a/src/solutions/day_19.rs +++ b/src/solutions/day_19.rs @@ -0,0 +1 @@ +pub struct AocDayNineteenSolution; diff --git a/src/solutions/day_2.rs b/src/solutions/day_2.rs index 1c0cb56..dd0e120 100644 --- a/src/solutions/day_2.rs +++ b/src/solutions/day_2.rs @@ -1,4 +1,7 @@ +use std::{fs::read_to_string, path::Path}; + use super::AocSolution; +use crate::utils::Result; fn is_safe(levels: &[i32]) -> bool { let dec = levels[0] > levels[1]; @@ -32,10 +35,16 @@ pub struct AocDayTwoSolution; impl AocSolution for AocDayTwoSolution { type Output = u64; - const INPUT: &str = include_str!("../../input/day2.txt"); - fn part_one(&self) -> Self::Output { - Self::INPUT + fn get_input(&self, path: Option<&Path>) -> Result { + Ok(match path { + Some(p) => read_to_string(p)?, + None => read_to_string("./input/day_2.txt")?, + }) + } + + fn part_one(&self, input: &str) -> Result { + Ok(input .lines() .map(|n| { n.split_whitespace() @@ -43,11 +52,11 @@ impl AocSolution for AocDayTwoSolution { .collect::>() }) .filter(|s| is_safe(s)) - .count() as u64 + .count() as u64) } - fn part_two(&self) -> Self::Output { - Self::INPUT + fn part_two(&self, input: &str) -> Result { + Ok(input .lines() .map(|n| { n.split_whitespace() @@ -55,6 +64,6 @@ impl AocSolution for AocDayTwoSolution { .collect::>() }) .filter(|s| is_safe(s) || is_safe_with_rem(s)) - .count() as u64 + .count() as u64) } } diff --git a/src/solutions/day_20.rs b/src/solutions/day_20.rs index e69de29..f97104c 100644 --- a/src/solutions/day_20.rs +++ b/src/solutions/day_20.rs @@ -0,0 +1 @@ +pub struct AocDayTwentySolution; diff --git a/src/solutions/day_21.rs b/src/solutions/day_21.rs index e69de29..ac8b628 100644 --- a/src/solutions/day_21.rs +++ b/src/solutions/day_21.rs @@ -0,0 +1 @@ +pub struct AocDayTwentyOneSolution; diff --git a/src/solutions/day_22.rs b/src/solutions/day_22.rs index e69de29..c60c8ca 100644 --- a/src/solutions/day_22.rs +++ b/src/solutions/day_22.rs @@ -0,0 +1 @@ +pub struct AocDayTwentyTwoSolution; diff --git a/src/solutions/day_23.rs b/src/solutions/day_23.rs index e69de29..168aebf 100644 --- a/src/solutions/day_23.rs +++ b/src/solutions/day_23.rs @@ -0,0 +1 @@ +pub struct AocDayTwentyThreeSolution; diff --git a/src/solutions/day_24.rs b/src/solutions/day_24.rs index e69de29..ec40882 100644 --- a/src/solutions/day_24.rs +++ b/src/solutions/day_24.rs @@ -0,0 +1 @@ +pub struct AocDayTwentyFourSolution; diff --git a/src/solutions/day_25.rs b/src/solutions/day_25.rs index e69de29..435ec37 100644 --- a/src/solutions/day_25.rs +++ b/src/solutions/day_25.rs @@ -0,0 +1 @@ +pub struct AocDayTwentyFiveSolution; diff --git a/src/solutions/day_3.rs b/src/solutions/day_3.rs index 96659cc..c87c8a9 100644 --- a/src/solutions/day_3.rs +++ b/src/solutions/day_3.rs @@ -1,8 +1,9 @@ -use std::sync::LazyLock; +use std::{fs::read_to_string, path::Path, sync::LazyLock}; use regex::Regex; use super::AocSolution; +use crate::utils::Result; static MUL: LazyLock = LazyLock::new(|| Regex::new(r"mul\([0-9]{1,3},[0-9]{1,3}\)").unwrap()); @@ -24,18 +25,21 @@ pub struct AocDayThreeSolution; impl AocSolution for AocDayThreeSolution { type Output = u64; - const INPUT: &str = include_str!("../../input/day3.txt"); - fn part_one(&self) -> Self::Output { - MUL.find_iter(Self::INPUT) - .map(|x| x.as_str()) - .map(as_mul) - .sum() + fn get_input(&self, path: Option<&Path>) -> Result { + Ok(match path { + Some(p) => read_to_string(p)?, + None => read_to_string("./input/day_3.txt")?, + }) } - fn part_two(&self) -> Self::Output { - COND_MUL - .find_iter(Self::INPUT) + fn part_one(&self, input: &str) -> Result { + Ok(MUL.find_iter(input).map(|x| x.as_str()).map(as_mul).sum()) + } + + fn part_two(&self, input: &str) -> Result { + Ok(COND_MUL + .find_iter(input) .map(|x| x.as_str()) .fold((0, true), |(sum, flag), cut| { if cut.starts_with("mul") && flag { @@ -46,6 +50,6 @@ impl AocSolution for AocDayThreeSolution { (sum, false) } }) - .0 + .0) } } diff --git a/src/solutions/day_4.rs b/src/solutions/day_4.rs index 44a4f86..4aef4f2 100644 --- a/src/solutions/day_4.rs +++ b/src/solutions/day_4.rs @@ -1,6 +1,7 @@ -use std::collections::HashMap; +use std::{collections::HashMap, fs::read_to_string, path::Path}; use super::AocSolution; +use crate::utils::Result; const DIRS: [(i16, i16); 8] = [ (1, 0), @@ -73,11 +74,17 @@ impl XmasGrid { pub struct AocDayFourSolution; impl AocSolution for AocDayFourSolution { - type Output = usize; - const INPUT: &str = include_str!("../../input/day4.txt"); + type Output = u64; - fn part_one(&self) -> Self::Output { - let xmas = XmasGrid::new(Self::INPUT); + fn get_input(&self, path: Option<&Path>) -> Result { + Ok(match path { + Some(p) => read_to_string(p)?, + None => read_to_string("./input/day_4.txt")?, + }) + } + + fn part_one(&self, input: &str) -> Result { + let xmas = XmasGrid::new(input); let mut tmp = 0; xmas.grid @@ -87,11 +94,11 @@ impl AocSolution for AocDayFourSolution { tmp += xmas.find_xmas(pt); }); - tmp as Self::Output + Ok(tmp as Self::Output) } - fn part_two(&self) -> Self::Output { - let xmas = XmasGrid::new(Self::INPUT); + fn part_two(&self, input: &str) -> Result { + let xmas = XmasGrid::new(input); let mut tmp = 0; xmas.grid @@ -101,6 +108,6 @@ impl AocSolution for AocDayFourSolution { tmp += xmas.find_x_mas(pt); }); - tmp as Self::Output + Ok(tmp as Self::Output) } } diff --git a/src/solutions/day_5.rs b/src/solutions/day_5.rs index 8315e0d..f139b10 100644 --- a/src/solutions/day_5.rs +++ b/src/solutions/day_5.rs @@ -1,6 +1,7 @@ -use std::{cmp::Ordering, collections::HashMap}; +use std::{cmp::Ordering, collections::HashMap, fs::read_to_string, path::Path}; use super::AocSolution; +use crate::utils::{Error, Result}; #[derive(Debug)] struct RuleChecker { @@ -76,17 +77,23 @@ pub struct AocDayFiveSolution; impl AocSolution for AocDayFiveSolution { type Output = u64; - const INPUT: &str = include_str!("../../input/day5.txt"); - fn part_one(&self) -> Self::Output { - let (rules, prints) = Self::INPUT.split_once("\r\n\r\n").unwrap_or(("", "")); - let checker = RuleChecker::new(rules, prints); - checker.compute_validated_print() + fn get_input(&self, path: Option<&Path>) -> Result { + Ok(match path { + Some(p) => read_to_string(p)?, + None => read_to_string("./input/day_5.txt")?, + }) } - fn part_two(&self) -> Self::Output { - let (rules, prints) = Self::INPUT.split_once("\r\n\r\n").unwrap_or(("", "")); + fn part_one(&self, input: &str) -> Result { + let (rules, prints) = input.split_once("\r\n\r\n").ok_or(Error::InvalidInput)?; + let checker = RuleChecker::new(rules, prints); + Ok(checker.compute_validated_print()) + } + + fn part_two(&self, input: &str) -> Result { + let (rules, prints) = input.split_once("\r\n\r\n").ok_or(Error::InvalidInput)?; let mut checker = RuleChecker::new(rules, prints); - checker.compute_invalid_print() + Ok(checker.compute_invalid_print()) } } diff --git a/src/solutions/day_6.rs b/src/solutions/day_6.rs index e69de29..414b007 100644 --- a/src/solutions/day_6.rs +++ b/src/solutions/day_6.rs @@ -0,0 +1 @@ +pub struct AocDaySixSolution; diff --git a/src/solutions/day_7.rs b/src/solutions/day_7.rs index e69de29..0d46306 100644 --- a/src/solutions/day_7.rs +++ b/src/solutions/day_7.rs @@ -0,0 +1 @@ +pub struct AocDaySevenSolution; diff --git a/src/solutions/day_8.rs b/src/solutions/day_8.rs index e69de29..a6a1c83 100644 --- a/src/solutions/day_8.rs +++ b/src/solutions/day_8.rs @@ -0,0 +1 @@ +pub struct AocDayEightSolution; diff --git a/src/solutions/day_9.rs b/src/solutions/day_9.rs index e69de29..526ebc6 100644 --- a/src/solutions/day_9.rs +++ b/src/solutions/day_9.rs @@ -0,0 +1 @@ +pub struct AocDayNineSolution; diff --git a/src/solutions/mod.rs b/src/solutions/mod.rs index ce13b4e..b97d678 100644 --- a/src/solutions/mod.rs +++ b/src/solutions/mod.rs @@ -1,6 +1,10 @@ +use std::path::Path; + +use crate::utils::Result; + macro_rules! define_solution { ($($id:ident),+ $(,)?) => { - $(pub mod $id;)+ + $(mod $id; pub use $id::*;)+ }; } @@ -11,8 +15,8 @@ define_solution!( pub trait AocSolution { type Output; - const INPUT: &str; - fn part_one(&self) -> Self::Output; - fn part_two(&self) -> Self::Output; + fn get_input(&self, path: Option<&Path>) -> Result; + fn part_one(&self, input: &str) -> Result; + fn part_two(&self, input: &str) -> Result; } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 8b13789..eaa9bcf 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,16 @@ +#[macro_use] +pub mod macros; +pub type Result = std::result::Result; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("IO error: {0}")] + Io(#[from] std::io::Error), + #[error("Invalid command usage: {0}")] + ClapError(#[from] clap::Error), + #[error("Invalid input.")] + InvalidInput, + #[error("Unsupported day.")] + UnsupportedDay, +}