feat: use cargo --bin
instead of solutions crate
This commit is contained in:
parent
4449f5bc94
commit
681c03ad89
9 changed files with 100 additions and 132 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
44
README.md
44
README.md
|
@ -33,15 +33,14 @@ Generated with the [advent-of-code-rust](https://github.com/fspoettel/advent-of-
|
|||
./scripts/scaffold.sh <day>
|
||||
|
||||
# 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 <day>
|
||||
|
||||
# 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 <day>
|
||||
# example: `cargo run --bin 01`
|
||||
cargo run --bin <day>
|
||||
|
||||
# output:
|
||||
# Running `target/debug/aoc 1`
|
||||
# ----
|
||||
#
|
||||
# Running `target/debug/01`
|
||||
# 🎄 Part 1 🎄
|
||||
#
|
||||
# 6 (elapsed: 37.03µs)
|
||||
|
@ -78,11 +76,17 @@ cargo run <day>
|
|||
# 🎄 Part 2 🎄
|
||||
#
|
||||
# 9 (elapsed: 33.18µs)
|
||||
#
|
||||
# ----
|
||||
```
|
||||
|
||||
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr <day>`.
|
||||
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr --bin <day>`.
|
||||
|
||||
### 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
|
||||
|
||||
|
|
|
@ -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,14 +24,8 @@ 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 <<EOF
|
||||
_==_ _
|
||||
_,(",)|_|
|
||||
\/. \-|
|
||||
__( : )|_ Done!
|
||||
EOF
|
||||
echo "---"
|
||||
echo "🎄 Successfully wrote input to \"$input_path\"!"
|
||||
|
||||
# Make sure it gets removed even if the script exits abnormally.
|
||||
trap "exit 1" HUP INT PIPE QUIT TERM
|
||||
|
|
|
@ -10,15 +10,17 @@ 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";
|
||||
example_path="src/examples/$filename.txt";
|
||||
module_path="src/solutions/$filename.rs";
|
||||
module_path="src/bin/$filename.rs";
|
||||
|
||||
touch $module_path;
|
||||
|
||||
cat > $module_path <<EOF
|
||||
use aoc::{solve_day, read_file};
|
||||
|
||||
pub fn part_one(input: &str) -> 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 <<EOF
|
||||
_==_ _
|
||||
_,(",)|_|
|
||||
\/. \-|
|
||||
__( : )|_ Done!
|
||||
EOF
|
||||
echo "Created empty example file \"$example_path\"";
|
||||
echo "---"
|
||||
echo "🎄 Type \`cargo run --bin $day_padded\` to run your solution."
|
||||
|
|
36
src/lib.rs
36
src/lib.rs
|
@ -1,13 +1,41 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
pub static ANSI_ITALIC: &str = "\x1b[3m";
|
||||
pub static ANSI_BOLD: &str = "\x1b[1m";
|
||||
pub static ANSI_RESET: &str = "\x1b[0m";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! solve_day {
|
||||
($input:expr, $part_one:ident, $part_two:ident) => {{
|
||||
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
|
||||
use std::fmt::Display;
|
||||
use std::time::Instant;
|
||||
|
||||
fn print_result<T: Display>(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")
|
||||
|
|
90
src/main.rs
90
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<T: Display>(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<String> = 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()
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue