From 90d400eb375890d8b054fd8b44fcb2205717ec96 Mon Sep 17 00:00:00 2001 From: Sebastian Tobie Date: Thu, 19 Dec 2024 17:12:39 +0100 Subject: [PATCH] inlcude_aoc is now the only method for importing data --- .gitignore | 2 +- days/2023/01.rs | 7 +-- days/2023/02.rs | 5 +- days/2024/01.rs | 5 +- days/2024/02.rs | 5 +- days/2024/03.rs | 5 +- days/2024/04.rs | 8 +-- days/2024/06.rs | 7 +-- days/2024/07.rs | 8 +-- days/2024/08.rs | 5 +- days/2024/09.rs | 5 +- days/2024/10.rs | 7 +-- days/2024/11.rs | 6 +- days/2024/12.rs | 22 +++---- days/2024/14.rs | 5 +- days/2024/15.rs | 5 +- days/2024/16.rs | 5 +- days/2024/17.rs | 5 +- days/2024/18.rs | 5 +- days/2024/19.rs | 40 ++++++------ macros/src/lib.rs | 153 +++++----------------------------------------- 21 files changed, 83 insertions(+), 232 deletions(-) diff --git a/.gitignore b/.gitignore index a092d7f..684a425 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ /data/**/*.txt !/data/2023/01a.txt !/data/2023/01b.txt -!/data/20*/.gitkeep \ No newline at end of file +!/data/20*/.gitkeep diff --git a/days/2023/01.rs b/days/2023/01.rs index ee8716c..a5bd4f9 100644 --- a/days/2023/01.rs +++ b/days/2023/01.rs @@ -1,9 +1,8 @@ +use advent_of_code::include_aoc; use advent_of_code::strings::{convert_to_array, get_numbers, get_string_numbers}; -#[allow(unused_imports)] -use advent_of_code::{include_data, include_example}; -include_data!(DATAa 2023 01a); -include_data!(DATAb 2023 01b); +include_aoc!(DATAa, 2023, 01a); +include_aoc!(DATAb, 2023, 01b); fn main() { let mut sum: u32 = 0; diff --git a/days/2023/02.rs b/days/2023/02.rs index 19cf441..3cf112b 100644 --- a/days/2023/02.rs +++ b/days/2023/02.rs @@ -1,8 +1,7 @@ +use advent_of_code::include_aoc; use advent_of_code::strings::parsenumber; -#[allow(unused_imports)] -use advent_of_code::{include_data, include_example}; -include_example!(DATA 2023 02); +include_aoc!(2023, 02); #[derive(Debug, Clone, Copy)] struct Take { diff --git a/days/2024/01.rs b/days/2024/01.rs index 1798e6d..75df5d0 100644 --- a/days/2024/01.rs +++ b/days/2024/01.rs @@ -1,8 +1,7 @@ +use advent_of_code::include_aoc; use advent_of_code::strings::{convert_to_array, parsenumber}; -#[allow(unused_imports)] -use advent_of_code::{include_data, include_example}; -include_data!(DATA 2024 01); +include_aoc!(2024, 01); pub fn splitspace(input: &str) -> (u32, u32) { println!("{}", input); diff --git a/days/2024/02.rs b/days/2024/02.rs index c1b3145..ce1bc95 100644 --- a/days/2024/02.rs +++ b/days/2024/02.rs @@ -1,11 +1,10 @@ -#[allow(unused_imports)] -use advent_of_code::{include_data, include_example}; +use advent_of_code::include_aoc; use advent_of_code::{ strings::{convert_to_array, parsenumber}, KD, }; -include_data!(DATA 2024 02); +include_aoc!(2024, 02); fn get_numbers(input: &str) -> Vec { input.split(char::is_whitespace).map(parsenumber).collect() diff --git a/days/2024/03.rs b/days/2024/03.rs index 66aafd4..6e2235e 100644 --- a/days/2024/03.rs +++ b/days/2024/03.rs @@ -1,9 +1,8 @@ +use advent_of_code::include_aoc; use advent_of_code::strings::parsenumber; -#[allow(unused_imports)] -use advent_of_code::{include_data, include_example}; use regex::{Captures, Regex}; -include_data!(DATA 2024 03); +include_aoc!(2024, 03); fn parse_part1(input: Vec>) -> u32 { let mut sum = 0; diff --git a/days/2024/04.rs b/days/2024/04.rs index a646fb3..24bc384 100644 --- a/days/2024/04.rs +++ b/days/2024/04.rs @@ -1,14 +1,10 @@ -#![allow(unused_variables, unused_assignments)] -#![allow(unused_imports)] -use std::ops::Add; - -use advent_of_code::{include_data, include_example}; +use advent_of_code::include_aoc; use advent_of_code::{ strings::{convert_to_array, line_to_char}, Kartesian, KartesianDirection, MaximumFromMap, Table, }; -include_data!(DATA 2024 04); +include_aoc!(2024, 04); #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] struct TextPos { diff --git a/days/2024/06.rs b/days/2024/06.rs index 4ae6439..63fa9a8 100644 --- a/days/2024/06.rs +++ b/days/2024/06.rs @@ -1,6 +1,5 @@ -#[allow(unused_imports)] use advent_of_code::{ - include_data, include_example, + include_aoc, strings::{convert_to_array, line_to_char}, KartesianDirection, }; @@ -8,7 +7,7 @@ use advent_of_code::{Kartesian, Table}; use log::debug; use num::Integer; -include_data!(DATA 2024 06); +include_aoc!(2024, 06); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] struct DirectionalKartesian { @@ -139,7 +138,7 @@ fn main() { mod test { use super::*; - include_example!(EXAMPLE 2024 06); + include_aoc!(EXAMPLE, 2024, 06, true); #[test] fn test_solution_1() { diff --git a/days/2024/07.rs b/days/2024/07.rs index e6d840f..02a46bf 100644 --- a/days/2024/07.rs +++ b/days/2024/07.rs @@ -1,15 +1,13 @@ -#![cfg_attr(debug_assertions, allow(unused_imports))] -use std::ops::{Add, AddAssign, BitXor, Mul}; +use std::ops::{Add, AddAssign, Mul}; use advent_of_code::{ numberlength, strings::{convert_to_array, parsenumber}, }; -use advent_of_code_macros::{include_data, include_example}; -use log::*; +use advent_of_code_macros::include_aoc; use num::{pow::Pow, Integer}; -include_data!(DATA 2024 07); +include_aoc!(2024, 07); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] enum Operation { diff --git a/days/2024/08.rs b/days/2024/08.rs index e4abf4b..5fb3784 100644 --- a/days/2024/08.rs +++ b/days/2024/08.rs @@ -4,11 +4,10 @@ use advent_of_code::{ strings::{convert_to_array, line_to_char}, Kartesian, Table, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; use log::*; -include_data!(DATA 2024 08); +include_aoc!(2024, 08); const EMPTY: char = '.'; diff --git a/days/2024/09.rs b/days/2024/09.rs index 8705fe5..d825def 100644 --- a/days/2024/09.rs +++ b/days/2024/09.rs @@ -1,8 +1,7 @@ use advent_of_code::strings::char_to_num; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; -include_data!(DATA 2024 09); +include_aoc!(2024, 09); type Disk = Vec>; diff --git a/days/2024/10.rs b/days/2024/10.rs index 09695c2..67fa38c 100644 --- a/days/2024/10.rs +++ b/days/2024/10.rs @@ -2,10 +2,9 @@ use advent_of_code::{ strings::{char_to_num, convert_to_array}, Kartesian, KartesianDirection, MaximumFromMap, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; -include_data!(DATA 2024 10); +include_aoc!(2024, 10); type Trail = Vec>; type Map = Vec>; @@ -96,7 +95,7 @@ fn main() { mod test { use super::*; - include_example!(MAP 2024 10); + include_aoc!(MAP, 2024, 10, true); const SCORE: u32 = 36; #[test] diff --git a/days/2024/11.rs b/days/2024/11.rs index 23204d4..419a861 100644 --- a/days/2024/11.rs +++ b/days/2024/11.rs @@ -1,4 +1,3 @@ -#![allow(unused)] use std::collections::HashMap; use advent_of_code::{ @@ -6,11 +5,10 @@ use advent_of_code::{ strings::{convert_to_array, parsenumber}, ExtendedOption, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; use num::Integer; -include_data!(DATA 2024 11); +include_aoc!(2024, 11); const BILLIONS: u64 = 1000_000_000; diff --git a/days/2024/12.rs b/days/2024/12.rs index f46d70f..af87a0b 100644 --- a/days/2024/12.rs +++ b/days/2024/12.rs @@ -1,13 +1,11 @@ -#![allow(unused)] -use std::ops::{Mul, Not}; +use std::ops::Mul; -use advent_of_code::{strings::convert_to_array, ExtendedOption, Kartesian, KartesianDirection, KartesianIterator, MaximumFromMap, Table, KD}; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code::{strings::convert_to_array, Kartesian, MaximumFromMap, Table, KD}; +use advent_of_code_macros::include_aoc; use log::*; -use num::{iter, Integer}; +use num::Integer; -include_data!(DATA 2024 12); +include_aoc!(2024, 12); type Minimap = Vec>; @@ -269,11 +267,11 @@ fn main() { #[cfg(test)] mod test { use super::*; - include_example!(MAP_A 2024 12a); - include_example!(MAP_B 2024 12b); - include_example!(MAP_C 2024 12c); - include_example!(MAP_D 2024 12d); - include_example!(MAP_E 2024 12f); + include_aoc!(MAP_A, 2024, 12a, true); + include_aoc!(MAP_B, 2024, 12b, true); + include_aoc!(MAP_C, 2024, 12c, true); + include_aoc!(MAP_D, 2024, 12d, true); + include_aoc!(MAP_E, 2024, 12f, true); #[test] fn test_fence_a_perimeter() { diff --git a/days/2024/14.rs b/days/2024/14.rs index 0a608c5..f60ff73 100644 --- a/days/2024/14.rs +++ b/days/2024/14.rs @@ -2,10 +2,9 @@ use advent_of_code::{ strings::{convert_to_array, parsenumber}, Kartesian, Velocity, KD, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; -include_data!(DATA 2024 14); +include_aoc!(2024, 14); fn parse_robot(line: &str) -> (Kartesian, Velocity) { let mut dir = KD::None; diff --git a/days/2024/15.rs b/days/2024/15.rs index 05f07a7..78bf7b8 100644 --- a/days/2024/15.rs +++ b/days/2024/15.rs @@ -3,11 +3,10 @@ use advent_of_code::{ strings::{convert_to_array, line_to_char}, Kartesian, KartesianDirection, Map, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; use log::debug; -include_data!(DATA 2024 15); +include_aoc!(DATA 2024 15); const WALL: char = '#'; const ROBOT: char = '@'; diff --git a/days/2024/16.rs b/days/2024/16.rs index 3d6f06e..ec1eaeb 100644 --- a/days/2024/16.rs +++ b/days/2024/16.rs @@ -5,10 +5,9 @@ use advent_of_code::{ strings::{convert_to_array, line_to_char}, Kartesian, KartesianDirection, Map, KD, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; -include_data!(DATA 2024 16); +include_aoc!(DATA 2024 16); const START: Option = Some('S'); const WALL: Option = Some('#'); diff --git a/days/2024/17.rs b/days/2024/17.rs index e70cd18..1be2a02 100644 --- a/days/2024/17.rs +++ b/days/2024/17.rs @@ -1,10 +1,9 @@ use advent_of_code::strings::{convert_to_array, parsenumber}; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; use log::*; use thousands::Separable; -include_data!(DATA 2024 17); +include_aoc!(DATA 2024 17); const ADV: u64 = 0; const BXL: u64 = 1; diff --git a/days/2024/18.rs b/days/2024/18.rs index 958a892..9a1d944 100644 --- a/days/2024/18.rs +++ b/days/2024/18.rs @@ -4,11 +4,10 @@ use advent_of_code::{ strings::{convert_to_array, parsenumber}, Kartesian, Map, ToCoords, KD, }; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; use log::*; -include_data!(DATA 2024 18); +include_aoc!(DATA 2024 18); const HEIGHT: usize = 71; const WIDTH: usize = HEIGHT; diff --git a/days/2024/19.rs b/days/2024/19.rs index 6e5647b..d671e86 100644 --- a/days/2024/19.rs +++ b/days/2024/19.rs @@ -1,11 +1,9 @@ use advent_of_code::strings::convert_to_array; -#[allow(unused_imports)] -use advent_of_code_macros::{include_data, include_example}; +use advent_of_code_macros::include_aoc; -include_data!(DATA 2024 19); +include_aoc!(2024, 19); fn test_pattern(pattern: String, parts: Vec) -> bool { - false } @@ -17,27 +15,27 @@ fn main() { let mut possible = 0; for design in designs { let mut candidates = vec![design]; - 'designloop :loop { - let mut new = Vec::with_capacity(candidates.len()); - for possibility in candidates { - for part in patterns.clone() { - if possibility.starts_with(part.as_str()) { - if possibility.len() == part.len() { - println!("Found design"); - possible+=1; - break 'designloop; + 'designloop: loop { + let mut new = Vec::with_capacity(candidates.len()); + for possibility in candidates { + for part in patterns.clone() { + if possibility.starts_with(part.as_str()) { + if possibility.len() == part.len() { + println!("Found design"); + possible += 1; + break 'designloop; + } + new.push(possibility[part.len()..].to_owned()); } - new.push(possibility[part.len()..].to_owned()); } } + new.sort(); + new.dedup(); + candidates = new; + if candidates.len() == 0 { + break; + } } - new.sort(); - new.dedup(); - candidates = new; - if candidates.len() == 0 { - break; - } - } } println!("There are {} possible designs", possible); } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 30eb54e..a6a787c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -2,7 +2,7 @@ use std::fs::{self, read_to_string}; use proc_macro::TokenStream; use quote::{format_ident, quote}; -use syn::{parse, LitBool, Result}; +use syn::{parse, token::Comma, LitBool, Result}; use syn::{ parse::{Parse, ParseStream}, spanned::Spanned, @@ -13,23 +13,6 @@ const DATA_DIR: &str = "data"; const EXAMPLE_DIR: &str = "examples"; const VAR_NAME: &str = "DATA"; -#[derive(Debug, Clone)] -struct IncludeData { - var: String, - year: Option, - day: Option, -} - -impl Default for IncludeData { - fn default() -> Self { - IncludeData { - var: VAR_NAME.into(), - year: None, - day: None, - } - } -} - fn get_text(item: T) -> Result { let span = item.span(); match span.source_text() { @@ -42,119 +25,8 @@ fn get_text(item: T) -> Result { } } -impl Parse for IncludeData { - fn parse(input: ParseStream) -> Result { - let mut data = IncludeData::default(); - if input.peek(Ident) && !input.peek(LitInt) { - data.var = get_text(input.parse::().unwrap())?; - } - data.year = Some(get_text(input.parse::()?)?); - data.day = Some(get_text(input.parse::()?)?); - - Ok(data) - } -} - -fn canonicalize(dir: &str, input: IncludeData) -> Option { - let pathname = format!("{}/{}/{}.txt", dir, input.year.unwrap(), input.day.unwrap()); - match fs::canonicalize(pathname) { - Ok(canon) => { - if canon.is_file() { - match canon.to_str() { - Some(c) => Some(c.to_string()), - None => None, - } - } else { - None - } - }, - Err(_) => None, - } -} - -/// includes Data from Advent of code -/// ```ignore (cannot-doctest-external-file-dependency) -/// include_data!(DATA 2015 01) -/// // or -/// include_data!(2015 01) -/// -/// fn main() { -/// print!("{DATA}"); -/// } -/// ``` -/// The Equivalent is -/// ```ignore (cannot-doctest-external-file-dependency) -/// static DATA: &str = include_str!("../../../data/2015/01.txt"); -/// ``` -#[proc_macro] -pub fn include_data(data: TokenStream) -> TokenStream { - let input = match parse::(data) { - Ok(include) => include, - Err(error) => return error.into_compile_error().into(), - }; - let ident = format_ident!("{}", input.var); - let mut comment: String; - if input.day.is_some() && input.year.is_some() { - comment = "Data from the data dir".into(); - let mut path = canonicalize(DATA_DIR, input.clone()); - if path.is_none() { - comment = "Data from the examples".into(); - path = canonicalize(EXAMPLE_DIR, input) - } - match path { - Some(p) => { - return quote! { - #[doc = #comment] - const #ident: &str = include_str!(#p).trim_ascii(); - } - .into(); - }, - None => comment = "failed to get data from the paths".into(), - } - } else { - comment = format!("Failed to get the year({:?}) or day({:?}) falling back to default", input.year, input.day); - } - quote! { - #[doc = #comment] - const #ident: &str = ""; - } - .into() -} - -/// Same as include_data!, but it only gets data from the example directory. -/// This is useful for testing the examples, even when Data from the AOC is available -#[proc_macro] -pub fn include_example(data: TokenStream) -> TokenStream { - let input = match parse::(data) { - Ok(include) => include, - Err(error) => return error.into_compile_error().into(), - }; - let ident = format_ident!("{}", input.var); - let mut comment: String; - if input.day.is_some() && input.year.is_some() { - comment = "Data from the Example dir".into(); - match canonicalize(EXAMPLE_DIR, input.clone()) { - Some(p) => { - return quote! { - #[doc = #comment] - const #ident: &str = include_str!(#p).trim_ascii(); - } - .into(); - }, - None => comment = "failed to get data from the path".into(), - } - } else { - comment = format!("Failed to get the year({:?}) or day({:?}) falling back to default", input.year, input.day); - } - quote! { - #[doc = #comment] - const #ident: &str = ""; - } - .into() -} - #[derive(Debug, Clone, Default)] -struct NewIncludeData { +struct IncludeData { var: String, year: String, day: String, @@ -162,20 +34,25 @@ struct NewIncludeData { parts: usize, } -impl Parse for NewIncludeData { +impl Parse for IncludeData { fn parse(input: ParseStream) -> Result { let mut v = Self::default(); v.var = if input.peek(Ident) && !input.peek(LitInt) { - get_text(input.parse::().unwrap())? + let t = get_text(input.parse::().unwrap())?; + input.parse::()?; + t } else { VAR_NAME.to_string() }; v.year = get_text(input.parse::()?)?; + input.parse::()?; v.day = get_text(input.parse::()?)?; - if input.peek(LitBool) { + if input.peek2(LitBool) { + input.parse::()?; v.example = input.parse::()?.value; } - if input.peek(LitInt) { + if input.peek2(LitInt) { + input.parse::()?; v.parts = input.parse::()?.base10_parse()?; } if v.parts == 0 { @@ -185,12 +62,12 @@ impl Parse for NewIncludeData { } } -fn fallback(input: NewIncludeData, message: String) -> TokenStream { +fn fallback(input: IncludeData, message: String) -> TokenStream { if input.parts != 1 { let postfixes = (1..=input.parts).map(|i| format_ident!("{}_{}", input.var, i)); quote! { + #[doc = #message] #( - /// const #postfixes: &str = ""; )* } @@ -198,7 +75,7 @@ fn fallback(input: NewIncludeData, message: String) -> TokenStream { } else { let name = format_ident!("{}", input.var); quote! { - /// #name + #[doc = #message] const #name: &str = ""; } .into() @@ -213,7 +90,7 @@ fn fallback(input: NewIncludeData, message: String) -> TokenStream { /// and the last is the amount of parts in the file, if it is greater than 1 the first argument is treated as an Prefix. #[proc_macro] pub fn include_aoc(data: TokenStream) -> TokenStream { - let input = match parse::(data) { + let input = match parse::(data) { Ok(data) => data, Err(error) => return error.into_compile_error().into(), };