Compare commits
10 Commits
000003607b
...
0000046052
Author | SHA1 | Date |
---|---|---|
Matej Janezic | 0000046052 | |
Matej Janezic | 00000450ed | |
Matej Janezic | 0000044053 | |
Matej Janezic | 0000043020 | |
Matej Janezic | 000004209d | |
Matej Janezic | 000004100d | |
Matej Janezic | 000004005f | |
Matej Janezic | 0000039097 | |
Matej Janezic | 0000038042 | |
Matej Janezic | 00000370cc |
|
@ -1,4 +1,4 @@
|
||||||
[alias]
|
[alias]
|
||||||
scaffold = "run -p scaffold --release --quiet --"
|
scaffold = "run -p scaffold --release --quiet --"
|
||||||
download = "run -p download --release --quiet --"
|
download = "run -p download --release --quiet --"
|
||||||
solve = "run --release --bin"
|
solve = "run --bin"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
TOKEN=secret
|
TOKEN=secret
|
||||||
YEAR=2022
|
YEAR=year
|
||||||
|
|
|
@ -11,6 +11,6 @@ target/
|
||||||
.env
|
.env
|
||||||
|
|
||||||
# downloaded inputs
|
# downloaded inputs
|
||||||
/src/inputs/*
|
/data/inputs/*
|
||||||
!/src/inputs/.keep
|
!/data/inputs/.keep
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc"
|
name = "aoc"
|
||||||
version = "36.0.0"
|
version = "46.0.0"
|
||||||
dependencies = [
|
|
||||||
"itertools",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
|
@ -105,19 +102,13 @@ checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "download"
|
name = "download"
|
||||||
version = "36.0.0"
|
version = "46.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"pico-args",
|
"pico-args",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.31"
|
version = "0.8.31"
|
||||||
|
@ -360,15 +351,6 @@ version = "2.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
|
checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -643,7 +625,7 @@ checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scaffold"
|
name = "scaffold"
|
||||||
version = "36.0.0"
|
version = "46.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"pico-args",
|
"pico-args",
|
||||||
|
|
27
Cargo.toml
27
Cargo.toml
|
@ -1,3 +1,15 @@
|
||||||
|
[workspace.package]
|
||||||
|
description = "template for advent of code"
|
||||||
|
readme = "README.md"
|
||||||
|
version = "46.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT"
|
||||||
|
authors = ["Matej Janežič <janezic.mj@gmail.com>"]
|
||||||
|
repository = "https://github.com/janezicmatej/aoc-template.git"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["utils/download", "utils/scaffold"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "aoc"
|
name = "aoc"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
|
@ -9,19 +21,4 @@ authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# many cool stuff for iterators
|
|
||||||
itertools = "0.12.0"
|
|
||||||
|
|
||||||
[workspace]
|
|
||||||
|
|
||||||
members = ["utils/download", "utils/scaffold"]
|
|
||||||
|
|
||||||
[workspace.package]
|
|
||||||
description = "template for advent of code"
|
|
||||||
readme = "README.md"
|
|
||||||
version = "36.0.0"
|
|
||||||
edition = "2021"
|
|
||||||
license = "MIT"
|
|
||||||
authors = ["Matej Janežič <janezic.mj@gmail.com>"]
|
|
||||||
repository = "https://github.com/janezicmatej/aoc-template.git"
|
|
||||||
|
|
||||||
|
|
11
README.md
11
README.md
|
@ -5,15 +5,16 @@
|
||||||
## Project overview
|
## Project overview
|
||||||
|
|
||||||
### Project structure
|
### Project structure
|
||||||
|
- `data/` :
|
||||||
|
- `examples/`: example files go here; you can push this as test are run in ci
|
||||||
|
- `inputs/`: this directory is gitignored, input files go here
|
||||||
- `src/` :
|
- `src/` :
|
||||||
- `bin/`:
|
- `bin/`:
|
||||||
- `<day>.rs`: solution files
|
- `<day>.rs`: solution files
|
||||||
- `inputs/`: this directory is gitignored, input files go here
|
- `lib.rs`: library entrypoint, reusable code goes here
|
||||||
- `examples/`: example files go here; you can push this as test are run in ci
|
- `template.rs`: contains template code
|
||||||
- `utils/`: utils files go here
|
|
||||||
- `lib.rs`: contains framework code
|
|
||||||
- `.env.example`: example dotenv file
|
|
||||||
- `utils/`: binary packages with convenience scripts structured using cargo workspaces
|
- `utils/`: binary packages with convenience scripts structured using cargo workspaces
|
||||||
|
- `.env.example`: example dotenv file
|
||||||
|
|
||||||
### Cli
|
### Cli
|
||||||
- `cargo scaffold <day>`: prepare solution files for `day`
|
- `cargo scaffold <day>`: prepare solution files for `day`
|
||||||
|
|
50
src/lib.rs
50
src/lib.rs
|
@ -1,49 +1 @@
|
||||||
/*
|
pub mod template;
|
||||||
* This file contains template code.
|
|
||||||
* There is no need to edit this file unless you want to change template functionality.
|
|
||||||
* Prefer `./helpers.rs` if you want to extract code from your solutions.
|
|
||||||
*/
|
|
||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
|
||||||
pub const ANSI_BOLD: &str = "\x1b[1m";
|
|
||||||
pub const ANSI_RESET: &str = "\x1b[0m";
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! solve {
|
|
||||||
($part:expr, $solver:ident, $input:expr) => {{
|
|
||||||
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
fn print_result<T: Display>(func: impl FnOnce(&str) -> Option<T>, input: &str) {
|
|
||||||
let timer = Instant::now();
|
|
||||||
let result = func(input);
|
|
||||||
let elapsed = timer.elapsed();
|
|
||||||
match result {
|
|
||||||
Some(result) => {
|
|
||||||
println!(
|
|
||||||
"{} {}(elapsed: {:.2?}){}",
|
|
||||||
result, ANSI_ITALIC, elapsed, ANSI_RESET
|
|
||||||
);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
println!("not solved.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("🎄 {}Part {}{} 🎄", ANSI_BOLD, $part, ANSI_RESET);
|
|
||||||
print_result($solver, $input);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_file(folder: &str, day: u8) -> String {
|
|
||||||
let cwd = env::current_dir().unwrap();
|
|
||||||
|
|
||||||
let filepath = cwd.join("src").join(folder).join(format!("{day:02}.txt"));
|
|
||||||
|
|
||||||
let f = fs::read_to_string(filepath);
|
|
||||||
f.expect("could not open input file").trim().to_string()
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file contains template code.
|
||||||
|
* There is no need to edit this file unless you want to change template functionality.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
||||||
|
pub const ANSI_BOLD: &str = "\x1b[1m";
|
||||||
|
pub const ANSI_RESET: &str = "\x1b[0m";
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
fn time_solution<T>(func: impl FnOnce(&str) -> Option<T>, input: &str) -> Option<(T, Duration)> {
|
||||||
|
let timer = Instant::now();
|
||||||
|
let result = func(input);
|
||||||
|
let elapsed = timer.elapsed();
|
||||||
|
|
||||||
|
result.map(|result| (result, elapsed))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_result<T: Display>(func: impl FnOnce(&str) -> Option<T>, input: &str, part: u8) {
|
||||||
|
match time_solution(func, input) {
|
||||||
|
Some((result, elapsed)) => {
|
||||||
|
println!(
|
||||||
|
"{}Part {}{}: {} {}(elapsed: {:.2?}){}",
|
||||||
|
ANSI_BOLD, part, ANSI_RESET, result, ANSI_ITALIC, elapsed, ANSI_RESET
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
println!("{}Part {}{}: not solved.", ANSI_BOLD, part, ANSI_RESET)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! solution {
|
||||||
|
($day:expr) => {
|
||||||
|
fn main() {
|
||||||
|
let input = aoc::template::read_file("inputs", $day);
|
||||||
|
aoc::template::print_result(part_one, &input, 1);
|
||||||
|
aoc::template::print_result(part_two, &input, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn read_file(folder: &str, day: u8) -> String {
|
||||||
|
let cwd = env::current_dir().unwrap();
|
||||||
|
let filepath = cwd.join("data").join(folder).join(format!("{day:02}.txt"));
|
||||||
|
let f = fs::read_to_string(filepath);
|
||||||
|
f.expect("could not open input file").trim().to_string()
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ fn main() {
|
||||||
.text()
|
.text()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let input_path = format!("src/inputs/{day_padded}.txt");
|
let input_path = format!("data/inputs/{day_padded}.txt");
|
||||||
let mut file = match OpenOptions::new()
|
let mut file = match OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
|
|
|
@ -11,26 +11,23 @@ use std::{
|
||||||
const MODULE_TEMPLATE: &str = r#"pub fn part_one(input: &str) -> Option<u32> {
|
const MODULE_TEMPLATE: &str = r#"pub fn part_one(input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn main() {
|
|
||||||
let input = &aoc::read_file("inputs", DAY);
|
aoc::solution!(DAY);
|
||||||
aoc::solve!(1, part_one, input);
|
|
||||||
aoc::solve!(2, part_two, input);
|
|
||||||
}
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
let input = aoc::read_file("examples", DAY);
|
assert_eq!(part_one(&aoc::template::read_file("examples", DAY)), None);
|
||||||
assert_eq!(part_one(&input), None);
|
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_two() {
|
fn test_part_two() {
|
||||||
let input = aoc::read_file("examples", DAY);
|
assert_eq!(part_two(&aoc::template::read_file("examples", DAY)), None);
|
||||||
assert_eq!(part_two(&input), None);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
@ -59,8 +56,8 @@ fn main() {
|
||||||
|
|
||||||
let day_padded = format!("{day:02}");
|
let day_padded = format!("{day:02}");
|
||||||
|
|
||||||
let input_path = format!("src/inputs/{day_padded}.txt");
|
let input_path = format!("data/inputs/{day_padded}.txt");
|
||||||
let example_path = format!("src/examples/{day_padded}.txt");
|
let example_path = format!("data/examples/{day_padded}.txt");
|
||||||
let module_path = format!("src/bin/{day_padded}.rs");
|
let module_path = format!("src/bin/{day_padded}.rs");
|
||||||
|
|
||||||
let mut file = match safe_create_file(&module_path) {
|
let mut file = match safe_create_file(&module_path) {
|
||||||
|
@ -102,8 +99,5 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("---");
|
println!("---");
|
||||||
println!(
|
println!("Type `cargo solve {}` to run your solution.", &day_padded);
|
||||||
"🎄 Type `cargo solve {}` to run your solution.",
|
|
||||||
&day_padded
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue