Updated lib to allow different output between part 1 and part 2

This commit is contained in:
Dreaded_X 2022-12-10 17:33:17 +01:00
parent 068b675982
commit 225537f364
14 changed files with 167 additions and 149 deletions

View File

@ -14,19 +14,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 24000)
Day::test(Day::part1, "test-1", 24000)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 70116)
Day::test(Day::part1, "input", 70116)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 45000)
Day::test(Day::part2, "test-1", 45000)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 206582)
Day::test(Day::part2, "input", 206582)
}
}
@ -40,24 +40,25 @@ mod bench {
#[bench]
#[ignore]
fn part1_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
1
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
input.split("\n\n")
.map(|elf| elf.lines()
.flat_map(|snack| snack.parse::<u32>())
@ -66,7 +67,7 @@ impl aoc::Solver for Day {
.unwrap()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let mut elfs: Vec<u32> = input.split("\n\n")
.map(|elf| elf.lines()
.flat_map(|snack| snack.parse::<u32>())

View File

@ -13,15 +13,31 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 13140)
Day::test(Day::part1, "test-1", 13140)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 13220)
Day::test(Day::part1, "input", 13220)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", -1)
Day::test(Day::part2, "test-1", r"##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######.....
".to_owned())
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(Day::part2, "input", r"###..#..#..##..#..#.#..#.###..####.#..#.
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#.#..#.#..#.##...####.###..###..##...
###..#..#.####.#.#..#..#.#..#.#....#.#..
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#..##..#..#.#..#.#..#.###..####.#..#.
".to_owned())
}
// Benchmarks
@ -29,12 +45,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -80,12 +96,13 @@ fn parse(input: &str) -> Vec<Instruction> {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = isize;
type Output1 = isize;
type Output2 = String;
fn day() -> u8 {
10
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
let instructions = parse(input);
let mut cpu = CPU::new();
@ -107,31 +124,31 @@ impl aoc::Solver for Day {
sum
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let instructions = parse(input);
let mut cpu = CPU::new();
let mut cycle = 1;
let mut output = "".to_owned();
for instruction in instructions {
let (cycle_count, x) = cpu.execute(&instruction);
for c in 0..cycle_count {
let ccm = (cycle + c - 1) % 40;
let mut sign = ' ';
let mut sign = ".";
if ccm-1 == x || ccm == x || ccm+1 == x {
sign = '#';
sign = "#";
}
print!("{}", sign);
output += sign;
if ccm == 39 {
println!("");
output += "\n";
}
}
cycle += cycle_count;
}
// @TODO Figure out how we return this
0
output
}
}

View File

@ -13,19 +13,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 15)
Day::test(Day::part1, "test-1", 15)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 14264)
Day::test(Day::part1, "input", 14264)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 12)
Day::test(Day::part2, "test-1", 12)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 12382)
Day::test(Day::part2, "input", 12382)
}
}
@ -39,12 +39,12 @@ mod bench {
#[bench]
#[ignore]
fn part1_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -122,19 +122,20 @@ fn calc_score(sum: u32, (a, b): (Hand, Hand)) -> u32 {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
2
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
input.lines()
.filter_map(|round| round.split_once(" "))
.map(|(a, b)| (Hand::from(a), Hand::from(b)))
.fold(0, calc_score)
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
input.lines()
.filter_map(|round| round.split_once(" "))
.map(|(a, b)| {

View File

@ -13,19 +13,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 157)
Day::test(Day::part1, "test-1", 157)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 8298)
Day::test(Day::part1, "input", 8298)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 70)
Day::test(Day::part2, "test-1", 70)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 2708)
Day::test(Day::part2, "input", 2708)
}
}
@ -39,12 +39,12 @@ mod bench {
#[bench]
#[ignore]
fn part1_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -76,12 +76,13 @@ fn find_common(group: &[&str]) -> char {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
3
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
input.lines()
.map(|line| line.split_at(line.len()/2))
.map(|(a, b)| {
@ -97,7 +98,7 @@ impl aoc::Solver for Day {
.sum()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
input.lines()
.collect::<Vec<_>>()
.chunks(3)

View File

@ -14,19 +14,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 2)
Day::test(Day::part1, "test-1", 2)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 567)
Day::test(Day::part1, "input", 567)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 4)
Day::test(Day::part2, "test-1", 4)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 907)
Day::test(Day::part2, "input", 907)
}
}
@ -40,12 +40,12 @@ mod bench {
#[bench]
#[ignore]
fn part1_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -91,12 +91,13 @@ fn transform(s: &str) -> (Elf, Elf) {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
4
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
input
.lines()
.map(transform)
@ -104,7 +105,7 @@ impl aoc::Solver for Day {
.count() as u32
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
input
.lines()
.map(transform)

View File

@ -19,19 +19,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", "CMZ".to_string())
Day::test(Day::part1, "test-1", "CMZ".to_string())
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", "RNZLFZSJH".to_string())
Day::test(Day::part1, "input", "RNZLFZSJH".to_string())
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", "MCD".to_string())
Day::test(Day::part2, "test-1", "MCD".to_string())
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", "CNSFCGJSM".to_string())
Day::test(Day::part2, "input", "CNSFCGJSM".to_string())
}
// Run it on a 6MB file to see how it performs
@ -39,12 +39,12 @@ mod tests {
#[test]
#[ignore]
fn part1_large() -> Result<()> {
Day::test(aoc::Part::ONE, "large", "GATHERING".to_string())
Day::test(Day::part1, "large", "GATHERING".to_string())
}
#[test]
#[ignore]
fn part2_large() -> Result<()> {
Day::test(aoc::Part::TWO, "large", "DEVSCHUUR".to_string())
Day::test(Day::part2, "large", "DEVSCHUUR".to_string())
}
}
@ -58,12 +58,12 @@ mod bench {
#[bench]
#[ignore]
fn part1_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_solution(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -192,16 +192,17 @@ fn solution(input: &str, part1: bool) -> String {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = String;
type Output1 = String;
type Output2 = String;
fn day() -> u8 {
5
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
solution(input, true)
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
solution(input, false)
}
}

View File

@ -13,52 +13,52 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 7)
Day::test(Day::part1, "test-1", 7)
}
#[test]
fn part1_test2() -> Result<()> {
Day::test(aoc::Part::ONE, "test-2", 5)
Day::test(Day::part1, "test-2", 5)
}
#[test]
fn part1_test3() -> Result<()> {
Day::test(aoc::Part::ONE, "test-3", 6)
Day::test(Day::part1, "test-3", 6)
}
#[test]
fn part1_test4() -> Result<()> {
Day::test(aoc::Part::ONE, "test-4", 10)
Day::test(Day::part1, "test-4", 10)
}
#[test]
fn part1_test5() -> Result<()> {
Day::test(aoc::Part::ONE, "test-5", 11)
Day::test(Day::part1, "test-5", 11)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 1275)
Day::test(Day::part1, "input", 1275)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 19)
Day::test(Day::part2, "test-1", 19)
}
#[test]
fn part2_test2() -> Result<()> {
Day::test(aoc::Part::TWO, "test-2", 23)
Day::test(Day::part2, "test-2", 23)
}
#[test]
fn part2_test3() -> Result<()> {
Day::test(aoc::Part::TWO, "test-3", 23)
Day::test(Day::part2, "test-3", 23)
}
#[test]
fn part2_test4() -> Result<()> {
Day::test(aoc::Part::TWO, "test-4", 29)
Day::test(Day::part2, "test-4", 29)
}
#[test]
fn part2_test5() -> Result<()> {
Day::test(aoc::Part::TWO, "test-5", 26)
Day::test(Day::part2, "test-5", 26)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 3605)
Day::test(Day::part2, "input", 3605)
}
// Benchmarks
@ -66,12 +66,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -99,16 +99,17 @@ fn solution(input: &str, length: usize) -> usize {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = usize;
type Output1 = usize;
type Output2 = usize;
fn day() -> u8 {
6
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
solution(input, 4)
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
solution(input, 14)
}
}

