Maybe ready for 2023?

This commit is contained in:
Daniel Flanagan 2023-11-28 23:36:58 -06:00
parent bba1059869
commit 81ee8fecda
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
14 changed files with 394 additions and 0 deletions

30
2023/fetch-input.sh Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env sh
AOC_YEAR="${AOC_YEAR:-2023}"
if [ "$#" -lt 1 ]; then
echo "Error: No day provided"
exit 1
fi
DAY="$1"
f="$HOME/.cache/aoc$AOC_YEAR/$DAY.input"
if [ -f "$f" ]; then
echo "Skip: File already exists"
exit 0
fi
url="https://adventofcode.com/$AOC_YEAR/day/$DAY/input"
cookie_file="$HOME/.advent-of-code-session-cookie"
if [[ ! -f "$cookie_file" ]]; then
echo "Cookie file not found: $cookie_file"
exit 1
fi
cookie="$(cat "$cookie_file")"
mkdir -p "$(dirname "$f")"
if curl -s --fail-with-body -X GET "$url" -H "Cookie:$cookie" > "$f"; then
cat "$f"
echo "Downloaded $url to $f - contents have been output to this terminal as well"
exit 0
else
echo "Error: curl failed (are you sure the input is available now?)"
rm -f "$f"
exit 1
fi

1
2023/nim/.envrc Normal file
View file

@ -0,0 +1 @@
use flake

1
2023/nim/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/.direnv

27
2023/nim/flake.lock Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1700390070,
"narHash": "sha256-de9KYi8rSJpqvBfNwscWdalIJXPo8NjdIZcEJum1mH0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

20
2023/nim/flake.nix Normal file
View file

@ -0,0 +1,20 @@
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs?rev=e4ad989506ec7d71f7302cc3067abd82730a4beb";
outputs = {
self,
nixpkgs,
}: let
supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];
forEachSupportedSystem = f:
nixpkgs.lib.genAttrs supportedSystems (system:
f {
pkgs = import nixpkgs {inherit system;};
});
in {
devShells = forEachSupportedSystem ({pkgs}: {
default = pkgs.mkShell {
buildInputs = with pkgs; [nim nimble-unwrapped nimlsp];
};
});
};
}

1
2023/rust/.envrc Normal file
View file

@ -0,0 +1 @@
use flake

3
2023/rust/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/target
/.direnv

7
2023/rust/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aoc2023"
version = "1.0.0"

105
2023/rust/Cargo.toml Normal file
View file

@ -0,0 +1,105 @@
[package]
name = "aoc2023"
version = "1.0.0"
[[bin]]
name = "day1"
path = "src/day1.rs"
[[bin]]
name = "day2"
path = "src/day2.rs"
[[bin]]
name = "day3"
path = "src/day3.rs"
[[bin]]
name = "day4"
path = "src/day4.rs"
[[bin]]
name = "day5"
path = "src/day5.rs"
[[bin]]
name = "day6"
path = "src/day6.rs"
[[bin]]
name = "day7"
path = "src/day7.rs"
[[bin]]
name = "day8"
path = "src/day8.rs"
[[bin]]
name = "day9"
path = "src/day9.rs"
[[bin]]
name = "day10"
path = "src/day10.rs"
[[bin]]
name = "day11"
path = "src/day11.rs"
[[bin]]
name = "day12"
path = "src/day12.rs"
[[bin]]
name = "day13"
path = "src/day13.rs"
[[bin]]
name = "day14"
path = "src/day14.rs"
[[bin]]
name = "day15"
path = "src/day15.rs"
[[bin]]
name = "day16"
path = "src/day16.rs"
[[bin]]
name = "day17"
path = "src/day17.rs"
[[bin]]
name = "day18"
path = "src/day18.rs"
[[bin]]
name = "day19"
path = "src/day19.rs"
[[bin]]
name = "day20"
path = "src/day20.rs"
[[bin]]
name = "day21"
path = "src/day21.rs"
[[bin]]
name = "day22"
path = "src/day22.rs"
[[bin]]
name = "day23"
path = "src/day23.rs"
[[bin]]
name = "day24"
path = "src/day24.rs"
[[bin]]
name = "day25"
path = "src/day25.rs"
[dependencies]

27
2023/rust/flake.lock Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1700390070,
"narHash": "sha256-de9KYi8rSJpqvBfNwscWdalIJXPo8NjdIZcEJum1mH0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

27
2023/rust/flake.nix Normal file
View file

