update macro api

This commit is contained in:
Adam Jeniski 2022-12-04 17:56:26 -05:00
parent cad101cf54
commit ee1a97f61a
6 changed files with 147 additions and 130 deletions

View File

@ -1,16 +1,27 @@
advent_of_code_macro::solve_problem!( type Input = Vec<Vec<i32>>;
day 1,
Input Vec<Vec<i32>>, fn parse(input: &str) -> Input {
parse |input: &str| { input
input.split("\n\n").map(|lines| lines.lines().map(|line| line.parse().unwrap()).collect()).collect() .split("\n\n")
}, .map(|lines| lines.lines().map(|line| line.parse().unwrap()).collect())
part one |data: Input| { .collect()
}
fn part_one(data: Input) -> i32 {
data.iter().map(|cals| cals.iter().sum()).max().unwrap() data.iter().map(|cals| cals.iter().sum()).max().unwrap()
}, }
part two |data: Input| {
let mut cals: std::collections::BinaryHeap<i32> = data.iter().map(|cals| cals.iter().sum()).collect(); fn part_two(data: Input) -> i32 {
let mut cals: std::collections::BinaryHeap<i32> =
data.iter().map(|cals| cals.iter().sum()).collect();
cals.pop().unwrap() + cals.pop().unwrap() + cals.pop().unwrap() cals.pop().unwrap() + cals.pop().unwrap() + cals.pop().unwrap()
}, }
advent_of_code_macro::generate_tests!(
day 1,
parse,
part_one,
part_two,
sample tests [24_000, 45_000], sample tests [24_000, 45_000],
star tests [68_923, 200_044] star tests [68_923, 200_044]
); );

View File

