Skip to content

Commit d076121

Browse files
committed
Update proc macro
- allows defining the file inline or reading from file system - change solutions to use &str, not String - make the files a different distributed_slice
1 parent 3a1411a commit d076121

File tree

19 files changed

+75
-36
lines changed

19 files changed

+75
-36
lines changed

data/day15.txt

Whitespace-only changes.

libaoc/aoc_attr/src/lib.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@ use syn::{
1212
struct AocTestAttributes {
1313
part1: LitStr,
1414
part2: LitStr,
15+
file: Option<LitStr>,
1516
}
1617

1718
impl Parse for AocTestAttributes {
1819
fn parse(input: ParseStream) -> Result<Self> {
1920
let part1: LitStr = input.parse()?;
2021
input.parse::<Token!(,)>()?;
2122
let part2: LitStr = input.parse()?;
23+
let file = match input.parse::<Token!(,)>() {
24+
Ok(_) => Some(input.parse()?),
25+
Err(_) => None,
26+
};
2227
Ok(Self {
2328
part1: part1,
2429
part2: part2,
30+
file: file,
2531
})
2632
}
2733
}
@@ -42,17 +48,22 @@ pub fn aoc(attr: TokenStream, item: TokenStream) -> TokenStream {
4248
let day_number = nums.parse::<u32>().unwrap();
4349

4450
// parse the provided test results
45-
let AocTestAttributes { part1, part2 } = parse_macro_input!(attr as AocTestAttributes);
51+
let AocTestAttributes { part1, part2, file } = syn::parse(attr).unwrap();
4652

4753
let name = provided_name.to_string();
4854

4955
// use absolute path otherwise rustc breaks
50-
let file = format!(
51-
"{}/data/day{}.txt",
52-
std::env::current_dir().unwrap().to_str().unwrap(),
53-
day_number
54-
);
55-
let fn_name = format_ident!("day{:02}", day_number);
56+
let file = if let Some(file) = file {
57+
quote! { #file }
58+
} else {
59+
let file_name = format!(
60+
"{}/data/day{}.txt",
61+
std::env::current_dir().unwrap().to_str().unwrap(),
62+
day_number
63+
);
64+
quote! {include_str!(#file_name)}
65+
};
66+
5667
let part1_name = format_ident!("day{:02}a", day_number);
5768
let part2_name = format_ident!("day{:02}b", day_number);
5869
let day_number = LitInt::new(&day_number.to_string(), provided_name.span());
@@ -68,7 +79,12 @@ pub fn aoc(attr: TokenStream, item: TokenStream) -> TokenStream {
6879
number: #day_number,
6980
name: #name,
7081
run: #provided_name,
71-
file: include_str!(#file),
82+
};
83+
84+
#[linkme::distributed_slice(crate::FILES)]
85+
static FILE: libaoc::AocFile = libaoc::AocFile {
86+
number: #day_number,
87+
data: #file,
7288
};
7389

7490
#ast
@@ -82,17 +98,19 @@ pub fn aoc(attr: TokenStream, item: TokenStream) -> TokenStream {
8298
#[test]
8399
fn #part1_name() -> Result<()> {
84100
let solution = libaoc::Solution::get(&*crate::SOLUTIONS, #day_number, "solve")?;
101+
let file = libaoc::AocFile::get(&*crate::FILES, #day_number)?;
85102
let mut timer = Timer::new();
86-
let res = #fn_name::#provided_name(&mut timer, solution.file.to_string())?;
103+
let res = solution.run(&mut timer, file)?;
87104
assert_eq!(res.results[0].1, #part1);
88105
Ok(())
89106
}
90107

91108
#[test]
92109
fn #part2_name() -> Result<()> {
93110
let solution = libaoc::Solution::get(&*crate::SOLUTIONS, #day_number, "solve")?;
111+
let file = libaoc::AocFile::get(&*crate::FILES, #day_number)?;
94112
let mut timer = Timer::new();
95-
let res = #fn_name::#provided_name(&mut timer, solution.file.to_string())?;
113+
let res = solution.run(&mut timer, file)?;
96114
assert_eq!(res.results[1].1, #part2);
97115
Ok(())
98116
}

libaoc/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ pub use aoc_attr::aoc;
1515
pub struct Solution {
1616
pub number: usize,
1717
pub name: &'static str,
18-
pub run: fn(&mut Timer, String) -> Result<AocResult>,
19-
pub file: &'static str,
18+
pub run: fn(&mut Timer, &str) -> Result<AocResult>,
2019
}
2120

2221
impl PartialEq for Solution {
@@ -32,7 +31,7 @@ impl PartialEq for Solution {
3231
}
3332

3433
impl Solution {
35-
pub fn run(&self, timer: &mut timer::Timer, arg: String) -> Result<AocResult> {
34+
pub fn run(&self, timer: &mut timer::Timer, arg: &str) -> Result<AocResult> {
3635
(self.run)(timer, arg)
3736
}
3837

@@ -54,6 +53,21 @@ impl Solution {
5453
}
5554
}
5655

56+
pub struct AocFile {
57+
pub number: usize,
58+
pub data: &'static str,
59+
}
60+
61+
impl AocFile {
62+
pub fn get(files: &'static [AocFile], day: usize) -> Result<&'static str> {
63+
files
64+
.iter()
65+
.find(|&x| x.number == day)
66+
.ok_or_else(|| anyhow!("Could not find solution"))
67+
.map(|x| x.data)
68+
}
69+
}
70+
5771
/// generic result container for each day
5872
pub struct AocResult {
5973
pub results: Vec<(&'static str, String)>,

src/days/day01.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::Result;
22
use libaoc::{aoc, AocResult, Timer};
33

44
#[aoc("964875", "158661360")]
5-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
5+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
66
let nums = input
77
.split_whitespace()
88
.map(|x| x.parse::<i32>())

src/days/day02.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use libaoc::{aoc, AocResult, Timer};
33
use regex::Regex;
44

55
#[aoc("483", "482")]
6-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
6+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
77
let lines = input.lines();
88
let extract = Regex::new(r"(\d+)-(\d+) (.): (.+)")?;
99

src/days/day03.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn iter(lines: &[Vec<char>], depth: usize, height: usize) -> i32 {
1717
}
1818

1919
#[aoc("254", "1666768320")]
20-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
20+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
2121
let lines = input
2222
.lines()
2323
.map(|x| x.chars().collect::<Vec<_>>())

src/days/day04.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use libaoc::{aoc, AocResult, Timer};
33
use regex::Regex;
44

55
#[aoc("228", "175")]
6-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
6+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
77
let line = Regex::new(r"(\r?\n){2}")?;
88

99
let datas: Vec<Vec<Vec<_>>> = line

src/days/day05.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use libaoc::{aoc, AocResult, Timer};
33
use std::cmp::max;
44

55
#[aoc("953", "615")]
6-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
6+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
77
let lines: Vec<_> = input.lines().collect();
88
let mut seats = [[false; 8]; 128];
99
timer.lap("Parse");

src/days/day06.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libaoc::{aoc, AocResult, Timer};
44
use regex::Regex;
55

66
#[aoc("7283", "3520")]
7-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
7+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
88
let line = Regex::new(r"(\r?\n){2}")?;
99

1010
let chars1 = line

src/days/day07.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct Bag {
1414
const TARGET: &str = "shiny gold";
1515

1616
#[aoc("278", "45157")]
17-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
17+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
1818
let mut bags: HashMap<String, Rc<RefCell<Bag>>> = HashMap::new();
1919

2020
let input: Vec<Vec<_>> = input

src/days/day08.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::Result;
22
use libaoc::{aoc, AocResult, Instruction, Timer, VM};
33

44
#[aoc("1915", "944")]
5-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
5+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
66
let vm = VM::file_parse(&input);
77
timer.lap("Parse");
88

src/days/day09.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libaoc::{aoc, AocResult, Timer};
44
use std::cmp::Ordering;
55

66
#[aoc("3199139634", "438559930")]
7-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
7+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
88
let nums: Vec<_> = input.lines().map(|x| x.parse::<u64>().unwrap()).collect();
99
timer.lap("Parse");
1010

src/days/day10.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::Result;
22
use libaoc::{aoc, AocResult, Timer};
33

44
#[aoc("1885", "2024782584832")]
5-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
5+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
66
let mut nums: Vec<_> = input.lines().map(|x| x.parse::<i64>().unwrap()).collect();
77
nums.sort_unstable();
88
timer.lap("Parse");

src/days/day11.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fn iter_advance(initial_seats: &[Vec<Postion>], any_dist: bool, occ_count: i32)
113113
}
114114

115115
#[aoc("2494", "2306")]
116-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
116+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
117117
let initial_seats: Vec<Vec<_>> = input
118118
.lines()
119119
.map(|x| {

src/days/day12.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn waypoint(left: bool, amount: i32, x: i32, y: i32) -> (i32, i32) {
5858
}
5959

6060
#[aoc("2297", "89984")]
61-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
61+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
6262
let input: Vec<_> = input
6363
.trim()
6464
.lines()

src/days/day13.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::Result;
22
use libaoc::{aoc, AocResult, Timer};
33

44
#[aoc("3215", "1001569619313439")]
5-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
5+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
66
let lines: Vec<_> = input.lines().collect();
77
let secs: usize = lines[0].parse().unwrap();
88
let buses: Vec<usize> = lines[1]

src/days/day14.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ enum Command {
1111
use Command::*;
1212

1313
#[aoc("11501064782628", "5142195937660")]
14-
pub fn solve(timer: &mut Timer, input: String) -> Result<AocResult> {
14+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
1515
let mem_reg = Regex::new(r"mem\[(\d+)\] = (\d+)")?;
1616
let mask_reg = Regex::new(r"mask = ([X01]+)")?;
1717

src/days/day15.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ fn run(numbers_map: &mut [(i32, usize, usize)], numbers: &[usize], max: usize) -
3636
spoken
3737
}
3838

39-
#[aoc("1015", "201")]
40-
pub fn solve(timer: &mut Timer, _input: String) -> Result<AocResult> {
41-
let numbers = vec![19, 0, 5, 1, 10, 13];
42-
let mut map1 = vec![(0, 0, 0); 2020];
43-
let mut map2 = vec![(0, 0, 0); 30000000];
39+
#[aoc("1015", "201", "2020, 30000000, 19, 0, 5, 1, 10, 13")]
40+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
41+
let numbers: Vec<_> = input
42+
.split(',')
43+
.map(|x| x.trim().parse())
44+
.collect::<Result<_, _>>()?;
45+
let mut map1 = vec![(0, 0, 0); numbers[0]];
46+
let mut map2 = vec![(0, 0, 0); numbers[1]];
47+
let numbers = &numbers[2..];
4448
timer.lap("Parse");
4549

4650
let part1 = run(&mut map1, &numbers, 2020);

src/main.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use anyhow::Result;
66
use clap::{App, Arg, ArgMatches};
7-
use libaoc::{FloatTime, Solution, Timer};
7+
use libaoc::{AocFile, FloatTime, Solution, Timer};
88
use linkme::distributed_slice;
99
use regex::Regex;
1010
use std::{error::Error, fmt, time::Instant};
@@ -17,6 +17,9 @@ mod days;
1717
#[distributed_slice]
1818
pub static SOLUTIONS: [Solution] = [..];
1919

20+
#[distributed_slice]
21+
pub static FILES: [AocFile] = [..];
22+
2023
/// custom error type for the command line interface
2124
/// only exists so that multiple errors can be combined, so all errors
2225
/// are reported, not just the first
@@ -93,10 +96,10 @@ fn run_solution(solution: &Solution, debug: bool) {
9396
print!("Day {} {}: ", solution.number, solution.name);
9497
}
9598

96-
let file_data = solution.file;
99+
let file_data = AocFile::get(&*FILES, solution.number).unwrap();
97100

98101
let mut timer = Timer::new();
99-
let res = solution.run(&mut timer, file_data.to_string());
102+
let res = solution.run(&mut timer, file_data);
100103
timer.stop();
101104

102105
match res {
@@ -107,7 +110,7 @@ fn run_solution(solution: &Solution, debug: bool) {
107110
println!("{}", val)
108111
}
109112
}
110-
Err(err) => print!("{:#?}", err),
113+
Err(err) => println!("{:#?}", err),
111114
}
112115

113116
if debug {

0 commit comments

Comments
 (0)