Even better way to have different return types, also added script to setup template
This commit is contained in:
parent
5554cfedb3
commit
ee9dcc92c1
|
@ -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
15
2022/new.sh
Executable 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!"
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user