@ -1,5 +1,7 @@
use Shape::*; use Shape::*;
type Input = Vec<Vec<char>>;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
enum Shape { enum Shape {
Rock, Rock,
@ -37,15 +39,15 @@ impl Shape {
} }
} }
} }
fn parse(input: &str) -> Input {
advent_of_code_macro::solve_problem!( input
day 2, .lines()
Input Vec<Vec<char>>, .map(|line| line.split(' ').map(|s| s.chars().next().unwrap()).collect())
parse |input: &str| { .collect()
input.lines().map(|line| line.split(' ').map(|s| s.chars().next().unwrap()).collect()).collect() }
}, fn part_one(data: Input) -> i32 {
part one |data: Input| { data.iter()
data.iter().map(|round| { .map(|round| {
let my_move = Shape::from_char(round[1]); let my_move = Shape::from_char(round[1]);
let other_move = Shape::from_char(round[0]); let other_move = Shape::from_char(round[0]);
let round_result = if my_move == other_move { let round_result = if my_move == other_move {
@ -56,16 +58,25 @@ advent_of_code_macro::solve_problem!(
6 6
}; };
round_result + my_move.as_int() round_result + my_move.as_int()
}).sum() })
}, .sum()
part two |data: Input| { }
data.iter().map(|round| match round[1] { fn part_two(data: Input) -> i32 {
data.iter()
.map(|round| match round[1] {
'X' => Shape::from_char(round[0]).wins_to().as_int(), 'X' => Shape::from_char(round[0]).wins_to().as_int(),
'Y' => Shape::from_char(round[0]).as_int() + 3, 'Y' => Shape::from_char(round[0]).as_int() + 3,
'Z' => Shape::from_char(round[0]).loses_to().as_int() + 6, 'Z' => Shape::from_char(round[0]).loses_to().as_int() + 6,
_ => panic!("expected X, Y, or Z"), _ => panic!("expected X, Y, or Z"),
}).sum() })
}, .sum()
}
advent_of_code_macro::generate_tests!(
day 2,
parse,
part_one,
part_two,
sample tests [15, 12], sample tests [15, 12],
star tests [11063, 10349] star tests [11063, 10349]
); );

View File

@ -1,3 +1,5 @@
type Input = Vec<String>;
fn get_priority(c: char) -> i32 { fn get_priority(c: char) -> i32 {
match c { match c {
'a'..='z' => c as i32 - 'a' as i32 + 1, 'a'..='z' => c as i32 - 'a' as i32 + 1,
@ -5,27 +7,20 @@ fn get_priority(c: char) -> i32 {
_ => panic!("expected letter"), _ => panic!("expected letter"),
} }
} }
fn parse(input: &str) -> Input {
advent_of_code_macro::solve_problem!(
day 3,
Input Vec<String>,
parse |input: &str| {
input.lines().map(str::to_owned).collect() input.lines().map(str::to_owned).collect()
}, }
part one |data: Input| { fn part_one(data: Input) -> i32 {
data.iter() data.iter()
.map(|s| { .map(|s| {
use std::collections::HashSet; use std::collections::HashSet;
let (left, right) = s.split_at(s.len() / 2); let (left, right) = s.split_at(s.len() / 2);
let right_set: HashSet<char> = right.chars().collect(); let right_set: HashSet<char> = right.chars().collect();
get_priority( get_priority(left.chars().find(|c| right_set.contains(c)).unwrap())
left.chars() })
.find(|c| right_set.contains(c)) .sum()
.unwrap(), }
) fn part_two(data: Input) -> i32 {
}).sum()
},
part two |data: Input| {
data.as_slice() data.as_slice()
.chunks(3) .chunks(3)
.map(|c| { .map(|c| {
@ -39,7 +34,13 @@ advent_of_code_macro::solve_problem!(
) )
}) })
.sum() .sum()
}, }
advent_of_code_macro::generate_tests!(
day 3,
parse,
part_one,
part_two,
sample tests [157, 70], sample tests [157, 70],
star tests [7908, 2838] star tests [7908, 2838]
); );

View File

@ -1,42 +1,49 @@
advent_of_code_macro::solve_problem!( type Input = Vec<Vec<i32>>;
day 4,
Input Vec<Vec<i32>>, fn parse(input: &str) -> Input {
parse |input: &str| { input
input.lines() .lines()
.map(|line| { .map(|line| {
let (a, rest) = line.split_once('-').unwrap(); let (a, rest) = line.split_once('-').unwrap();
let (b, rest) = rest.split_once(',').unwrap(); let (b, rest) = rest.split_once(',').unwrap();
let (c, d) = rest.split_once('-').unwrap(); let (c, d) = rest.split_once('-').unwrap();
[a, b, c, d].into_iter() [a, b, c, d]
.into_iter()
.map(str::parse) .map(str::parse)
.map(Result::unwrap) .map(Result::unwrap)
.collect() .collect()
}).collect() })
}, .collect()
part one |data: Input| { }
data.into_iter() fn part_one(data: Input) -> i32 {
.fold(0, |acc, curr| data.into_iter().fold(0, |acc, curr| {
if (curr[0] <= curr[2] && curr[1] >= curr[3]) if (curr[0] <= curr[2] && curr[1] >= curr[3]) || (curr[2] <= curr[0] && curr[3] >= curr[1])
|| (curr[2] <= curr[0] && curr[3] >= curr[1]) { {
acc + 1 acc + 1
} else { } else {
acc acc
} }
) })
}, }
part two |data: Input| { fn part_two(data: Input) -> i32 {
data.into_iter() data.into_iter().fold(0, |acc, curr| {
.fold(0, |acc, curr|
if (curr[0] >= curr[2] && curr[0] <= curr[3]) if (curr[0] >= curr[2] && curr[0] <= curr[3])
|| (curr[1] >= curr[2] && curr[1] <= curr[3]) || (curr[1] >= curr[2] && curr[1] <= curr[3])
|| (curr[2] >= curr[0] && curr[2] <= curr[1]) || (curr[2] >= curr[0] && curr[2] <= curr[1])
|| (curr[3] >= curr[0] && curr[3] <= curr[1]) { || (curr[3] >= curr[0] && curr[3] <= curr[1])
{
acc + 1 acc + 1
} else { } else {
acc acc
} }
) })
}, }
advent_of_code_macro::generate_tests!(
day 4,
parse,
part_one,
part_two,
sample tests [2, 4], sample tests [2, 4],
star tests [450, 837] star tests [450, 837]
); );

View File

@ -1,6 +1,6 @@
[package] [package]
name = "advent_of_code_macro" name = "advent_of_code_macro"
version = "0.1.1" version = "0.1.2"
edition = "2021" edition = "2021"
description = "An test generating macro for advent of code" description = "An test generating macro for advent of code"
license = "MIT" license = "MIT"

View File

@ -1,55 +1,42 @@
#[macro_export] #[macro_export]
macro_rules! solve_problem { macro_rules! generate_tests {
(day $day:literal, (day $day:literal,
Input $input_type:ty, $parse_input:ident,
parse $parse_input:expr, $part_one:ident,
part one $part_one:expr, $part_two:ident,
part two $part_two:expr,
sample tests [$part_one_sample_ans:literal, $part_two_sample_ans:literal], sample tests [$part_one_sample_ans:literal, $part_two_sample_ans:literal],
star tests [$part_one_ans:literal, $part_two_ans:literal]) => { star tests [$part_one_ans:literal, $part_two_ans:literal]) => {
#[cfg(test)] #[cfg(test)]
paste::paste! { paste::paste! {
mod [<day_ $day _tests>] { mod [<day_ $day _tests>] {
use super::*; use super::{$parse_input, $part_one, $part_two};
type Input = $input_type;
fn parse_input(s: &str) -> Input {
$parse_input(s)
}
fn part_one_solution(data: Input) -> i32 {
$part_one(data)
}
fn part_two_solution(data: Input) -> i32 {
$part_two(data)
}
#[test] #[test]
fn part_one_sample() { fn part_one_sample() {
let input = include_str!(concat!("../input/day_", $day, "_sample.txt")); let input = include_str!(concat!("../input/day_", $day, "_sample.txt"));
let data = parse_input(input); let data = $parse_input(input);
assert_eq!($part_one_sample_ans, part_one_solution(data)); assert_eq!($part_one_sample_ans, $part_one(data));
} }
#[test] #[test]
fn part_one() { fn part_one_star() {
let input = include_str!(concat!("../input/day_", $day, ".txt")); let input = include_str!(concat!("../input/day_", $day, ".txt"));
let data = parse_input(input); let data = $parse_input(input);
assert_eq!($part_one_ans, part_one_solution(data)); assert_eq!($part_one_ans, $part_one(data));
} }
#[test] #[test]
fn part_two_sample() { fn part_two_sample() {
let input = include_str!(concat!("../input/day_", $day, "_sample.txt")); let input = include_str!(concat!("../input/day_", $day, "_sample.txt"));
let data = parse_input(input); let data = $parse_input(input);
assert_eq!($part_two_sample_ans, part_two_solution(data)); assert_eq!($part_two_sample_ans, $part_two(data));
} }
#[test] #[test]
fn part_two() { fn part_two_star() {
let input = include_str!(concat!("../input/day_", $day, ".txt")); let input = include_str!(concat!("../input/day_", $day, ".txt"));
let data = parse_input(input); let data = $parse_input(input);
assert_eq!($part_two_ans, part_two_solution(data)); assert_eq!($part_two_ans, $part_two(data));
} }
} }
} }