Setup for 2023

This commit is contained in:
Dreaded_X 2023-12-01 11:12:56 +01:00
parent ea51fd11fe
commit 1b597ec05f
Signed by: Dreaded_X
GPG Key ID: 5A0CBFE3C3377FAA
5 changed files with 143 additions and 0 deletions

21
2023/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# Created by https://www.toptal.com/developers/gitignore/api/rust
# Edit at https://www.toptal.com/developers/gitignore?templates=rust
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# End of https://www.toptal.com/developers/gitignore/api/rust

11
2023/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "aoc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.75"
[features]

15
2023/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/2023/day/$1/input" -H "Cookie: session=${SESSION}" > input/$1/input
echo "Done!"

46
2023/src/lib.rs Normal file
View File

@ -0,0 +1,46 @@
#![feature(test)]
extern crate test;
use core::fmt;
use std::{fmt::Debug, fs};
use anyhow::{Context, Result};
pub trait Solver {
type Output1: fmt::Display + Debug + PartialEq;
type Output2: fmt::Display + Debug + PartialEq;
fn day() -> u8;
fn part1(input: &str) -> Self::Output1;
fn part2(input: &str) -> Self::Output2;
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/{:02}/{name}", Self::day()))
.with_context(|| format!("Failed to read '{}' for day {:02}", name, Self::day()))?;
// Assert that the result matches the expected value
assert_eq!(f(&input), result);
Ok(())
}
fn solve() -> Result<()> {
let input = fs::read_to_string(format!("input/{:02}/input", Self::day()))
.with_context(|| format!("Failed to read 'input' for day {:02}", Self::day()))?;
println!("Part 1:\n{}", Self::part1(&input));
println!("Part 2:\n{}", Self::part2(&input));
Ok(())
}
fn benchmark<T: Fn(&str) -> U, U: Debug + PartialEq>(f: T, b: &mut test::Bencher) {
let input = fs::read_to_string(format!("input/{:02}/input", Self::day()))
.with_context(|| format!("Failed to read 'input' for day {:02}", Self::day()))
.unwrap();
b.iter(|| f(&input));
}
}

50
2023/template.rs Normal file
View File

@ -0,0 +1,50 @@
#![feature(test)]
use anyhow::Result;
use aoc::Solver;
// -- Runners --
fn main() -> Result<()> {
Day::solve()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_test1() -> Result<()> {
Day::test(Day::part1, "test-1", TEST)
}
// Benchmarks
extern crate test;
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(Day::part2, b)
}
}
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output1 = TYPE;
type Output2 = TYPE;
fn day() -> u8 {
DAY
}
fn part1(input: &str) -> Self::Output1 {
DEFAULT
}
fn part2(input: &str) -> Self::Output2 {
DEFAULT
}
}