Skip to content

Commit 681c03a

Browse files
committed
feat: use cargo --bin instead of solutions crate
1 parent 4449f5b commit 681c03a

File tree

9 files changed

+100
-132
lines changed

9 files changed

+100
-132
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ target/
1616

1717
# Advent of Code
1818
# @see https://old.reddit.com/r/adventofcode/comments/k99rod/sharing_input_data_were_we_requested_not_to/gf2ukkf/?context=3
19-
inputs
20-
!inputs/.keep
19+
/src/inputs
20+
!/src/inputs/.keep

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "aoc"
33
version = "0.1.0"
44
authors = ["Felix Spöttel <[email protected]>"]
55
edition = "2021"
6-
6+
default-run = "aoc"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[profile.release]

README.md

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@ Generated with the [advent-of-code-rust](https://github.com/fspoettel/advent-of-
3333
./scripts/scaffold.sh <day>
3434

3535
# output:
36-
# Created module `src/solutions/day01.rs`
37-
# Created input file `src/inputs/day01.txt`
38-
# Created example file `src/examples/day01.txt`
39-
# Linked new module in `src/main.rs`
40-
# Linked new module in `src/solutions/mod.rs`
41-
# Done! 🎄
36+
# Created module "src/bin/01.rs"
37+
# Created empty input file "src/inputs/01.txt"
38+
# Created empty example file "src/examples/01.txt"
39+
# ---
40+
# 🎄 Type `cargo run --bin 01` to run your solution.
4241
```
4342

44-
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.
43+
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.
4544

4645
### Download inputs for a day
4746

@@ -50,39 +49,44 @@ Every solution file has _unit tests_ referencing the example input file. You can
5049
./scripts/download.sh <day>
5150

5251
# output:
53-
# Invoking `aoc` cli...
54-
# Loaded session cookie from "/home/foo/.adventofcode.session".
52+
# Loaded session cookie from "/home/felix/.adventofcode.session".
5553
# Downloading input for day 1, 2021...
56-
# Saving puzzle input to "/tmp/..."...
54+
# Saving puzzle input to "/tmp/tmp.MBdcAdL9Iw/input"...
5755
# Done!
58-
# Wrote input to `src/inputs/day01.txt`...
59-
# Done! 🎄
56+
# ---
57+
# 🎄 Successfully wrote input to "src/inputs/01.txt"!
6058
```
6159

6260
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.
6361

62+
> 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.
63+
6464
### Run solutions for a day
6565

6666
```sh
67-
# example: `cargo run 1`
68-
cargo run <day>
67+
# example: `cargo run --bin 01`
68+
cargo run --bin <day>
6969

7070
# output:
71-
# Running `target/debug/aoc 1`
72-
# ----
73-
#
71+
# Running `target/debug/01`
7472
# 🎄 Part 1 🎄
7573
#
7674
# 6 (elapsed: 37.03µs)
7775
#
7876
# 🎄 Part 2 🎄
7977
#
8078
# 9 (elapsed: 33.18µs)
81-
#
82-
# ----
8379
```
8480

85-
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr <day>`.
81+
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr --bin <day>`.
82+
83+
### Run all solutions
84+
85+
```sh
86+
cargo run
87+
```
88+
89+
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr`.
8690

8791
### Run all solutions against example input
8892

scripts/download.sh

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,17 @@ fi
1616
day=$(echo $1 | sed 's/^0*//');
1717
day_padded=`printf %02d $day`;
1818

19-
filename="day$day_padded";
19+
filename="$day_padded";
2020
input_path="src/inputs/$filename.txt";
2121

2222
tmp_dir=$(mktemp -d);
2323
tmp_file_path="$tmp_dir/input";
2424

2525
aoc download --day $day --file $tmp_file_path;
2626
cat $tmp_file_path > $input_path;
27-
echo "Wrote input to \"$input_path\"...";
28-
29-
cat <<EOF
30-
_==_ _
31-
_,(",)|_|
32-
\/. \-|
33-
__( : )|_ Done!
34-
EOF
27+
echo "---"
28+
echo "🎄 Successfully wrote input to \"$input_path\"!"
3529

3630
# Make sure it gets removed even if the script exits abnormally.
37-
trap "exit 1" HUP INT PIPE QUIT TERM
31+
trap "exit 1" HUP INT PIPE QUIT TERM
3832
trap 'rm -rf "$tmp_dir"' EXIT

scripts/scaffold.sh

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ fi
1010
day=$(echo $1 | sed 's/^0*//');
1111
day_padded=`printf %02d $day`;
1212

13-
filename="day$day_padded";
13+
filename="$day_padded";
1414

1515
input_path="src/inputs/$filename.txt";
1616
example_path="src/examples/$filename.txt";
17-
module_path="src/solutions/$filename.rs";
17+
module_path="src/bin/$filename.rs";
1818

1919
touch $module_path;
2020

2121
cat > $module_path <<EOF
22+
use aoc::{solve_day, read_file};
23+
2224
pub fn part_one(input: &str) -> u32 {
2325
0
2426
}
@@ -27,50 +29,38 @@ pub fn part_two(input: &str) -> u32 {
2729
0
2830
}
2931
32+
fn main() {
33+
solve_day!(&read_file("inputs", DAYNUM), part_one, part_two)
34+
}
35+
3036
#[cfg(test)]
3137
mod tests {
3238
use super::*;
3339
3440
#[test]
3541
fn test_part_one() {
3642
use aoc::read_file;
37-
let input = read_file("examples", day);
43+
let input = read_file("examples", DAYNUM);
3844
assert_eq!(part_one(&input), 0);
3945
}
4046
4147
#[test]
4248
fn test_part_two() {
4349
use aoc::read_file;
44-
let input = read_file("examples", day);
50+
let input = read_file("examples", DAYNUM);
4551
assert_eq!(part_two(&input), 0);
4652
}
4753
}
4854
EOF
4955

50-
perl -pi -e "s,day,$day,g" $module_path;
56+
perl -pi -e "s,DAYNUM,$day,g" $module_path;
5157

5258
echo "Created module \"$module_path\"";
5359

5460
touch $input_path;
55-
echo "Created input file \"$input_path\"";
61+
echo "Created empty input file \"$input_path\"";
5662

5763
touch $example_path;
58-
echo "Created example file \"$example_path\"";
59-
60-
line=" $day => solve_day!($filename, &input),"
61-
perl -pi -le "print '$line' if(/^*.day not solved/);" "src/main.rs";
62-
63-
echo "Linked new module in \"src/main.rs\"";
64-
65-
LINE="pub mod $filename;";
66-
FILE="src/solutions/mod.rs";
67-
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE";
68-
echo "Linked new module in \"$FILE\"";
69-
70-
71-
cat <<EOF
72-
_==_ _
73-
_,(",)|_|
74-
\/. \-|
75-
__( : )|_ Done!
76-
EOF
64+
echo "Created empty example file \"$example_path\"";
65+
echo "---"
66+
echo "🎄 Type \`cargo run --bin $day_padded\` to run your solution."
File renamed without changes.
File renamed without changes.

src/lib.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,41 @@
11
use std::env;
22
use std::fs;
33

4+
pub static ANSI_ITALIC: &str = "\x1b[3m";
5+
pub static ANSI_BOLD: &str = "\x1b[1m";
6+
pub static ANSI_RESET: &str = "\x1b[0m";
7+
8+
#[macro_export]
9+
macro_rules! solve_day {
10+
($input:expr, $part_one:ident, $part_two:ident) => {{
11+
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
12+
use std::fmt::Display;
13+
use std::time::Instant;
14+
15+
fn print_result<T: Display>(func: impl FnOnce(&str) -> T, input: &str) {
16+
let timer = Instant::now();
17+
let result = func(input);
18+
let time = timer.elapsed();
19+
println!(
20+
"{} {}(elapsed: {:.2?}){}",
21+
result, ANSI_ITALIC, time, ANSI_RESET
22+
);
23+
}
24+
25+
println!("🎄 {}Part 1{} 🎄", ANSI_BOLD, ANSI_RESET);
26+
println!("");
27+
print_result($part_one, $input);
28+
println!("");
29+
println!("🎄 {}Part 2{} 🎄", ANSI_BOLD, ANSI_RESET);
30+
println!("");
31+
print_result($part_two, $input);
32+
}};
33+
}
34+
435
pub fn read_file(folder: &str, day: u8) -> String {
536
let cwd = env::current_dir().unwrap();
637

7-
let filepath = cwd
8-
.join("src")
9-
.join(folder)
10-
.join(format!("day{:02}.txt", day));
38+
let filepath = cwd.join("src").join(folder).join(format!("{:02}.txt", day));
1139

1240
let f = fs::read_to_string(filepath);
1341
f.expect("could not open input file")

src/main.rs

Lines changed: 22 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,26 @@
1-
use crate::solutions::*;
2-
use aoc::read_file;
3-
use std::env;
4-
use std::fmt::Display;
5-
use std::time::Instant;
6-
7-
mod helpers;
8-
mod solutions;
9-
10-
static ANSI_ITALIC: &str = "\x1b[3m";
11-
static ANSI_BOLD: &str = "\x1b[1m";
12-
static ANSI_RESET: &str = "\x1b[0m";
13-
14-
fn print_result<T: Display>(func: impl FnOnce(&str) -> T, input: &str) {
15-
let timer = Instant::now();
16-
let result = func(input);
17-
let time = timer.elapsed();
18-
println!(
19-
"{} {}(elapsed: {:.2?}){}",
20-
result, ANSI_ITALIC, time, ANSI_RESET
21-
);
22-
}
23-
24-
macro_rules! solve_day {
25-
($day:path, $input:expr) => {{
26-
use $day::*;
27-
println!("----");
28-
println!("");
29-
println!("🎄 {}Part 1{} 🎄", ANSI_BOLD, ANSI_RESET);
30-
println!("");
31-
print_result(part_one, $input);
32-
println!("");
33-
println!("🎄 {}Part 2{} 🎄", ANSI_BOLD, ANSI_RESET);
34-
println!("");
35-
print_result(part_two, $input);
36-
println!("");
37-
println!("----");
38-
}};
39-
}
1+
use aoc::{ANSI_BOLD, ANSI_RESET};
2+
use std::process::Command;
403

414
fn main() {
42-
let args: Vec<String> = env::args().collect();
43-
let day: u8 = args[1].clone().parse().unwrap();
44-
let input = read_file("inputs", day);
5+
(1..=25).for_each(|day| {
6+
let day = format!("{:02}", day);
7+
8+
let cmd = Command::new("cargo")
9+
.args(&["run", "--release", "--bin", &day])
10+
.output()
11+
.unwrap();
4512

46-
match day {
47-
1 => solve_day!(day01, &input),
48-
2 => solve_day!(day02, &input),
49-
3 => solve_day!(day03, &input),
50-
4 => solve_day!(day04, &input),
51-
5 => solve_day!(day05, &input),
52-
6 => solve_day!(day06, &input),
53-
7 => solve_day!(day07, &input),
54-
8 => solve_day!(day08, &input),
55-
9 => solve_day!(day09, &input),
56-
10 => solve_day!(day10, &input),
57-
11 => solve_day!(day11, &input),
58-
12 => solve_day!(day12, &input),
59-
13 => solve_day!(day13, &input),
60-
14 => solve_day!(day14, &input),
61-
15 => solve_day!(day15, &input),
62-
16 => solve_day!(day16, &input),
63-
17 => solve_day!(day17, &input),
64-
18 => solve_day!(day18, &input),
65-
19 => solve_day!(day19, &input),
66-
20 => solve_day!(day20, &input),
67-
21 => solve_day!(day21, &input),
68-
22 => solve_day!(day22, &input),
69-
23 => solve_day!(day23, &input),
70-
24 => solve_day!(day24, &input),
71-
25 => solve_day!(day25, &input),
72-
_ => println!("day not solved: {}", day),
73-
}
13+
let output = String::from_utf8(cmd.stdout).unwrap();
14+
println!("----------");
15+
println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET);
16+
println!("----------");
17+
println!(
18+
"{}",
19+
if !output.is_empty() {
20+
output
21+
} else {
22+
"Not solved.".to_string()
23+
}
24+
);
25+
});
7426
}

0 commit comments

Comments
 (0)