#[bin_setup]Available on crate feature
binary only.Expand description
This macro can be used to generate my standard approach to Advent of Code binaries.
It can only be attached to fn main().
Required arguments:
puzzles_count, number of puzzles in the binaryresources_directory, path to inputs and answers files, relative tosrcinput_extension, input files extensionanswers_file, file containing the puzzle answers for checking execution
A simple pretty_solution_2 macro is provided to:
- embed input strings
- execute solutions
- measure execution time
- verify output against provided answers
The generated main function provides args handling to execute only specific days, e.g. $ executable 1 3 5
Example usage:
use aoc_core_macros::bin_setup;
#[bin_setup(5, "../resources", ".in", "Answers.out")]
fn main() {
pretty_solution_2!(5, "PuzzleX", solution1, solution2);
}
fn solution1(input: &str) -> u8 {
input.lines().map(|n| n.parse::<u8>().unwrap()).sum()
}
fn solution2(input: &str) -> u8 {
input.lines().map(|n| n.parse::<u8>().unwrap()).product()
}
// ../resources/PuzzleX.in
// 2
// 3
// ../resources/Answers.out
// PuzzleX 5 6Generated code looks like this:
#[allow(clippy::items_after_statements)]
fn main() {
let puzzle_answers: rustc_hash::FxHashMap<&'static str, [&'static str; 2]> =
include_str!(concat!("../resources", "/", "Answers.out"))
.lines()
.map(|line| {
let parts: Vec<_> = line.split_ascii_whitespace().collect();
(parts[0], [parts[1], parts[2]])
})
.collect();
let selected_puzzles: [bool; 5] = {
let args: Vec<_> = std::env::args().collect();
if args.len() == 1 {
[true; 5]
} else {
std::array::from_fn(|day| args.contains(&(day + 1).to_string()))
}
};
#[inline]
fn pretty_solution<R>(
puzzle: &str,
part: usize,
solution: fn(&str) -> R,
input: &str,
answer: &str,
) where
R: std::fmt::Display + PartialEq,
{
let now = std::time::Instant::now();
let solution = solution(input);
let microseconds = now.elapsed().as_micros();
assert!(
solution.to_string() == answer,
"Wrong solution for {puzzle} part {part}: expected {answer}, but got {solution}"
);
println!("{part} -> {answer} ({microseconds}μs)");
}
macro_rules! pretty_solution_2 {
($day:literal, $puzzle: literal, $solution1:ident $(,$solution2:ident)?) => {
if selected_puzzles[$day - 1] {
println!("Day {}: {}", $day, $puzzle);
const INPUT: &str =
include_str!(concat!("../resources", "/", $puzzle, ".in"));
let answers = puzzle_answers.get($puzzle).expect("Puzzle answer not found");
pretty_solution($puzzle, 1, $solution1, INPUT, answers[0]);
$(pretty_solution($puzzle, 2, $solution2, INPUT, answers[1]);)?
println!();
}
};
}
pretty_solution_2!(5, "PuzzleX", solution1, solution2);
}