Even better way to have different return types, also added script to setup template

This commit is contained in:
Dreaded_X 2022-12-06 01:26:17 +01:00
parent 5554cfedb3
commit ee9dcc92c1
Signed by: Dreaded_X
GPG Key ID: 76BDEC4E165D8AD9
9 changed files with 87 additions and 102 deletions

View File

@ -1,4 +0,0 @@
#!/bin/bash
source ../.env
mkdir -p input/$1
curl "https://adventofcode.com/2022/day/$1/input" -H "Cookie: session=${SESSION}" > input/$1/input

15
2022/new.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
day=$1
type=$2
default=$3
test=$4
echo "Creating file from template..."
sed -e "s/DAY/$day/g" -e "s/TYPE/$type/" -e "s/DEFAULT/$default/" -e "s/TEST/$test/" ./template.rs > ./src/bin/day${day}.rs
echo "Downloading input..."
source ../.env
mkdir -p input/$1
curl -s "https://adventofcode.com/2022/day/$1/input" -H "Cookie: session=${SESSION}" > input/$1/input
echo "Done!"

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -12,41 +12,40 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::Number(24000)) Day::test(aoc::Part::ONE, "test-1", 24000)
} }
#[test] #[test]
fn part2_test1() -> Result<()> { fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", Output::Number(45000)) Day::test(aoc::Part::TWO, "test-1", 45000)
} }
#[test] #[test]
fn part1_solution() -> Result<()> { fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", Output::Number(70116)) Day::test(aoc::Part::ONE, "input", 70116)
} }
#[test] #[test]
fn part2_solution() -> Result<()> { fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", Output::Number(206582)) Day::test(aoc::Part::TWO, "input", 206582)
} }
} }
// -- Solution -- // -- Solution --
pub struct Day; pub struct Day;
impl aoc::Solver for Day { impl aoc::Solver for Day {
type Output = u32;
fn day() -> u8 { fn day() -> u8 {
1 1
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
let result = 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>())
.sum()) .sum())
.max() .max()
.unwrap(); .unwrap()
Output::Number(result)
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
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>())
@ -55,8 +54,6 @@ impl aoc::Solver for Day {
elfs.sort_by(|a, b| b.cmp(a)); elfs.sort_by(|a, b| b.cmp(a));
let result = elfs.iter().take(3).sum(); elfs.iter().take(3).sum()
Output::Number(result)
} }
} }

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -12,19 +12,19 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::Number(15)) Day::test(aoc::Part::ONE, "test-1", 15)
} }
#[test] #[test]
fn part2_test1() -> Result<()> { fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", Output::Number(12)) Day::test(aoc::Part::TWO, "test-1", 12)
} }
#[test] #[test]
fn part1_solution() -> Result<()> { fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", Output::Number(14264)) Day::test(aoc::Part::ONE, "input", 14264)
} }
#[test] #[test]
fn part2_solution() -> Result<()> { fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", Output::Number(12382)) Day::test(aoc::Part::TWO, "input", 12382)
} }
} }
@ -102,28 +102,25 @@ 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;
fn day() -> u8 { fn day() -> u8 {
2 2
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
let result = 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)
Output::Number(result)
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
let result = input.lines() input.lines()
.filter_map(|round| round.split_once(" ")) .filter_map(|round| round.split_once(" "))
.map(|(a, b)| { .map(|(a, b)| {
let opponent = Hand::from(a); let opponent = Hand::from(a);
(opponent, opponent.strategy(b)) (opponent, opponent.strategy(b))
}) })
.fold(0, calc_score); .fold(0, calc_score)
Output::Number(result)
} }
} }

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -12,19 +12,19 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::Number(157)) Day::test(aoc::Part::ONE, "test-1", 157)
} }
#[test] #[test]
fn part2_test1() -> Result<()> { fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", Output::Number(70)) Day::test(aoc::Part::TWO, "test-1", 70)
} }
#[test] #[test]
fn part1_solution() -> Result<()> { fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", Output::Number(8298)) Day::test(aoc::Part::ONE, "input", 8298)
} }
#[test] #[test]
fn part2_solution() -> Result<()> { fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", Output::Number(2708)) Day::test(aoc::Part::TWO, "input", 2708)
} }
} }
@ -56,12 +56,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;
fn day() -> u8 { fn day() -> u8 {
3 3
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
let result = 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)| {
for c in a.chars() { for c in a.chars() {
@ -73,19 +74,15 @@ impl aoc::Solver for Day {
unreachable!("No characters in common, this should never happen") unreachable!("No characters in common, this should never happen")
}) })
.map(convert) .map(convert)
.sum(); .sum()
Output::Number(result)
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
let result = input.lines() input.lines()
.collect::<Vec<_>>() .collect::<Vec<_>>()
.chunks(3) .chunks(3)
.map(find_common) .map(find_common)
.map(convert) .map(convert)
.sum(); .sum()
Output::Number(result)
} }
} }

View File