View File

@ -14,19 +14,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 95437)
Day::test(Day::part1, "test-1", 95437)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 2031851)
Day::test(Day::part1, "input", 2031851)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 24933642)
Day::test(Day::part2, "test-1", 24933642)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 2568781)
Day::test(Day::part2, "input", 2568781)
}
// Benchmarks
@ -34,12 +34,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -133,12 +133,13 @@ mod implementation {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
7
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
Node::new(input)
.flatten_sizes()
.iter()
@ -146,7 +147,7 @@ impl aoc::Solver for Day {
.sum()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let root = Node::new(input);
let need_to_free = root.get_size() - 40000000;

View File

@ -15,19 +15,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 95437)
Day::test(Day::part1, "test-1", 95437)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 2031851)
Day::test(Day::part1, "input", 2031851)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 24933642)
Day::test(Day::part2, "test-1", 24933642)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 2568781)
Day::test(Day::part2, "input", 2568781)
}
// Benchmarks
@ -35,12 +35,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -76,19 +76,20 @@ fn process(input: &str) -> Vec<u32> {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
7
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
process(input)
.iter()
.filter(|&&size| size < 100000)
.sum()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let mut sizes = process(input);
sizes.sort();

View File

@ -14,19 +14,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 95437)
Day::test(Day::part1, "test-1", 95437)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 2031851)
Day::test(Day::part1, "input", 2031851)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 24933642)
Day::test(Day::part2, "test-1", 24933642)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 2568781)
Day::test(Day::part2, "input", 2568781)
}
// Benchmarks
@ -34,12 +34,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -145,12 +145,13 @@ mod implementation {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = u32;
type Output1 = u32;
type Output2 = u32;
fn day() -> u8 {
7
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
Tree::new(input)
.flatten_sizes()
.iter()
@ -158,7 +159,7 @@ impl aoc::Solver for Day {
.sum()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let tree = Tree::new(input);
let need_to_free = tree.get_size() - 40000000;

View File

@ -16,19 +16,19 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 21)
Day::test(Day::part1, "test-1", 21)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 1845)
Day::test(Day::part1, "input", 1845)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 8)
Day::test(Day::part2, "test-1", 8)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 230112)
Day::test(Day::part2, "input", 230112)
}
// Benchmarks
@ -36,12 +36,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
// -- Helpers --
@ -97,12 +97,13 @@ fn process_1d(input: &Vec<Vec<i32>>) -> Vec<Vec<bool>> {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = usize;
type Output1 = usize;
type Output2 = usize;
fn day() -> u8 {
8
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
let input = parse(input);
let horizontal = process_1d(&input);
@ -111,7 +112,7 @@ impl aoc::Solver for Day {
horizontal.iter().flatten().zip(vertical.iter().flatten()).filter(|(&horizontal, &vertical)| horizontal || vertical).count()
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
let input = parse(input);
let mut score_highest = 0;

View File

@ -16,23 +16,23 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", 13)
Day::test(Day::part1, "test-1", 13)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", 5695)
Day::test(Day::part1, "input", 5695)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", 1)
Day::test(Day::part2, "test-1", 1)
}
#[test]
fn part2_test2() -> Result<()> {
Day::test(aoc::Part::TWO, "test-2", 36)
Day::test(Day::part2, "test-2", 36)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", 2434)
Day::test(Day::part2, "input", 2434)
}
// Benchmarks
@ -40,12 +40,12 @@ mod tests {
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::ONE, b)
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(aoc::Part::TWO, b)
Day::benchmark(Day::part2, b)
}
}
@ -207,16 +207,17 @@ fn solution(input: &str, length: usize) -> usize {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = usize;
type Output1 = usize;
type Output2 = usize;
fn day() -> u8 {
9
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
solution(input, 2)
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
solution(input, 10)
}
}

