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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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