@ -1,6 +1,6 @@
use std::cmp; use std::cmp;
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -13,19 +13,19 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::Number(2)) Day::test(aoc::Part::ONE, "test-1", 2)
} }
#[test] #[test]
fn part2_test1() -> Result<()> { fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", Output::Number(4)) Day::test(aoc::Part::TWO, "test-1", 4)
} }
#[test] #[test]
fn part1_solution() -> Result<()> { fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", Output::Number(567)) Day::test(aoc::Part::ONE, "input", 567)
} }
#[test] #[test]
fn part2_solution() -> Result<()> { fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", Output::Number(907)) Day::test(aoc::Part::TWO, "input", 907)
} }
} }
@ -72,27 +72,24 @@ 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;
fn day() -> u8 { fn day() -> u8 {
4 4
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
let result = input input
.lines() .lines()
.map(transform) .map(transform)
.filter(contains) .filter(contains)
.count() as u32; .count() as u32
Output::Number(result)
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
let result = input input
.lines() .lines()
.map(transform) .map(transform)
.filter(overlaps) .filter(overlaps)
.count() as u32; .count() as u32
Output::Number(result)
} }
} }

View File

@ -4,7 +4,7 @@ use lazy_static::lazy_static;
use regex::Regex; use regex::Regex;
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -17,19 +17,19 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::String("CMZ".to_string())) Day::test(aoc::Part::ONE, "test-1", "CMZ".to_string())
} }
#[test] #[test]
fn part2_test1() -> Result<()> { fn part2_test1() -> Result<()> {
Day::test(aoc::Part::TWO, "test-1", Output::String("MCD".to_string())) Day::test(aoc::Part::TWO, "test-1", "MCD".to_string())
} }
#[test] #[test]
fn part1_solution() -> Result<()> { fn part1_solution() -> Result<()> {
Day::test(aoc::Part::ONE, "input", Output::String("RNZLFZSJH".to_string())) Day::test(aoc::Part::ONE, "input", "RNZLFZSJH".to_string())
} }
#[test] #[test]
fn part2_solution() -> Result<()> { fn part2_solution() -> Result<()> {
Day::test(aoc::Part::TWO, "input", Output::String("CNSFCGJSM".to_string())) Day::test(aoc::Part::TWO, "input", "CNSFCGJSM".to_string())
} }
} }
@ -123,7 +123,7 @@ fn parse_instruction(s: &str) -> (usize, usize, usize) {
(amount, from, to) (amount, from, to)
} }
fn solution(input: &str, reverse: bool) -> Output { fn solution(input: &str, reverse: bool) -> String {
// The current layout description ends with an empty line // The current layout description ends with an empty line
let mut boat = Boat::new(&input let mut boat = Boat::new(&input
.lines() .lines()
@ -145,21 +145,22 @@ fn solution(input: &str, reverse: bool) -> Output {
boat.put(to, taken); boat.put(to, taken);
}); });
Output::String(boat.to_string()) boat.to_string()
} }
// -- Solution -- // -- Solution --
pub struct Day; pub struct Day;
impl aoc::Solver for Day { impl aoc::Solver for Day {
type Output = String;
fn day() -> u8 { fn day() -> u8 {
5 5
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
solution(input, true) solution(input, true)
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
solution(input, false) solution(input, false)
} }
} }

View File

@ -1,5 +1,5 @@
use core::fmt; use core::fmt;
use std::fs; use std::{fs, fmt::Debug};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -8,30 +8,14 @@ pub enum Part {
TWO TWO
} }
#[derive(Debug,PartialEq, PartialOrd)]
pub enum Output {
Number(u32),
String(String),
}
impl fmt::Display for Output {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Output::Number(i) => write!(f, "{}", i)?,
Output::String(s) => write!(f, "{}", s)?,
_ => panic!("fmt::Display not implemented")
}
Ok(())
}
}
pub trait Solver { pub trait Solver {
fn day() -> u8; type Output: fmt::Display + Debug + PartialEq;
fn part1(input: &str) -> Output;
fn part2(input: &str) -> Output;
fn test(part: Part, name: &str, result: Output) -> Result<()> { fn day() -> u8;
fn part1(input: &str) -> Self::Output;
fn part2(input: &str) -> Self::Output;
fn test(part: Part, name: &str, result: Self::Output) -> Result<()> {
// Select the right function // Select the right function
let fun = match part { let fun = match part {
Part::ONE => Self::part1, Part::ONE => Self::part1,

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use aoc::{Solver, Output}; use aoc::Solver;
// -- Runners -- // -- Runners --
fn main() -> Result<()> { fn main() -> Result<()> {
@ -12,22 +12,23 @@ mod tests {
#[test] #[test]
fn part1_test1() -> Result<()> { fn part1_test1() -> Result<()> {
Day::test(aoc::Part::ONE, "test-1", Output::Number(0)) Day::test(aoc::Part::ONE, "test-1", TEST)
} }
} }
// -- Solution -- // -- Solution --
pub struct Day; pub struct Day;
impl aoc::Solver for Day { impl aoc::Solver for Day {
type Output = TYPE;
fn day() -> u8 { fn day() -> u8 {
todo!("Day not set") DAY
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Self::Output {
Output::Number(0) DEFAULT
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Self::Output {
Output::Number(0) DEFAULT
} }
} }