From 681c03ad89afd2134c450ecbc08414cde9a30baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sp=C3=B6ttel?= <1682504+fspoettel@users.noreply.github.com> Date: Wed, 29 Dec 2021 14:36:48 +0100 Subject: [PATCH] feat: use `cargo --bin` instead of solutions crate --- .gitignore | 4 +- Cargo.toml | 2 +- README.md | 44 ++++++------ scripts/download.sh | 14 ++-- scripts/scaffold.sh | 40 +++++------ src/{solutions => bin}/.keep | 0 src/{solutions/mod.rs => inputs/.keep} | 0 src/lib.rs | 36 ++++++++-- src/main.rs | 92 ++++++-------------------- 9 files changed, 100 insertions(+), 132 deletions(-) rename src/{solutions => bin}/.keep (100%) rename src/{solutions/mod.rs => inputs/.keep} (100%) diff --git a/.gitignore b/.gitignore index 81498f2..f2fd7aa 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,5 @@ target/ # Advent of Code # @see https://old.reddit.com/r/adventofcode/comments/k99rod/sharing_input_data_were_we_requested_not_to/gf2ukkf/?context=3 -inputs -!inputs/.keep +/src/inputs +!/src/inputs/.keep diff --git a/Cargo.toml b/Cargo.toml index b8cff29..00131b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "aoc" version = "0.1.0" authors = ["Felix SpΓΆttel <1682504+fspoettel@users.noreply.github.com>"] edition = "2021" - +default-run = "aoc" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [profile.release] diff --git a/README.md b/README.md index 6633ff7..00a1028 100644 --- a/README.md +++ b/README.md @@ -33,15 +33,14 @@ Generated with the [advent-of-code-rust](https://github.com/fspoettel/advent-of- ./scripts/scaffold.sh # output: -# Created module `src/solutions/day01.rs` -# Created input file `src/inputs/day01.txt` -# Created example file `src/examples/day01.txt` -# Linked new module in `src/main.rs` -# Linked new module in `src/solutions/mod.rs` -# Done! πŸŽ„ +# Created module "src/bin/01.rs" +# Created empty input file "src/inputs/01.txt" +# Created empty example file "src/examples/01.txt" +# --- +# πŸŽ„ Type `cargo run --bin 01` to run your solution. ``` -Every solution file has _unit tests_ referencing the example input file. You can use these tests to develop and debug your solution. When editing a solution file, `rust-analyzer` will display buttons for these actions above the unit tests. +Every solution has _unit tests_ referencing the _example_ file. Use these tests to develop and debug your solution. When editing a solution, `rust-analyzer` will display buttons for these actions above the unit tests. ### Download inputs for a day @@ -50,27 +49,26 @@ Every solution file has _unit tests_ referencing the example input file. You can ./scripts/download.sh # output: -# Invoking `aoc` cli... -# Loaded session cookie from "/home/foo/.adventofcode.session". +# Loaded session cookie from "/home/felix/.adventofcode.session". # Downloading input for day 1, 2021... -# Saving puzzle input to "/tmp/..."... +# Saving puzzle input to "/tmp/tmp.MBdcAdL9Iw/input"... # Done! -# Wrote input to `src/inputs/day01.txt`... -# Done! πŸŽ„ +# --- +# πŸŽ„ Successfully wrote input to "src/inputs/01.txt"! ``` Puzzle inputs are not checked into git. [See here](https://old.reddit.com/r/adventofcode/comments/k99rod/sharing_input_data_were_we_requested_not_to/gf2ukkf/?context=3) why. +> This script does not support downloading inputs for previous years. If you want to use this template for a previous aoc, [use the underlying `aoc-cli` binary directly](https://github.com/scarvalhojr/aoc-cli/#download-puzzle-input) or download your inputs manually. + ### Run solutions for a day ```sh -# example: `cargo run 1` -cargo run +# example: `cargo run --bin 01` +cargo run --bin # output: -# Running `target/debug/aoc 1` -# ---- -# +# Running `target/debug/01` # πŸŽ„ Part 1 πŸŽ„ # # 6 (elapsed: 37.03Β΅s) @@ -78,11 +76,17 @@ cargo run # πŸŽ„ Part 2 πŸŽ„ # # 9 (elapsed: 33.18Β΅s) -# -# ---- ``` -To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr `. +To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr --bin `. + +### Run all solutions + +```sh +cargo run +``` + +To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr`. ### Run all solutions against example input diff --git a/scripts/download.sh b/scripts/download.sh index 2860a0e..a3aefcd 100755 --- a/scripts/download.sh +++ b/scripts/download.sh @@ -16,7 +16,7 @@ fi day=$(echo $1 | sed 's/^0*//'); day_padded=`printf %02d $day`; -filename="day$day_padded"; +filename="$day_padded"; input_path="src/inputs/$filename.txt"; tmp_dir=$(mktemp -d); @@ -24,15 +24,9 @@ tmp_file_path="$tmp_dir/input"; aoc download --day $day --file $tmp_file_path; cat $tmp_file_path > $input_path; -echo "Wrote input to \"$input_path\"..."; - -cat < $module_path < u32 { 0 } @@ -27,6 +29,10 @@ pub fn part_two(input: &str) -> u32 { 0 } +fn main() { + solve_day!(&read_file("inputs", DAYNUM), part_one, part_two) +} + #[cfg(test)] mod tests { use super::*; @@ -34,43 +40,27 @@ mod tests { #[test] fn test_part_one() { use aoc::read_file; - let input = read_file("examples", day); + let input = read_file("examples", DAYNUM); assert_eq!(part_one(&input), 0); } #[test] fn test_part_two() { use aoc::read_file; - let input = read_file("examples", day); + let input = read_file("examples", DAYNUM); assert_eq!(part_two(&input), 0); } } EOF -perl -pi -e "s,day,$day,g" $module_path; +perl -pi -e "s,DAYNUM,$day,g" $module_path; echo "Created module \"$module_path\""; touch $input_path; -echo "Created input file \"$input_path\""; +echo "Created empty input file \"$input_path\""; touch $example_path; -echo "Created example file \"$example_path\""; - -line=" $day => solve_day!($filename, &input)," -perl -pi -le "print '$line' if(/^*.day not solved/);" "src/main.rs"; - -echo "Linked new module in \"src/main.rs\""; - -LINE="pub mod $filename;"; -FILE="src/solutions/mod.rs"; -grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE"; -echo "Linked new module in \"$FILE\""; - - -cat < {{ + use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET}; + use std::fmt::Display; + use std::time::Instant; + + fn print_result(func: impl FnOnce(&str) -> T, input: &str) { + let timer = Instant::now(); + let result = func(input); + let time = timer.elapsed(); + println!( + "{} {}(elapsed: {:.2?}){}", + result, ANSI_ITALIC, time, ANSI_RESET + ); + } + + println!("πŸŽ„ {}Part 1{} πŸŽ„", ANSI_BOLD, ANSI_RESET); + println!(""); + print_result($part_one, $input); + println!(""); + println!("πŸŽ„ {}Part 2{} πŸŽ„", ANSI_BOLD, ANSI_RESET); + println!(""); + print_result($part_two, $input); + }}; +} + pub fn read_file(folder: &str, day: u8) -> String { let cwd = env::current_dir().unwrap(); - let filepath = cwd - .join("src") - .join(folder) - .join(format!("day{:02}.txt", day)); + let filepath = cwd.join("src").join(folder).join(format!("{:02}.txt", day)); let f = fs::read_to_string(filepath); f.expect("could not open input file") diff --git a/src/main.rs b/src/main.rs index 1071164..fb92954 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,26 @@ -use crate::solutions::*; -use aoc::read_file; -use std::env; -use std::fmt::Display; -use std::time::Instant; - -mod helpers; -mod solutions; - -static ANSI_ITALIC: &str = "\x1b[3m"; -static ANSI_BOLD: &str = "\x1b[1m"; -static ANSI_RESET: &str = "\x1b[0m"; - -fn print_result(func: impl FnOnce(&str) -> T, input: &str) { - let timer = Instant::now(); - let result = func(input); - let time = timer.elapsed(); - println!( - "{} {}(elapsed: {:.2?}){}", - result, ANSI_ITALIC, time, ANSI_RESET - ); -} - -macro_rules! solve_day { - ($day:path, $input:expr) => {{ - use $day::*; - println!("----"); - println!(""); - println!("πŸŽ„ {}Part 1{} πŸŽ„", ANSI_BOLD, ANSI_RESET); - println!(""); - print_result(part_one, $input); - println!(""); - println!("πŸŽ„ {}Part 2{} πŸŽ„", ANSI_BOLD, ANSI_RESET); - println!(""); - print_result(part_two, $input); - println!(""); - println!("----"); - }}; -} +use aoc::{ANSI_BOLD, ANSI_RESET}; +use std::process::Command; fn main() { - let args: Vec = env::args().collect(); - let day: u8 = args[1].clone().parse().unwrap(); - let input = read_file("inputs", day); + (1..=25).for_each(|day| { + let day = format!("{:02}", day); - match day { - 1 => solve_day!(day01, &input), - 2 => solve_day!(day02, &input), - 3 => solve_day!(day03, &input), - 4 => solve_day!(day04, &input), - 5 => solve_day!(day05, &input), - 6 => solve_day!(day06, &input), - 7 => solve_day!(day07, &input), - 8 => solve_day!(day08, &input), - 9 => solve_day!(day09, &input), - 10 => solve_day!(day10, &input), - 11 => solve_day!(day11, &input), - 12 => solve_day!(day12, &input), - 13 => solve_day!(day13, &input), - 14 => solve_day!(day14, &input), - 15 => solve_day!(day15, &input), - 16 => solve_day!(day16, &input), - 17 => solve_day!(day17, &input), - 18 => solve_day!(day18, &input), - 19 => solve_day!(day19, &input), - 20 => solve_day!(day20, &input), - 21 => solve_day!(day21, &input), - 22 => solve_day!(day22, &input), - 23 => solve_day!(day23, &input), - 24 => solve_day!(day24, &input), - 25 => solve_day!(day25, &input), - _ => println!("day not solved: {}", day), - } + let cmd = Command::new("cargo") + .args(&["run", "--release", "--bin", &day]) + .output() + .unwrap(); + + let output = String::from_utf8(cmd.stdout).unwrap(); + println!("----------"); + println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET); + println!("----------"); + println!( + "{}", + if !output.is_empty() { + output + } else { + "Not solved.".to_string() + } + ); + }); }