@ -0,0 +1,27 @@
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs?rev=e4ad989506ec7d71f7302cc3067abd82730a4beb";
outputs = {
self,
nixpkgs,
}: let
supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];
forEachSupportedSystem = f:
nixpkgs.lib.genAttrs supportedSystems (system:
f {
pkgs = import nixpkgs {inherit system;};
});
in {
devShells = forEachSupportedSystem ({pkgs}: {
default = pkgs.mkShell {
buildInputs = with pkgs; [
cargo
rustc
rustfmt
rustPackages.clippy
rust-analyzer
curl
];
};
});
};
}

43
2023/rust/readme.md Normal file
View file

@ -0,0 +1,43 @@
# Rust Advent of Code 2023 Solutions
## Competing
I compete very lightly. I use [my `at` script][at] like `at 2022-12-02 && ../
fetch-input.sh 2` to fetch input as soon as it's available and I use `watchexec
-e rs 'clear; cargo test --bin day2 && cargo run --bin day2'` to run my file(s)
as I edit them.
## Running
### Debug
```bash
cargo run --bin day1
```
### Tests
```bash
cargo test --bin day1
```
### Release Mode
For speeeeeed!
```bash
cargo build --release --bin day1
time ./target/release/day1
```
### Everything
You can use this `fish` script to build all binaries in release mode and run/
time them all:
```fish
cargo build --release --bins
time for f in (fd 'day.' target/release/ --type executable --max-depth 1); echo $f; time $f; end
```
[at]: https://git.lyte.dev/lytedev/nix/src/branch/main/modules/home-manager/scripts/common/bin/at

33
2023/rust/src/day1.rs Normal file
View file

@ -0,0 +1,33 @@
use crate::prelude::*;
mod prelude;
fn main() {
Day1::show(day_input(1), day_input(1))
}
struct Day1 {}
impl AoCSolution for Day1 {
type Input = String;
type Solution = i128;
fn part1(input: Self::Input) -> Self::Solution {
println!("{}", input);
return 1;
}
fn part2(_input: Self::Input) -> Self::Solution {
return 0;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
assert_eq!(Day1::part1("asdf".into()), 1);
assert_eq!(Day1::part2("asdf".into()), 2);
}
}

69
2023/rust/src/prelude.rs Normal file
View file

@ -0,0 +1,69 @@
pub use std::fs::File;
pub use std::io::Read;
use std::path::{Path, PathBuf};
use std::{env, io};
pub type Reader = Box<dyn Read>;
#[derive(Debug)]
enum InputFileError {
VarError(env::VarError),
IoError(io::Error),
}
/// Ensures that the input file exists
fn ensure_input_file(day: u8) -> Result<PathBuf, InputFileError> {
let path = Path::new(&env::var("HOME").map_err(InputFileError::VarError)?)
.join(format!("./.cache/aoc2023/{0}.input", day));
if !path.exists() {
eprintln!("Running input downloaded script with day arg {}...", day);
std::process::Command::new("sh")
.args(["../fetch-input.sh", &day.to_string()])
.status()
.map_err(InputFileError::IoError)?;
}
Ok(path)
}
/// Useful when you simply want the day's input as a String.
pub fn day_input(day: u8) -> String {
let mut buffer = String::new();
day_input_file(day)
.read_to_string(&mut buffer)
.expect(&format!("invalid utf8 input for day {}", day));
buffer
}
/// Useful when you want the day's input for streaming for maximum performance nonsense
pub fn day_input_file(day: u8) -> File {
let f = ensure_input_file(day).expect(&format!("Failed to ensure input for day {}", day));
File::open(&f).expect(format!("Failed to open file {}", f.display()).as_str())
}
pub trait AoCSolution {
type Input;
type Solution: std::fmt::Debug + std::cmp::PartialEq + std::fmt::Display;
// Are part1 and part2 solutions _always_ the same?
fn part1(input: Self::Input) -> Self::Solution;
fn part2(input: Self::Input) -> Self::Solution;
fn show(i1: Self::Input, i2: Self::Input) {
println!("Part 1: {}", Self::part1(i1));
println!("Part 2: {}", Self::part2(i2));
}
}
#[cfg(test)]
pub trait AoCSolutionTest: AoCSolution {
const PART1_TEST_INPUT: Self::Input;
const PART2_TEST_INPUT: Self::Input;
const PART1_TEST_RESULT: Self::Solution;
const PART2_TEST_RESULT: Self::Solution;
fn assert_valid() {
assert_eq!(Self::part1(Self::PART1_TEST_INPUT), Self::PART1_TEST_RESULT);
assert_eq!(Self::part2(Self::PART2_TEST_INPUT), Self::PART2_TEST_RESULT);
}
}