Compare commits
13 commits
Author | SHA1 | Date | |
---|---|---|---|
6a3a324ea1 | |||
ae09ba2cc7 | |||
51e34a6b06 | |||
|
36608db7b3 | ||
|
a50047ab0d | ||
|
3abf88c16a | ||
|
10f8c0e1b4 | ||
|
a49a1d3c4a | ||
|
fe89ad7990 | ||
|
1d46931242 | ||
|
59866c3d70 | ||
|
3657f8c6dc | ||
|
e2062e33fd |
21 changed files with 321 additions and 59 deletions
|
@ -9,4 +9,4 @@ all = "run --quiet --release -- all"
|
||||||
time = "run --quiet --release -- time"
|
time = "run --quiet --release -- time"
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
AOC_YEAR = "2023"
|
AOC_YEAR = "2024"
|
||||||
|
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
@ -6,13 +6,13 @@ env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
ci:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: CI
|
name: Continuous Integration
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Set up cargo cache
|
- name: Set up cargo cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
continue-on-error: false
|
continue-on-error: false
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
|
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
|
@ -2,7 +2,6 @@
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"vadimcn.vscode-lldb",
|
"vadimcn.vscode-lldb",
|
||||||
"rust-lang.rust-analyzer",
|
"rust-lang.rust-analyzer",
|
||||||
"serayuzgur.crates",
|
|
||||||
"editorConfig.editorConfig"
|
"editorConfig.editorConfig"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
|
@ -12,8 +12,10 @@
|
||||||
"args": [
|
"args": [
|
||||||
"test",
|
"test",
|
||||||
"--no-run",
|
"--no-run",
|
||||||
// replace `01` here with the solution you like to debug.
|
// replace with binary name (e.g. "01") here if you always
|
||||||
"--bin=01",
|
// want to debug one file regardless of the active file in
|
||||||
|
// the editor.
|
||||||
|
"--bin=${fileBasenameNoExtension}",
|
||||||
"--package=advent_of_code"
|
"--package=advent_of_code"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -27,8 +29,10 @@
|
||||||
"cargo": {
|
"cargo": {
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
// replace `01` here with the solution you like to debug.
|
// replace with binary name (e.g. "01") here if you always
|
||||||
"--bin=01",
|
// want to debug one file regardless of the active file in
|
||||||
|
// the editor
|
||||||
|
"--bin=${fileBasenameNoExtension}",
|
||||||
"--package=advent_of_code"
|
"--package=advent_of_code"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
92
Cargo.lock
generated
92
Cargo.lock
generated
|
@ -92,16 +92,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.31"
|
version = "0.4.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
|
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-targets",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -112,9 +112,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dhat"
|
name = "dhat"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f2aaf837aaf456f6706cb46386ba8dffd4013a757e36f4ea05c20dd46b209a3"
|
checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -267,7 +267,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -463,7 +463,7 @@ version = "0.51.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -472,13 +472,29 @@ version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.48.5",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.48.5",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.48.5",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.48.5",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.6",
|
||||||
|
"windows_aarch64_msvc 0.52.6",
|
||||||
|
"windows_i686_gnu 0.52.6",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc 0.52.6",
|
||||||
|
"windows_x86_64_gnu 0.52.6",
|
||||||
|
"windows_x86_64_gnullvm 0.52.6",
|
||||||
|
"windows_x86_64_msvc 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -487,38 +503,86 @@ version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
|
@ -22,8 +22,8 @@ test_lib = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
# Template dependencies
|
# Template dependencies
|
||||||
chrono = { version = "0.4.31", optional = true }
|
chrono = { version = "0.4.38", optional = true }
|
||||||
dhat = { version = "0.3.2", optional = true }
|
dhat = { version = "0.3.3", optional = true }
|
||||||
pico-args = "0.5.0"
|
pico-args = "0.5.0"
|
||||||
tinyjson = "2.5.1"
|
tinyjson = "2.5.1"
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,14 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
||||||
|
|
||||||
<!--- advent_readme_stars table --->
|
<!--- advent_readme_stars table --->
|
||||||
|
|
||||||
|
<!--- benchmarking table --->
|
||||||
|
## Benchmarks
|
||||||
|
|
||||||
|
| Day | Part 1 | Part 2 |
|
||||||
|
| :---: | :---: | :---: |
|
||||||
|
| [Day 1](./src/bin/01.rs) | `89.5µs` | `125.4µs` |
|
||||||
|
|
||||||
|
**Total: 0.21ms**
|
||||||
<!--- benchmarking table --->
|
<!--- benchmarking table --->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
0
data/examples/01.txt
Normal file
0
data/examples/01.txt
Normal file
6
data/examples/02.txt
Normal file
6
data/examples/02.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
7 6 4 2 1
|
||||||
|
1 2 7 8 9
|
||||||
|
9 7 6 2 1
|
||||||
|
1 3 2 4 5
|
||||||
|
8 6 4 4 1
|
||||||
|
1 3 6 7 9
|
0
data/examples/03.txt
Normal file
0
data/examples/03.txt
Normal file
0
data/examples/04.txt
Normal file
0
data/examples/04.txt
Normal file
85
src/bin/01.rs
Normal file
85
src/bin/01.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
advent_of_code::solution!(1);
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
if input.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut left: Vec<u32> = Vec::new();
|
||||||
|
let mut right: Vec<u32> = Vec::new();
|
||||||
|
|
||||||
|
for line in input.lines() {
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
|
||||||
|
if let (Some(l), Some(r)) = (split.next(), split.next()) {
|
||||||
|
if let (Ok(l_number), Ok(r_number)) = (l.parse::<u32>(), r.parse::<u32>()) {
|
||||||
|
left.push(l_number);
|
||||||
|
right.push(r_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
left.sort();
|
||||||
|
right.sort();
|
||||||
|
|
||||||
|
let total_distance: u32 = left
|
||||||
|
.iter()
|
||||||
|
.zip(right.iter())
|
||||||
|
.map(|(&x, &y)| if x > y { x - y } else { y - x })
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
Some(total_distance)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
if input.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut left: Vec<u32> = Vec::new();
|
||||||
|
let mut right: Vec<u32> = Vec::new();
|
||||||
|
|
||||||
|
for line in input.lines() {
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
|
||||||
|
if let (Some(l), Some(r)) = (split.next(), split.next()) {
|
||||||
|
if let (Ok(l_number), Ok(r_number)) = (l.parse::<u32>(), r.parse::<u32>()) {
|
||||||
|
left.push(l_number);
|
||||||
|
right.push(r_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
left.sort();
|
||||||
|
right.sort();
|
||||||
|
|
||||||
|
let mut right_list_counts: HashMap<u32, u32> = HashMap::new();
|
||||||
|
for &num in &right {
|
||||||
|
*right_list_counts.entry(num).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let total_similarity_score: u32 = left
|
||||||
|
.iter()
|
||||||
|
.map(|&num| num * right_list_counts.get(&num).unwrap_or(&0))
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
Some(total_similarity_score)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
}
|
42
src/bin/02.rs
Normal file
42
src/bin/02.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
advent_of_code::solution!(2);
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
let mut num_safe: u32 = 0;
|
||||||
|
let lines = input.lines();
|
||||||
|
for line in lines {
|
||||||
|
let levels: Vec<u32> = line
|
||||||
|
.split_whitespace()
|
||||||
|
.filter_map(|i| i.parse::<u32>().ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if levels
|
||||||
|
.windows(2)
|
||||||
|
.all(|w| (w[0] > w[1] && w[0] - w[1] <= 3) || (w[1] > w[0] && w[1] - w[0] <= 3))
|
||||||
|
&& (levels.windows(2).all(|w| w[0] < w[1]) || levels.windows(2).all(|w| w[0] > w[1]))
|
||||||
|
{
|
||||||
|
num_safe += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(num_safe)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
}
|
26
src/bin/03.rs
Normal file
26
src/bin/03.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
advent_of_code::solution!(3);
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
}
|
26
src/bin/04.rs
Normal file
26
src/bin/04.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
advent_of_code::solution!(4);
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
}
|
12
src/main.rs
12
src/main.rs
|
@ -20,6 +20,7 @@ mod args {
|
||||||
Scaffold {
|
Scaffold {
|
||||||
day: Day,
|
day: Day,
|
||||||
download: bool,
|
download: bool,
|
||||||
|
overwrite: bool,
|
||||||
},
|
},
|
||||||
Solve {
|
Solve {
|
||||||
day: Day,
|
day: Day,
|
||||||
|
@ -65,6 +66,7 @@ mod args {
|
||||||
Some("scaffold") => AppArguments::Scaffold {
|
Some("scaffold") => AppArguments::Scaffold {
|
||||||
day: args.free_from_str()?,
|
day: args.free_from_str()?,
|
||||||
download: args.contains("--download"),
|
download: args.contains("--download"),
|
||||||
|
overwrite: args.contains("--overwrite"),
|
||||||
},
|
},
|
||||||
Some("solve") => AppArguments::Solve {
|
Some("solve") => AppArguments::Solve {
|
||||||
day: args.free_from_str()?,
|
day: args.free_from_str()?,
|
||||||
|
@ -104,8 +106,12 @@ fn main() {
|
||||||
AppArguments::Time { day, all, store } => time::handle(day, all, store),
|
AppArguments::Time { day, all, store } => time::handle(day, all, store),
|
||||||
AppArguments::Download { day } => download::handle(day),
|
AppArguments::Download { day } => download::handle(day),
|
||||||
AppArguments::Read { day } => read::handle(day),
|
AppArguments::Read { day } => read::handle(day),
|
||||||
AppArguments::Scaffold { day, download } => {
|
AppArguments::Scaffold {
|
||||||
scaffold::handle(day);
|
day,
|
||||||
|
download,
|
||||||
|
overwrite,
|
||||||
|
} => {
|
||||||
|
scaffold::handle(day, overwrite);
|
||||||
if download {
|
if download {
|
||||||
download::handle(day);
|
download::handle(day);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +126,7 @@ fn main() {
|
||||||
AppArguments::Today => {
|
AppArguments::Today => {
|
||||||
match Day::today() {
|
match Day::today() {
|
||||||
Some(day) => {
|
Some(day) => {
|
||||||
scaffold::handle(day);
|
scaffold::handle(day, false);
|
||||||
download::handle(day);
|
download::handle(day);
|
||||||
read::handle(day)
|
read::handle(day)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,30 @@ use crate::template::Day;
|
||||||
const MODULE_TEMPLATE: &str =
|
const MODULE_TEMPLATE: &str =
|
||||||
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/template.txt"));
|
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/template.txt"));
|
||||||
|
|
||||||
fn safe_create_file(path: &str) -> Result<File, std::io::Error> {
|
fn safe_create_file(path: &str, overwrite: bool) -> Result<File, std::io::Error> {
|
||||||
OpenOptions::new().write(true).create_new(true).open(path)
|
let mut file = OpenOptions::new();
|
||||||
|
if overwrite {
|
||||||
|
file.create(true);
|
||||||
|
} else {
|
||||||
|
file.create_new(true);
|
||||||
|
}
|
||||||
|
file.truncate(true).write(true).open(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_file(path: &str) -> Result<File, std::io::Error> {
|
fn create_file(path: &str) -> Result<File, std::io::Error> {
|
||||||
OpenOptions::new().write(true).create(true).open(path)
|
OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle(day: Day) {
|
pub fn handle(day: Day, overwrite: bool) {
|
||||||
let input_path = format!("data/inputs/{day}.txt");
|
let input_path = format!("data/inputs/{day}.txt");
|
||||||
let example_path = format!("data/examples/{day}.txt");
|
let example_path = format!("data/examples/{day}.txt");
|
||||||
let module_path = format!("src/bin/{day}.rs");
|
let module_path = format!("src/bin/{day}.rs");
|
||||||
|
|
||||||
let mut file = match safe_create_file(&module_path) {
|
let mut file = match safe_create_file(&module_path, overwrite) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to create module file: {e}");
|
eprintln!("Failed to create module file: {e}");
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::template::Day;
|
||||||
|
|
||||||
static MARKER: &str = "<!--- benchmarking table --->";
|
static MARKER: &str = "<!--- benchmarking table --->";
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Parser(String),
|
Parser(String),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn run_multi(days_to_run: &HashSet<Day>, is_release: bool, is_timed: bool) -
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
BrokenPipe,
|
BrokenPipe,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{cmp, env, process};
|
||||||
use crate::template::ANSI_BOLD;
|
use crate::template::ANSI_BOLD;
|
||||||
use crate::template::{aoc_cli, Day, ANSI_ITALIC, ANSI_RESET};
|
use crate::template::{aoc_cli, Day, ANSI_ITALIC, ANSI_RESET};
|
||||||
|
|
||||||
pub fn run_part<I: Clone, T: Display>(func: impl Fn(I) -> Option<T>, input: I, day: Day, part: u8) {
|
pub fn run_part<I: Copy, T: Display>(func: impl Fn(I) -> Option<T>, input: I, day: Day, part: u8) {
|
||||||
let part_str = format!("Part {part}");
|
let part_str = format!("Part {part}");
|
||||||
|
|
||||||
let (result, duration, samples) =
|
let (result, duration, samples) =
|
||||||
|
@ -25,15 +25,13 @@ pub fn run_part<I: Clone, T: Display>(func: impl Fn(I) -> Option<T>, input: I, d
|
||||||
/// Run a solution part. The behavior differs depending on whether we are running a release or debug build:
|
/// Run a solution part. The behavior differs depending on whether we are running a release or debug build:
|
||||||
/// 1. in debug, the function is executed once.
|
/// 1. in debug, the function is executed once.
|
||||||
/// 2. in release, the function is benched (approx. 1 second of execution time or 10 samples, whatever take longer.)
|
/// 2. in release, the function is benched (approx. 1 second of execution time or 10 samples, whatever take longer.)
|
||||||
fn run_timed<I: Clone, T>(
|
fn run_timed<I: Copy, T>(
|
||||||
func: impl Fn(I) -> T,
|
func: impl Fn(I) -> T,
|
||||||
input: I,
|
input: I,
|
||||||
hook: impl Fn(&T),
|
hook: impl Fn(&T),
|
||||||
) -> (T, Duration, u128) {
|
) -> (T, Duration, u128) {
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
let result = {
|
let result = {
|
||||||
let input = input.clone();
|
|
||||||
|
|
||||||
#[cfg(feature = "dhat-heap")]
|
#[cfg(feature = "dhat-heap")]
|
||||||
let _profiler = dhat::Profiler::new_heap();
|
let _profiler = dhat::Profiler::new_heap();
|
||||||
|
|
||||||
|
@ -52,27 +50,20 @@ fn run_timed<I: Clone, T>(
|
||||||
(result, run.0, run.1)
|
(result, run.0, run.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench<I: Clone, T>(func: impl Fn(I) -> T, input: I, base_time: &Duration) -> (Duration, u128) {
|
fn bench<I: Copy, T>(func: impl Fn(I) -> T, input: I, base_time: &Duration) -> (Duration, u128) {
|
||||||
let mut stdout = stdout();
|
let mut stdout = stdout();
|
||||||
|
|
||||||
print!(" > {ANSI_ITALIC}benching{ANSI_RESET}");
|
print!(" > {ANSI_ITALIC}benching{ANSI_RESET}");
|
||||||
let _ = stdout.flush();
|
let _ = stdout.flush();
|
||||||
|
|
||||||
let bench_iterations = cmp::min(
|
let bench_iterations =
|
||||||
10000,
|
(Duration::from_secs(1).as_nanos() / cmp::max(base_time.as_nanos(), 10)).clamp(10, 10000);
|
||||||
cmp::max(
|
|
||||||
Duration::from_secs(1).as_nanos() / cmp::max(base_time.as_nanos(), 10),
|
|
||||||
10,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut timers: Vec<Duration> = vec![];
|
let mut timers: Vec<Duration> = vec![];
|
||||||
|
|
||||||
for _ in 0..bench_iterations {
|
for _ in 0..bench_iterations {
|
||||||
// need a clone here to make the borrow checker happy.
|
|
||||||
let cloned = input.clone();
|
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
black_box(func(black_box(cloned)));
|
black_box(func(black_box(input)));
|
||||||
timers.push(timer.elapsed());
|
timers.push(timer.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,10 @@ impl Timings {
|
||||||
|
|
||||||
/// Rehydrate timings from a JSON file. If not present, returns empty timings.
|
/// Rehydrate timings from a JSON file. If not present, returns empty timings.
|
||||||
pub fn read_from_file() -> Self {
|
pub fn read_from_file() -> Self {
|
||||||
let s = fs::read_to_string(TIMINGS_FILE_PATH)
|
fs::read_to_string(TIMINGS_FILE_PATH)
|
||||||
.map_err(|x| x.to_string())
|
.map_err(|x| x.to_string())
|
||||||
.and_then(Timings::try_from);
|
.and_then(Timings::try_from)
|
||||||
|
.unwrap_or_default()
|
||||||
match s {
|
|
||||||
Ok(timings) => timings,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("{e}");
|
|
||||||
Timings::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge two sets of timings, overwriting `self` with `other` if present.
|
/// Merge two sets of timings, overwriting `self` with `other` if present.
|
||||||
|
|
Loading…
Add table
Reference in a new issue