View File

@ -6,47 +6,35 @@ use std::{fs, fmt::Debug};
use anyhow::{Context, Result};
pub enum Part {
ONE,
TWO
}
pub trait Solver {
type Output: fmt::Display + Debug + PartialEq;
type Output1: fmt::Display + Debug + PartialEq;
type Output2: fmt::Display + Debug + PartialEq;
fn day() -> u8;
fn part1(input: &str) -> Self::Output;
fn part2(input: &str) -> Self::Output;
fn part1(input: &str) -> Self::Output1;
fn part2(input: &str) -> Self::Output2;
fn select(part: Part) -> for<'a> fn(&'a str) -> <Self as Solver>::Output {
match part {
Part::ONE => Self::part1,
Part::TWO => Self::part2,
}
}
fn test(part: Part, name: &str, result: Self::Output) -> Result<()> {
fn test<T: Fn(&str) -> U, U: Debug + PartialEq>(f: T, name: &str, result: U) -> Result<()> {
// Select the right function
// Read the test input
let input = fs::read_to_string(format!("input/{}/{name}", Self::day())).with_context(|| format!("Failed to read '{}' for day {}", name, Self::day()))?;
// Assert that the result matches the expected value
assert_eq!(Self::select(part)(&input), result);
assert_eq!(f(&input), result);
Ok(())
}
fn solve() -> Result<()> {
let input = fs::read_to_string(format!("input/{}/input", Self::day())).with_context(|| format!("Failed to read 'input' for day {}", Self::day()))?;
println!("Part 1: {}", Self::part1(&input));
println!("Part 2: {}", Self::part2(&input));
println!("Part 1:\n{}", Self::part1(&input));
println!("Part 2:\n{}", Self::part2(&input));
Ok(())
}
fn benchmark(part: Part, b: &mut test::Bencher) {
let f = Self::select(part);
fn benchmark<T: Fn(&str) -> U, U: Debug + PartialEq>(f: T, b: &mut test::Bencher) {
let input = fs::read_to_string(format!("input/{}/input", Self::day())).with_context(|| format!("Failed to read 'input' for day {}", Self::day())).unwrap();
b.iter(|| {

View File

@ -13,7 +13,7 @@ mod tests {
#[test]
fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", TEST)
Day::test(Day::part1, "test-1", TEST)
}
// Benchmarks
@ -33,16 +33,18 @@ mod tests {
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output = TYPE;
type Output1 = TYPE;
type Output2 = TYPE;
fn day() -> u8 {
DAY
}
fn part1(input: &str) -> Self::Output {
fn part1(input: &str) -> Self::Output1 {
DEFAULT
}
fn part2(input: &str) -> Self::Output {
fn part2(input: &str) -> Self::Output2 {
DEFAULT
}
}