mirror of
https://github.com/Ajetski/advent-of-code.git
synced 2025-09-30 07:03:19 -09:00
update macro api
This commit is contained in:
parent
cad101cf54
commit
ee1a97f61a
@ -1,16 +1,27 @@
|
|||||||
advent_of_code_macro::solve_problem!(
|
type Input = Vec<Vec<i32>>;
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
input
|
||||||
|
.split("\n\n")
|
||||||
|
.map(|lines| lines.lines().map(|line| line.parse().unwrap()).collect())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_one(data: Input) -> i32 {
|
||||||
|
data.iter().map(|cals| cals.iter().sum()).max().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
advent_of_code_macro::generate_tests!(
|
||||||
day 1,
|
day 1,
|
||||||
Input Vec<Vec<i32>>,
|
parse,
|
||||||
parse |input: &str| {
|
part_one,
|
||||||
input.split("\n\n").map(|lines| lines.lines().map(|line| line.parse().unwrap()).collect()).collect()
|
part_two,
|
||||||
},
|
|
||||||
part one |data: Input| {
|
|
||||||
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();
|
|
||||||
cals.pop().unwrap() + cals.pop().unwrap() + cals.pop().unwrap()
|
|
||||||
},
|
|
||||||
sample tests [24_000, 45_000],
|
sample tests [24_000, 45_000],
|
||||||
star tests [68_923, 200_044]
|
star tests [68_923, 200_044]
|
||||||
);
|
);
|
||||||
|
@ -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 {
|
||||||
'X' => Shape::from_char(round[0]).wins_to().as_int(),
|
data.iter()
|
||||||
'Y' => Shape::from_char(round[0]).as_int() + 3,
|
.map(|round| match round[1] {
|
||||||
'Z' => Shape::from_char(round[0]).loses_to().as_int() + 6,
|
'X' => Shape::from_char(round[0]).wins_to().as_int(),
|
||||||
|
'Y' => Shape::from_char(round[0]).as_int() + 3,
|
||||||
|
'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]
|
||||||
);
|
);
|
||||||
|
@ -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,41 +7,40 @@ fn get_priority(c: char) -> i32 {
|
|||||||
_ => panic!("expected letter"),
|
_ => panic!("expected letter"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
input.lines().map(str::to_owned).collect()
|
||||||
|
}
|
||||||
|
fn part_one(data: Input) -> i32 {
|
||||||
|
data.iter()
|
||||||
|
.map(|s| {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
let (left, right) = s.split_at(s.len() / 2);
|
||||||
|
let right_set: HashSet<char> = right.chars().collect();
|
||||||
|
get_priority(left.chars().find(|c| right_set.contains(c)).unwrap())
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
fn part_two(data: Input) -> i32 {
|
||||||
|
data.as_slice()
|
||||||
|
.chunks(3)
|
||||||
|
.map(|c| {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
let second_set: HashSet<char> = c[1].chars().collect();
|
||||||
|
let third_set: HashSet<char> = c[2].chars().collect();
|
||||||
|
get_priority(
|
||||||
|
c[0].chars()
|
||||||
|
.find(|c| second_set.contains(c) && third_set.contains(c))
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
advent_of_code_macro::solve_problem!(
|
advent_of_code_macro::generate_tests!(
|
||||||
day 3,
|
day 3,
|
||||||
Input Vec<String>,
|
parse,
|
||||||
parse |input: &str| {
|
part_one,
|
||||||
input.lines().map(str::to_owned).collect()
|
part_two,
|
||||||
},
|
|
||||||
part one |data: Input| {
|
|
||||||
data.iter()
|
|
||||||
.map(|s| {
|
|
||||||
use std::collections::HashSet;
|
|
||||||
let (left, right) = s.split_at(s.len() / 2);
|
|
||||||
let right_set: HashSet<char> = right.chars().collect();
|
|
||||||
get_priority(
|
|
||||||
left.chars()
|
|
||||||
.find(|c| right_set.contains(c))
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
}).sum()
|
|
||||||
},
|
|
||||||
part two |data: Input| {
|
|
||||||
data.as_slice()
|
|
||||||
.chunks(3)
|
|
||||||
.map(|c| {
|
|
||||||
use std::collections::HashSet;
|
|
||||||
let second_set: HashSet<char> = c[1].chars().collect();
|
|
||||||
let third_set: HashSet<char> = c[2].chars().collect();
|
|
||||||
get_priority(
|
|
||||||
c[0].chars()
|
|
||||||
.find(|c| second_set.contains(c) && third_set.contains(c))
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.sum()
|
|
||||||
},
|
|
||||||
sample tests [157, 70],
|
sample tests [157, 70],
|
||||||
star tests [7908, 2838]
|
star tests [7908, 2838]
|
||||||
);
|
);
|
||||||
|
@ -1,42 +1,49 @@
|
|||||||
advent_of_code_macro::solve_problem!(
|
type Input = Vec<Vec<i32>>;
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let (a, rest) = line.split_once('-').unwrap();
|
||||||
|
let (b, rest) = rest.split_once(',').unwrap();
|
||||||
|
let (c, d) = rest.split_once('-').unwrap();
|
||||||
|
[a, b, c, d]
|
||||||
|
.into_iter()
|
||||||
|
.map(str::parse)
|
||||||
|
.map(Result::unwrap)
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
fn part_one(data: Input) -> i32 {
|
||||||
|
data.into_iter().fold(0, |acc, curr| {
|
||||||
|
if (curr[0] <= curr[2] && curr[1] >= curr[3]) || (curr[2] <= curr[0] && curr[3] >= curr[1])
|
||||||
|
{
|
||||||
|
acc + 1
|
||||||
|
} else {
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn part_two(data: Input) -> i32 {
|
||||||
|
data.into_iter().fold(0, |acc, curr| {
|
||||||
|
if (curr[0] >= curr[2] && curr[0] <= curr[3])
|
||||||
|
|| (curr[1] >= curr[2] && curr[1] <= curr[3])
|
||||||
|
|| (curr[2] >= curr[0] && curr[2] <= curr[1])
|
||||||
|
|| (curr[3] >= curr[0] && curr[3] <= curr[1])
|
||||||
|
{
|
||||||
|
acc + 1
|
||||||
|
} else {
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
advent_of_code_macro::generate_tests!(
|
||||||
day 4,
|
day 4,
|
||||||
Input Vec<Vec<i32>>,
|
parse,
|
||||||
parse |input: &str| {
|
part_one,
|
||||||
input.lines()
|
part_two,
|
||||||
.map(|line| {
|
|
||||||
let (a, rest) = line.split_once('-').unwrap();
|
|
||||||
let (b, rest) = rest.split_once(',').unwrap();
|
|
||||||
let (c, d) = rest.split_once('-').unwrap();
|
|
||||||
[a, b, c, d].into_iter()
|
|
||||||
.map(str::parse)
|
|
||||||
.map(Result::unwrap)
|
|
||||||
.collect()
|
|
||||||
}).collect()
|
|
||||||
},
|
|
||||||
part one |data: Input| {
|
|
||||||
data.into_iter()
|
|
||||||
.fold(0, |acc, curr|
|
|
||||||
if (curr[0] <= curr[2] && curr[1] >= curr[3])
|
|
||||||
|| (curr[2] <= curr[0] && curr[3] >= curr[1]) {
|
|
||||||
acc + 1
|
|
||||||
} else {
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
part two |data: Input| {
|
|
||||||
data.into_iter()
|
|
||||||
.fold(0, |acc, curr|
|
|
||||||
if (curr[0] >= curr[2] && curr[0] <= curr[3])
|
|
||||||
|| (curr[1] >= curr[2] && curr[1] <= curr[3])
|
|
||||||
|| (curr[2] >= curr[0] && curr[2] <= curr[1])
|
|
||||||
|| (curr[3] >= curr[0] && curr[3] <= curr[1]) {
|
|
||||||
acc + 1
|
|
||||||
} else {
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
sample tests [2, 4],
|
sample tests [2, 4],
|
||||||
star tests [450, 837]
|
star tests [450, 837]
|
||||||
);
|
);
|
||||||
|
@ -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"
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user