diff --git a/.gitignore b/.gitignore new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,1 @@ +/target diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.showUnlinkedFileNotification": false +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "advent" +version = "0.1.0" +dependencies = [ + "core", + "macros", + "y_2023", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "core" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "macros" +version = "0.1.0" +dependencies = [ + "core", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "utils" +version = "0.1.0" + +[[package]] +name = "y_2023" +version = "0.1.0" +dependencies = [ + "core", + "macros", + "utils", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "advent" +version = "0.1.0" +edition = "2021" + +[workspace] + +members = [ + "core", + "macros", + "utils", + "years/*" +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +y_2023 = { path = "years/2023" } +core = { path = "core" } +macros = { path = "macros" } + +[[bin]] +name = "advent" +path = "src/main.rs" \ No newline at end of file diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "core" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +regex = "1.10.2" diff --git a/core/src/bootstrap.rs b/core/src/bootstrap.rs new file mode 100644 --- /dev/null +++ b/core/src/bootstrap.rs @@ -0,0 +1,166 @@ +use std::path::Path; + +use regex::Regex; + +use crate::MAX_DAY; + + +const DAY_TEMPLATE: &str = " +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day{day}; + +impl Day for Day{day} { + + day_stuff!({day}, \"\", \"\"); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} +"; + +const YEAR_TEMPLATE: &str = " +use macros::year; + +year!({year}); +"; + +const RUNNER_TEMPLATE: &str = " +use macros::year_runner; + +year_runner!({year}); +"; + +const CARGO_TEMPLATE: &str = " +[package] +name = \"y_{year}\" +version = \"0.1.0\" +edition = \"2021\" + +[dependencies] +core = { path = \"../../core\" } +macros = { path = \"../../macros\" } +utils = { path = \"../../utils\" } +"; + +fn make_day(folder: &Path, day: usize) { + let day = day.to_string(); + + let day_path = folder.join(format!("day_{}.rs", day)); + + let contents = DAY_TEMPLATE.replace("{day}", &day); + + std::fs::write(day_path, contents).unwrap(); +} + +fn make_example(folder: &Path, day: usize) { + let day = day.to_string(); + + let example_path = folder.join(format!("day_{}", day)); + + let part_1_path = example_path.join("1.txt"); + let part_2_path = example_path.join("2.txt"); + + std::fs::create_dir_all(&example_path).unwrap(); + std::fs::write(part_1_path, "").unwrap(); + std::fs::write(part_2_path, "").unwrap(); +} + +fn make_days(folder: &Path) { + for day in 1..=MAX_DAY { + make_day(folder, day); + } +} + +fn make_examples(folder: &Path) { + let examples_path = folder.join("examples"); + for day in 1..=MAX_DAY { + make_example(&examples_path, day); + } +} + +fn make_lib(folder: &Path, year: &str) { + let lib_path = folder.join("lib.rs"); + + let contents = YEAR_TEMPLATE.replace("{year}", &year); + + std::fs::write(lib_path, contents).unwrap(); +} + +fn make_main(folder: &Path, year: &str) { + let main_path = folder.join("main.rs"); + + let contents = RUNNER_TEMPLATE.replace("{year}", &year); + + std::fs::write(main_path, contents).unwrap(); +} + +fn make_src(folder: &Path, year: &str) { + let src_path = folder.join("src"); + + std::fs::create_dir_all(&src_path).unwrap(); + + make_days(&src_path); + make_examples(&src_path); + make_lib(&src_path, &year); + make_main(&src_path, &year); +} + +fn make_cargo(folder: &Path, year: &str) { + let cargo_path = folder.join("Cargo.toml"); + + let contents = CARGO_TEMPLATE.replace("{year}", &year); + + std::fs::write(cargo_path, contents).unwrap(); +} + +fn replace_year_list(new_year: &str ) { + let main = include_str!("../../src/main.rs"); + + let global_runner_pattern = Regex::new(r"global_runner!\(([\d,]+)\)").unwrap(); + + let matches = global_runner_pattern.captures(main).unwrap(); + + let full = matches.get(0).unwrap().as_str(); + + let mut years = matches.get(1).unwrap().as_str().split(",").map(|s| s.parse::().unwrap()).collect::>(); + + years.push(new_year.parse::().unwrap()); + + years.sort(); + + let new_years = years.iter().map(|y| y.to_string()).collect::>().join(","); + + let new_main = main.replace(full, &format!("global_runner!({})", new_years)); + + std::fs::write("src/main.rs", new_main).unwrap(); +} + +fn replace_cargo_dependencies(new_year: &str) { + let cargo = include_str!("../../Cargo.toml"); + + let new_dep = format!("y_{year} = {{ path = \"years/{year}\" }}", year = new_year); + + let cargo = cargo.replace("[dependencies]", &format!("[dependencies]\n{}", new_dep)); + + std::fs::write("Cargo.toml", cargo).unwrap(); +} + +pub fn make_year(year: &str) { + let cwd = std::env::current_dir().unwrap(); + + let year_path = cwd.join(format!("years/{}", year)); + + std::fs::create_dir_all(&year_path).unwrap(); + + make_src(&year_path, year); + make_cargo(&year_path, year); + + replace_cargo_dependencies(year); + replace_year_list(year); +} \ No newline at end of file diff --git a/core/src/day.rs b/core/src/day.rs new file mode 100644 --- /dev/null +++ b/core/src/day.rs @@ -0,0 +1,175 @@ +use std::time::Instant; + +#[macro_export] +macro_rules! ex_for_day { + ($day:literal, $part:literal) => { + include_str!(concat!("examples/day_", stringify!($day), "/", stringify!($part), ".txt")) + }; +} + +#[macro_export] +macro_rules! day_stuff { + ($day:literal, $e_1:literal, $e_2:literal) => { + day_stuff!($day, $e_1, $e_2, String); + + fn parse_input(input: &str) -> Self::Input { + input.to_string() + } + }; + + ($day:literal, $e_1:literal, $e_2:literal, $i: ty) => { + type Input = $i; + + const DAY: usize = $day; + const EXAMPLE_INPUT_1: &'static str = ex_for_day!($day, 1); + const EXAMPLE_INPUT_2: &'static str = ex_for_day!($day, 2); + const EXPECTED_1: &'static str = $e_1; + const EXPECTED_2: &'static str = $e_2; + } +} + +/// A trait for a day of Advent of Code. +/// +/// This trait is implemented for each day of Advent of Code. +/// You're expected to implement the `EXAMPLE_INPUT_1` and `EXAMPLE_INPUT_2` constants +/// with the example inputs for each part of the day. +/// +/// You're also expected to implement the `EXPECTED_1` and `EXPECTED_2` constants +/// with the expected outputs for each part of the day. +/// +/// Then, any runner can use `run_part` to run a part of the day with a given input or the example input. +/// +pub trait Day { + + type Input; + + const DAY: usize = 0; + + const EXAMPLE_INPUT_1: &'static str = ""; + const EXAMPLE_INPUT_2: &'static str = ""; + + const EXPECTED_1: &'static str = ""; + const EXPECTED_2: &'static str = ""; + + fn get_example_input(part: usize) -> &'static str { + match part { + 1 => Self::EXAMPLE_INPUT_1, + 2 => Self::EXAMPLE_INPUT_2, + _ => panic!("Invalid part number"), + } + } + + fn run_part(part: usize, input: Option<&str>) -> Option { + let input = input.unwrap_or_else(|| Self::get_example_input(part)); + let input = Self::parse_input(input); + let instant = Instant::now(); + let solution = match part { + 1 => Self::part_1(input), + 2 => Self::part_2(input), + _ => panic!("Invalid part number"), + }; + println!("Day {} Part {}: {} ({}ms)", Self::DAY, part, solution.as_ref().unwrap_or(&"Not implemented".to_string()), instant.elapsed().as_millis()); + solution + } + + fn run_all_parts(extra_indent: &str) { + println!("{extra_indent}Day {day}:", extra_indent = extra_indent, day = Self::DAY); + for part in 1..=2 { + let part_time = Instant::now(); + let solution = match part { + 1 => Self::part_1(Self::parse_input(Self::EXAMPLE_INPUT_1)), + 2 => Self::part_2(Self::parse_input(Self::EXAMPLE_INPUT_2)), + _ => panic!("Invalid part number"), + }; + println!("{extra_indent} Part {}: {} ({}ms)", part, solution.as_ref().unwrap_or(&"Not implemented".to_string()), part_time.elapsed().as_millis()); + } + } + + fn parse_input(input: &str) -> Self::Input; + + fn part_1(_input: Self::Input) -> Option { + None + } + fn part_2(_input: Self::Input) -> Option { + None + } + + fn assert_part_1() { + let expected = Self::EXPECTED_1; + let actual = Self::run_part(1, None); + if let Some(actual) = actual { + assert_eq!(actual, expected); + } + } + + fn assert_part_2() { + let expected = Self::EXPECTED_2; + let actual = Self::run_part(2, None); + if let Some(actual) = actual { + assert_eq!(actual, expected); + } + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + struct TestDay; + + impl Day for TestDay { + + type Input = String; + + const EXAMPLE_INPUT_1: &'static str = "Hello, world!"; + const EXAMPLE_INPUT_2: &'static str = "Hello, world!"; + + const EXPECTED_1: &'static str = "Goodbye, world!"; + const EXPECTED_2: &'static str = "Hello, moon!"; + + fn parse_input(input: &str) -> String { + input.to_string() + } + + fn part_1(input: String) -> Option { + Some(input.replace("Hello", "Goodbye")) + } + + fn part_2(input: String) -> Option { + Some(input.replace("world", "moon")) + } + } + + struct TestDay2; + + impl Day for TestDay2 { + + type Input = Vec; + + const EXAMPLE_INPUT_1: &'static str = "A\nB\nC"; + + const EXPECTED_1: &'static str = "A,B,C"; + + fn parse_input(input: &str) -> Vec { + input.lines().map(|l| l.to_string()).collect::>() + } + + fn part_1(input: Vec) -> Option { + Some(input.join(",").to_string()) + } + } + + #[test] + fn test_day_1() { + TestDay::assert_part_1(); + TestDay::assert_part_2(); + } + + #[test] + fn test_day_2() { + TestDay2::assert_part_1(); + // Should skip + TestDay2::assert_part_2(); + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs new file mode 100644 --- /dev/null +++ b/core/src/lib.rs @@ -0,0 +1,11 @@ +mod day; +mod year; +mod parser; +mod bootstrap; + +pub const MAX_DAY: usize = 25; + +pub use day::Day; +pub use year::Year; +pub use parser::{Selection, YDP, DP, get_dp_and_input, get_ydp_and_input}; +pub use bootstrap::make_year; diff --git a/core/src/parser.rs b/core/src/parser.rs new file mode 100644 --- /dev/null +++ b/core/src/parser.rs @@ -0,0 +1,120 @@ +use std::io::{stdin, Read}; +use std::env::args; +#[derive(Clone, Debug)] +pub enum Selection { + All, + Single(usize), // TODO: Add range maybe? +} + +impl Selection { + + fn parse(input: &str) -> Self { + if input == "*" { + Self::All + } else { + let input = input.parse::().unwrap(); + Self::Single(input) + } + } + +} + +#[derive(Clone, Debug)] +pub struct DP { + pub day: Selection, + pub part: Selection, +} + +const DP_ALL: DP = DP { + day: Selection::All, + part: Selection::All, +}; + +impl DP { + + fn parse(input: &str) -> Self { + let mut split = input.split(':'); + + let day = split.next().map(Selection::parse).unwrap_or(Selection::All); + let part = split.next().map(Selection::parse).unwrap_or(Selection::All); + + Self { + day, + part, + } + } + +} + +#[derive(Clone, Debug)] +pub struct YDP { + pub year: Selection, + pub day: Selection, + pub part: Selection, +} + +impl YDP { + + fn parse(input: &str) -> Self { + let mut split = input.split(':'); + + let year = split.next().map(Selection::parse).unwrap_or(Selection::All); + let day = split.next().map(Selection::parse).unwrap_or(Selection::All); + let part = split.next().map(Selection::parse).unwrap_or(Selection::All); + + Self { + year, + day, + part, + } + } + + pub fn to_dp(&self) -> DP { + DP { + day: self.day.clone(), + part: self.part.clone(), + } + } + +} + +pub fn get_dp_and_input() -> (DP, Option) { + let mut args = args().skip(1); + + let dp = args.next().map(|s| DP::parse(&s.trim())).unwrap_or(DP_ALL); + + let input = args.next().map(|s| s.trim().to_string()).map(|i| { + if i == "-" { + let mut input = String::new(); + stdin().read_to_string(&mut input).expect("Failed to read input"); + input.trim().to_string() + } else { + i + } + }); + + (dp, input) +} + +pub fn get_ydp_and_input(args: Vec) -> (YDP, Option) { + + let mut args = args.into_iter(); + + let ydp = args.next().map(|s| YDP::parse(&s.trim())).unwrap_or(YDP { + year: Selection::All, + day: Selection::All, + part: Selection::All, + }); + + let input = args.next().map(|s| s.trim().to_string()).map(|i| { + if i == "-" { + let mut input = String::new(); + stdin().read_to_string(&mut input).expect("Failed to read input"); + input.trim().to_string() + } else { + i + } + }); + + (ydp, input) +} \ No newline at end of file diff --git a/core/src/year.rs b/core/src/year.rs new file mode 100644 --- /dev/null +++ b/core/src/year.rs @@ -0,0 +1,36 @@ +use crate::parser::{DP, Selection}; + +use super::MAX_DAY; + +pub trait Year { + const YEAR: usize; + + fn solve_day(day: usize, part: usize, input: Option<&str>) -> Option; + + fn solve_day_both_parts(day: usize, extra_indent: &str); + + fn solve_all_days() { + println!("Year {}:", Self::YEAR); + for day in 1..=MAX_DAY { + Self::solve_day_both_parts(day, " "); + } + } + + fn run_dp(input: Option<&str>, dp: DP) { + match dp.day { + Selection::All => { + Self::solve_all_days(); + }, + Selection::Single(day) => { + match dp.part { + Selection::All => { + Self::solve_day_both_parts(day, ""); + }, + Selection::Single(part) => { + Self::solve_day(day, part, input); + }, + } + }, + } + } +} diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "macros" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +proc-macro = true + +[dependencies] +core = { path = "../core" } \ No newline at end of file diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,158 @@ +extern crate proc_macro; + +use core::MAX_DAY; + +use proc_macro::TokenStream; + +fn make_day_mods() -> String { + (1..=MAX_DAY).map(|day| format!("mod day_{day};", day = day)).collect::>().join("\n") +} + +fn make_use_days() -> String { + (1..=MAX_DAY).map(|day| format!("use day_{day}::Day{day};", day = day)).collect::>().join("\n") +} + +fn make_day_match(inner: &str) -> String { + (1..=MAX_DAY).map(|day| format!("{day} => {},", inner.replace("{day}", &day.to_string()))).collect::>().join("\n") +} + +fn make_day_tests() -> String { + (1..=MAX_DAY).map(|day| format!(" + #[test] + fn test_day_{day}_part_1() {{ + Day{day}::assert_part_1(); + }} + + #[test] + fn test_day_{day}_part_2() {{ + Day{day}::assert_part_2(); + }}")).collect::>().join("\n") +} + +fn get_solve_day() -> String { + let inner = make_day_match("Day{day}::run_part(part, input)"); + format!(" + fn solve_day(day: usize, part: usize, input: Option<&str>) -> Option {{ + match day {{ + {inner} + _ => None, + }} + }}", inner = inner) +} + +fn get_solve_day_both_parts() -> String { + let inner = make_day_match("Day{day}::run_all_parts(extra_indent)"); + format!(" + fn solve_day_both_parts(day: usize, extra_indent: &str) {{ + match day {{ + {inner} + _ => (), + }} + }}", inner = inner) +} + +fn make_year_struct(year: &str) -> String { + format!(" + pub struct Year{year}; + + impl Year for Year{year} {{ + const YEAR: usize = {year}; + + {solve_day} + + {solve_day_both_parts} + }}", solve_day = get_solve_day(), solve_day_both_parts = get_solve_day_both_parts()) +} + +fn make_tests() -> String { + format!(" + #[cfg(test)] + mod tests {{ + use super::*; + use core::{{Day, Year}}; + + {day_tests} + }}", day_tests = make_day_tests()) +} + +#[proc_macro] +pub fn year(item: TokenStream) -> TokenStream { + let year = item.to_string(); + + let mods = make_day_mods(); + let uses = make_use_days(); + + let year_struct = make_year_struct(&year); + + let tests = make_tests(); + + format!(" + {mods} + + use core::{{Year, Day}}; + {uses} + + {year_struct} + + {tests} + ").parse::().unwrap() +} + +#[proc_macro] +pub fn year_runner(item: TokenStream) -> TokenStream { + let year = item.to_string(); + + format!(" + use core::{{Year, get_dp_and_input}}; + + use y_{year}::Year{year}; + + fn main() {{ + let (dp, input) = get_dp_and_input(); + Year{year}::run_dp(input.as_deref(), dp); + }}").parse::().unwrap() +} + +fn make_year_match(years: &Vec<&str>, inner: &str) -> String { + years.iter().map(|year| format!("{year} => {},", inner.replace("{year}", &year.to_string()))).collect::>().join("\n") +} + +fn make_year_uses(years: &Vec<&str>) -> String { + years.iter().map(|year| format!("use y_{year}::Year{year};", year = year)).collect::>().join("\n") +} + +fn make_run_all_years(years: &Vec<&str>) -> String { + years.iter().map(|year| format!("Year{year}::run_dp(input.as_deref(), dp.clone());", year = year)).collect::>().join("\n") +} + +fn make_run_year(years: &Vec<&str>) -> String { + let inner = make_year_match(years, "Year{year}::run_dp(input.as_deref(), dp)"); + format!(" + fn run_year(year: usize, dp: DP, input: Option<&str>) {{ + match year {{ + {inner} + _ => {{ + println!(\"Unknown year: {{year}}\"); + }} + }} + }}", inner = inner) +} + +#[proc_macro] +pub fn global_runner(item: TokenStream) -> TokenStream { + let item = item.to_string(); + let years = item.split(',').map(|s| s.trim()).collect::>(); + + let year_uses = make_year_uses(&years); + let run_all_years = make_run_all_years(&years); + let run_year = make_run_year(&years); + + format!(" + {year_uses} + + {run_year} + + fn run_all_years(dp: &DP, input: Option) {{ + {run_all_years} + }}").parse::().unwrap() +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,46 @@ +use core::{get_ydp_and_input, make_year, Year, Selection, YDP, DP}; +use macros::global_runner; + +global_runner!(2023); + +fn run_ydp(ydp: YDP, input: Option) { + let dp = ydp.to_dp(); + + match ydp.year { + Selection::All => { + run_all_years(&dp, input); + }, + Selection::Single(year) => { + run_year(year, dp, input.as_deref()); + }, + } +} + +fn main() { + let args = std::env::args().skip(1).collect::>(); + + let command = args.get(0); + + match command { + Some(command) => { + match command.as_str() { + "new" => { + let year = args.get(1).expect("No year provided"); + make_year(year); + }, + "solve" | "run" => { + let (ydp, input) = get_ydp_and_input(args[1..].to_vec()); + run_ydp(ydp, input); + } + _ => { + println!("Unknown command: {}", command); + println!("Available commands: new, solve"); + } + } + }, + None => { + println!("No command provided"); + println!("Available commands: new, solve"); + } + } +} diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "utils" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/years/2023/Cargo.toml b/years/2023/Cargo.toml new file mode 100644 --- /dev/null +++ b/years/2023/Cargo.toml @@ -0,0 +1,10 @@ + +[package] +name = "y_2023" +version = "0.1.0" +edition = "2021" + +[dependencies] +core = { path = "../../core" } +macros = { path = "../../macros" } +utils = { path = "../../utils" } diff --git a/years/2023/src/day_1.rs b/years/2023/src/day_1.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_1.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day1; + +impl Day for Day1 { + + day_stuff!(1, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_10.rs b/years/2023/src/day_10.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_10.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day10; + +impl Day for Day10 { + + day_stuff!(10, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_11.rs b/years/2023/src/day_11.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_11.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day11; + +impl Day for Day11 { + + day_stuff!(11, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_12.rs b/years/2023/src/day_12.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_12.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day12; + +impl Day for Day12 { + + day_stuff!(12, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_13.rs b/years/2023/src/day_13.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_13.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day13; + +impl Day for Day13 { + + day_stuff!(13, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_14.rs b/years/2023/src/day_14.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_14.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day14; + +impl Day for Day14 { + + day_stuff!(14, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_15.rs b/years/2023/src/day_15.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_15.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day15; + +impl Day for Day15 { + + day_stuff!(15, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_16.rs b/years/2023/src/day_16.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_16.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day16; + +impl Day for Day16 { + + day_stuff!(16, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_17.rs b/years/2023/src/day_17.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_17.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day17; + +impl Day for Day17 { + + day_stuff!(17, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_18.rs b/years/2023/src/day_18.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_18.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day18; + +impl Day for Day18 { + + day_stuff!(18, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_19.rs b/years/2023/src/day_19.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_19.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day19; + +impl Day for Day19 { + + day_stuff!(19, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_2.rs b/years/2023/src/day_2.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_2.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day2; + +impl Day for Day2 { + + day_stuff!(2, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_20.rs b/years/2023/src/day_20.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_20.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day20; + +impl Day for Day20 { + + day_stuff!(20, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_21.rs b/years/2023/src/day_21.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_21.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day21; + +impl Day for Day21 { + + day_stuff!(21, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_22.rs b/years/2023/src/day_22.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_22.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day22; + +impl Day for Day22 { + + day_stuff!(22, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_23.rs b/years/2023/src/day_23.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_23.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day23; + +impl Day for Day23 { + + day_stuff!(23, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_24.rs b/years/2023/src/day_24.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_24.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day24; + +impl Day for Day24 { + + day_stuff!(24, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_25.rs b/years/2023/src/day_25.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_25.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day25; + +impl Day for Day25 { + + day_stuff!(25, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_3.rs b/years/2023/src/day_3.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_3.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day3; + +impl Day for Day3 { + + day_stuff!(3, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_4.rs b/years/2023/src/day_4.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_4.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day4; + +impl Day for Day4 { + + day_stuff!(4, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_5.rs b/years/2023/src/day_5.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_5.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day5; + +impl Day for Day5 { + + day_stuff!(5, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_6.rs b/years/2023/src/day_6.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_6.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day6; + +impl Day for Day6 { + + day_stuff!(6, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_7.rs b/years/2023/src/day_7.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_7.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day7; + +impl Day for Day7 { + + day_stuff!(7, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_8.rs b/years/2023/src/day_8.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_8.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day8; + +impl Day for Day8 { + + day_stuff!(8, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/day_9.rs b/years/2023/src/day_9.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/day_9.rs @@ -0,0 +1,17 @@ + +use core::{Day, day_stuff, ex_for_day}; + +pub struct Day9; + +impl Day for Day9 { + + day_stuff!(9, "", ""); + + fn part_1(_input: Self::Input) -> Option { + None + } + + fn part_2(_input: Self::Input) -> Option { + None + } +} diff --git a/years/2023/src/examples/day_1/1.txt b/years/2023/src/examples/day_1/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_1/1.txt diff --git a/years/2023/src/examples/day_1/2.txt b/years/2023/src/examples/day_1/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_1/2.txt diff --git a/years/2023/src/examples/day_10/1.txt b/years/2023/src/examples/day_10/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_10/1.txt diff --git a/years/2023/src/examples/day_10/2.txt b/years/2023/src/examples/day_10/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_10/2.txt diff --git a/years/2023/src/examples/day_11/1.txt b/years/2023/src/examples/day_11/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_11/1.txt diff --git a/years/2023/src/examples/day_11/2.txt b/years/2023/src/examples/day_11/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_11/2.txt diff --git a/years/2023/src/examples/day_12/1.txt b/years/2023/src/examples/day_12/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_12/1.txt diff --git a/years/2023/src/examples/day_12/2.txt b/years/2023/src/examples/day_12/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_12/2.txt diff --git a/years/2023/src/examples/day_13/1.txt b/years/2023/src/examples/day_13/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_13/1.txt diff --git a/years/2023/src/examples/day_13/2.txt b/years/2023/src/examples/day_13/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_13/2.txt diff --git a/years/2023/src/examples/day_14/1.txt b/years/2023/src/examples/day_14/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_14/1.txt diff --git a/years/2023/src/examples/day_14/2.txt b/years/2023/src/examples/day_14/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_14/2.txt diff --git a/years/2023/src/examples/day_15/1.txt b/years/2023/src/examples/day_15/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_15/1.txt diff --git a/years/2023/src/examples/day_15/2.txt b/years/2023/src/examples/day_15/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_15/2.txt diff --git a/years/2023/src/examples/day_16/1.txt b/years/2023/src/examples/day_16/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_16/1.txt diff --git a/years/2023/src/examples/day_16/2.txt b/years/2023/src/examples/day_16/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_16/2.txt diff --git a/years/2023/src/examples/day_17/1.txt b/years/2023/src/examples/day_17/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_17/1.txt diff --git a/years/2023/src/examples/day_17/2.txt b/years/2023/src/examples/day_17/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_17/2.txt diff --git a/years/2023/src/examples/day_18/1.txt b/years/2023/src/examples/day_18/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_18/1.txt diff --git a/years/2023/src/examples/day_18/2.txt b/years/2023/src/examples/day_18/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_18/2.txt diff --git a/years/2023/src/examples/day_19/1.txt b/years/2023/src/examples/day_19/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_19/1.txt diff --git a/years/2023/src/examples/day_19/2.txt b/years/2023/src/examples/day_19/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_19/2.txt diff --git a/years/2023/src/examples/day_2/1.txt b/years/2023/src/examples/day_2/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_2/1.txt diff --git a/years/2023/src/examples/day_2/2.txt b/years/2023/src/examples/day_2/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_2/2.txt diff --git a/years/2023/src/examples/day_20/1.txt b/years/2023/src/examples/day_20/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_20/1.txt diff --git a/years/2023/src/examples/day_20/2.txt b/years/2023/src/examples/day_20/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_20/2.txt diff --git a/years/2023/src/examples/day_21/1.txt b/years/2023/src/examples/day_21/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_21/1.txt diff --git a/years/2023/src/examples/day_21/2.txt b/years/2023/src/examples/day_21/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_21/2.txt diff --git a/years/2023/src/examples/day_22/1.txt b/years/2023/src/examples/day_22/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_22/1.txt diff --git a/years/2023/src/examples/day_22/2.txt b/years/2023/src/examples/day_22/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_22/2.txt diff --git a/years/2023/src/examples/day_23/1.txt b/years/2023/src/examples/day_23/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_23/1.txt diff --git a/years/2023/src/examples/day_23/2.txt b/years/2023/src/examples/day_23/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_23/2.txt diff --git a/years/2023/src/examples/day_24/1.txt b/years/2023/src/examples/day_24/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_24/1.txt diff --git a/years/2023/src/examples/day_24/2.txt b/years/2023/src/examples/day_24/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_24/2.txt diff --git a/years/2023/src/examples/day_25/1.txt b/years/2023/src/examples/day_25/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_25/1.txt diff --git a/years/2023/src/examples/day_25/2.txt b/years/2023/src/examples/day_25/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_25/2.txt diff --git a/years/2023/src/examples/day_3/1.txt b/years/2023/src/examples/day_3/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_3/1.txt diff --git a/years/2023/src/examples/day_3/2.txt b/years/2023/src/examples/day_3/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_3/2.txt diff --git a/years/2023/src/examples/day_4/1.txt b/years/2023/src/examples/day_4/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_4/1.txt diff --git a/years/2023/src/examples/day_4/2.txt b/years/2023/src/examples/day_4/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_4/2.txt diff --git a/years/2023/src/examples/day_5/1.txt b/years/2023/src/examples/day_5/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_5/1.txt diff --git a/years/2023/src/examples/day_5/2.txt b/years/2023/src/examples/day_5/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_5/2.txt diff --git a/years/2023/src/examples/day_6/1.txt b/years/2023/src/examples/day_6/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_6/1.txt diff --git a/years/2023/src/examples/day_6/2.txt b/years/2023/src/examples/day_6/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_6/2.txt diff --git a/years/2023/src/examples/day_7/1.txt b/years/2023/src/examples/day_7/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_7/1.txt diff --git a/years/2023/src/examples/day_7/2.txt b/years/2023/src/examples/day_7/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_7/2.txt diff --git a/years/2023/src/examples/day_8/1.txt b/years/2023/src/examples/day_8/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_8/1.txt diff --git a/years/2023/src/examples/day_8/2.txt b/years/2023/src/examples/day_8/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_8/2.txt diff --git a/years/2023/src/examples/day_9/1.txt b/years/2023/src/examples/day_9/1.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_9/1.txt diff --git a/years/2023/src/examples/day_9/2.txt b/years/2023/src/examples/day_9/2.txt new file mode 100644 --- /dev/null +++ b/years/2023/src/examples/day_9/2.txt diff --git a/years/2023/src/lib.rs b/years/2023/src/lib.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/lib.rs @@ -0,0 +1,4 @@ + +use macros::year; + +year!(2023); diff --git a/years/2023/src/main.rs b/years/2023/src/main.rs new file mode 100644 --- /dev/null +++ b/years/2023/src/main.rs @@ -0,0 +1,4 @@ + +use macros::year_runner; + +year_runner!(2023);