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
|
# Advent of Code
|
||||||
# @see https://old.reddit.com/r/adventofcode/comments/k99rod/sharing_input_data_were_we_requested_not_to/gf2ukkf/?context=3
|
# @see https://old.reddit.com/r/adventofcode/comments/k99rod/sharing_input_data_were_we_requested_not_to/gf2ukkf/?context=3
|
||||||
inputs
|
/src/inputs
|
||||||
!inputs/.keep
|
!/src/inputs/.keep
|
||||||
|
|
|
@ -3,7 +3,7 @@ name = "aoc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Spöttel <1682504+fspoettel@users.noreply.github.com>"]
|
authors = ["Felix Spöttel <1682504+fspoettel@users.noreply.github.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
default-run = "aoc"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[profile.release]
|
[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>
|
./scripts/scaffold.sh <day>
|
||||||
|
|
||||||
# output:
|
# output:
|
||||||
# Created module `src/solutions/day01.rs`
|
# Created module "src/bin/01.rs"
|
||||||
# Created input file `src/inputs/day01.txt`
|
# Created empty input file "src/inputs/01.txt"
|
||||||
# Created example file `src/examples/day01.txt`
|
# Created empty example file "src/examples/01.txt"
|
||||||
# Linked new module in `src/main.rs`
|
# ---
|
||||||
# Linked new module in `src/solutions/mod.rs`
|
# 🎄 Type `cargo run --bin 01` to run your solution.
|
||||||
# Done! 🎄
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
### 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>
|
./scripts/download.sh <day>
|
||||||
|
|
||||||
# output:
|
# output:
|
||||||
# Invoking `aoc` cli...
|
# Loaded session cookie from "/home/felix/.adventofcode.session".
|
||||||
# Loaded session cookie from "/home/foo/.adventofcode.session".
|
|
||||||
# Downloading input for day 1, 2021...
|
# Downloading input for day 1, 2021...
|
||||||
# Saving puzzle input to "/tmp/..."...
|
# Saving puzzle input to "/tmp/tmp.MBdcAdL9Iw/input"...
|
||||||
# Done!
|
# 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.
|
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
|
### Run solutions for a day
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# example: `cargo run 1`
|
# example: `cargo run --bin 01`
|
||||||
cargo run <day>
|
cargo run --bin <day>
|
||||||
|
|
||||||
# output:
|
# output:
|
||||||
# Running `target/debug/aoc 1`
|
# Running `target/debug/01`
|
||||||
# ----
|
|
||||||
#
|
|
||||||
# 🎄 Part 1 🎄
|
# 🎄 Part 1 🎄
|
||||||
#
|
#
|
||||||
# 6 (elapsed: 37.03µs)
|
# 6 (elapsed: 37.03µs)
|
||||||
|
@ -78,11 +76,17 @@ cargo run <day>
|
||||||
# 🎄 Part 2 🎄
|
# 🎄 Part 2 🎄
|
||||||
#
|
#
|
||||||
# 9 (elapsed: 33.18µs)
|
# 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
|
### Run all solutions against example input
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ fi
|
||||||
day=$(echo $1 | sed 's/^0*//');
|
day=$(echo $1 | sed 's/^0*//');
|
||||||
day_padded=`printf %02d $day`;
|
day_padded=`printf %02d $day`;
|
||||||
|
|
||||||
filename="day$day_padded";
|
filename="$day_padded";
|
||||||
input_path="src/inputs/$filename.txt";
|
input_path="src/inputs/$filename.txt";
|
||||||
|
|
||||||
tmp_dir=$(mktemp -d);
|
tmp_dir=$(mktemp -d);
|
||||||
|
@ -24,14 +24,8 @@ tmp_file_path="$tmp_dir/input";
|
||||||
|
|
||||||
aoc download --day $day --file $tmp_file_path;
|
aoc download --day $day --file $tmp_file_path;
|
||||||
cat $tmp_file_path > $input_path;
|
cat $tmp_file_path > $input_path;
|
||||||
echo "Wrote input to \"$input_path\"...";
|
echo "---"
|
||||||
|
echo "🎄 Successfully wrote input to \"$input_path\"!"
|
||||||
cat <<EOF
|
|
||||||
_==_ _
|
|
||||||
_,(",)|_|
|
|
||||||
\/. \-|
|
|
||||||
__( : )|_ Done!
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Make sure it gets removed even if the script exits abnormally.
|
# Make sure it gets removed even if the script exits abnormally.
|
||||||
trap "exit 1" HUP INT PIPE QUIT TERM
|
trap "exit 1" HUP INT PIPE QUIT TERM
|
||||||
|
|
|
@ -10,15 +10,17 @@ fi
|
||||||
day=$(echo $1 | sed 's/^0*//');
|
day=$(echo $1 | sed 's/^0*//');
|
||||||
day_padded=`printf %02d $day`;
|
day_padded=`printf %02d $day`;
|
||||||
|
|
||||||
filename="day$day_padded";
|
filename="$day_padded";
|
||||||
|
|
||||||
input_path="src/inputs/$filename.txt";
|
input_path="src/inputs/$filename.txt";
|
||||||
example_path="src/examples/$filename.txt";
|
example_path="src/examples/$filename.txt";
|
||||||
module_path="src/solutions/$filename.rs";
|
module_path="src/bin/$filename.rs";
|
||||||
|
|
||||||
touch $module_path;
|
touch $module_path;
|
||||||
|
|
||||||
cat > $module_path <<EOF
|
cat > $module_path <<EOF
|
||||||
|
use aoc::{solve_day, read_file};
|
||||||
|
|
||||||
pub fn part_one(input: &str) -> u32 {
|
pub fn part_one(input: &str) -> u32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -27,6 +29,10 @@ pub fn part_two(input: &str) -> u32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
solve_day!(&read_file("inputs", DAYNUM), part_one, part_two)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -34,43 +40,27 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
use aoc::read_file;
|
use aoc::read_file;
|
||||||
let input = read_file("examples", day);
|
let input = read_file("examples", DAYNUM);
|
||||||
assert_eq!(part_one(&input), 0);
|
assert_eq!(part_one(&input), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_two() {
|
fn test_part_two() {
|
||||||
use aoc::read_file;
|
use aoc::read_file;
|
||||||
let input = read_file("examples", day);
|
let input = read_file("examples", DAYNUM);
|
||||||
assert_eq!(part_two(&input), 0);
|
assert_eq!(part_two(&input), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
perl -pi -e "s,day,$day,g" $module_path;
|
perl -pi -e "s,DAYNUM,$day,g" $module_path;
|
||||||
|
|
||||||
echo "Created module \"$module_path\"";
|
echo "Created module \"$module_path\"";
|
||||||
|
|
||||||
touch $input_path;
|
touch $input_path;
|
||||||
echo "Created input file \"$input_path\"";
|
echo "Created empty input file \"$input_path\"";
|
||||||
|
|
||||||
touch $example_path;
|
touch $example_path;
|
||||||
echo "Created example file \"$example_path\"";
|
echo "Created empty example file \"$example_path\"";
|
||||||
|
echo "---"
|
||||||
line=" $day => solve_day!($filename, &input),"
|
echo "🎄 Type \`cargo run --bin $day_padded\` to run your solution."
|
||||||
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
|
|
||||||
|
|
36
src/lib.rs
36
src/lib.rs
|
@ -1,13 +1,41 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
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 {
|
pub fn read_file(folder: &str, day: u8) -> String {
|
||||||
let cwd = env::current_dir().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
|
|
||||||
let filepath = cwd
|
let filepath = cwd.join("src").join(folder).join(format!("{:02}.txt", day));
|
||||||
.join("src")
|
|
||||||
.join(folder)
|
|
||||||
.join(format!("day{:02}.txt", day));
|
|
||||||
|
|
||||||
let f = fs::read_to_string(filepath);
|
let f = fs::read_to_string(filepath);
|
||||||
f.expect("could not open input file")
|
f.expect("could not open input file")
|
||||||
|
|
90
src/main.rs
90
src/main.rs
|
@ -1,74 +1,26 @@
|
||||||
use crate::solutions::*;
|
use aoc::{ANSI_BOLD, ANSI_RESET};
|
||||||
use aoc::read_file;
|
use std::process::Command;
|
||||||
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!("----");
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
(1..=25).for_each(|day| {
|
||||||
let day: u8 = args[1].clone().parse().unwrap();
|
let day = format!("{:02}", day);
|
||||||
let input = read_file("inputs", day);
|
|
||||||
|
|
||||||
match day {
|
let cmd = Command::new("cargo")
|
||||||
1 => solve_day!(day01, &input),
|
.args(&["run", "--release", "--bin", &day])
|
||||||
2 => solve_day!(day02, &input),
|
.output()
|
||||||
3 => solve_day!(day03, &input),
|
.unwrap();
|
||||||
4 => solve_day!(day04, &input),
|
|
||||||
5 => solve_day!(day05, &input),
|
let output = String::from_utf8(cmd.stdout).unwrap();
|
||||||
6 => solve_day!(day06, &input),
|
println!("----------");
|
||||||
7 => solve_day!(day07, &input),
|
println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET);
|
||||||
8 => solve_day!(day08, &input),
|
println!("----------");
|
||||||
9 => solve_day!(day09, &input),
|
println!(
|
||||||
10 => solve_day!(day10, &input),
|
"{}",
|
||||||
11 => solve_day!(day11, &input),
|
if !output.is_empty() {
|
||||||
12 => solve_day!(day12, &input),
|
output
|
||||||
13 => solve_day!(day13, &input),
|
} else {
|
||||||
14 => solve_day!(day14, &input),
|
"Not solved.".to_string()
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue