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"
|
||||
|
||||
[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
|
||||
|
||||
jobs:
|
||||
test:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
name: CI
|
||||
name: Continuous Integration
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up cargo cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
continue-on-error: false
|
||||
with:
|
||||
path: |
|
||||
|
|
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
|
@ -2,7 +2,6 @@
|
|||
"recommendations": [
|
||||
"vadimcn.vscode-lldb",
|
||||
"rust-lang.rust-analyzer",
|
||||
"serayuzgur.crates",
|
||||
"editorConfig.editorConfig"
|
||||
]
|
||||
}
|
||||
|
|
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
|
@ -12,8 +12,10 @@
|
|||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
// replace `01` here with the solution you like to debug.
|
||||
"--bin=01",
|
||||
// replace with binary name (e.g. "01") here if you always
|
||||
// want to debug one file regardless of the active file in
|
||||
// the editor.
|
||||
"--bin=${fileBasenameNoExtension}",
|
||||
"--package=advent_of_code"
|
||||
],
|
||||
},
|
||||
|
@ -27,8 +29,10 @@
|
|||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
// replace `01` here with the solution you like to debug.
|
||||
"--bin=01",
|
||||
// replace with binary name (e.g. "01") here if you always
|
||||
// want to debug one file regardless of the active file in
|
||||
// the editor
|
||||
"--bin=${fileBasenameNoExtension}",
|
||||
"--package=advent_of_code"
|
||||
],
|
||||
},
|
||||
|
|
92
Cargo.lock
generated
92
Cargo.lock
generated
|
@ -92,16 +92,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.31"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -112,9 +112,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
|||
|
||||
[[package]]
|
||||
name = "dhat"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f2aaf837aaf456f6706cb46386ba8dffd4013a757e36f4ea05c20dd46b209a3"
|
||||
checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"lazy_static",
|
||||
|
@ -267,7 +267,7 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -463,7 +463,7 @@ version = "0.51.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -472,13 +472,29 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"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]]
|
||||
|
@ -487,38 +503,86 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]
|
||||
|
||||
# Template dependencies
|
||||
chrono = { version = "0.4.31", optional = true }
|
||||
dhat = { version = "0.3.2", optional = true }
|
||||
chrono = { version = "0.4.38", optional = true }
|
||||
dhat = { version = "0.3.3", optional = true }
|
||||
pico-args = "0.5.0"
|
||||
tinyjson = "2.5.1"
|
||||
|
||||
|
|
|
@ -6,6 +6,14 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
|||
|
||||
<!--- 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 --->
|
||||
|
||||
---
|
||||
|
|
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 {
|
||||
day: Day,
|
||||
download: bool,
|
||||
overwrite: bool,
|
||||
},
|
||||
Solve {
|
||||
day: Day,
|
||||
|
@ -65,6 +66,7 @@ mod args {
|
|||
Some("scaffold") => AppArguments::Scaffold {
|
||||
day: args.free_from_str()?,
|
||||
download: args.contains("--download"),
|
||||
overwrite: args.contains("--overwrite"),
|
||||
},
|
||||
Some("solve") => AppArguments::Solve {
|
||||
day: args.free_from_str()?,
|
||||
|
@ -104,8 +106,12 @@ fn main() {
|
|||
AppArguments::Time { day, all, store } => time::handle(day, all, store),
|
||||
AppArguments::Download { day } => download::handle(day),
|
||||
AppArguments::Read { day } => read::handle(day),
|
||||
AppArguments::Scaffold { day, download } => {
|
||||
scaffold::handle(day);
|
||||
AppArguments::Scaffold {
|
||||
day,
|
||||
download,
|
||||
overwrite,
|
||||
} => {
|
||||
scaffold::handle(day, overwrite);
|
||||
if download {
|
||||
download::handle(day);
|
||||
}
|
||||
|
@ -120,7 +126,7 @@ fn main() {
|
|||
AppArguments::Today => {
|
||||
match Day::today() {
|
||||
Some(day) => {
|
||||
scaffold::handle(day);
|
||||
scaffold::handle(day, false);
|
||||
download::handle(day);
|
||||
read::handle(day)
|
||||
}
|
||||
|
|
|
@ -9,20 +9,30 @@ use crate::template::Day;
|
|||
const MODULE_TEMPLATE: &str =
|
||||
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/template.txt"));
|
||||
|
||||
fn safe_create_file(path: &str) -> Result<File, std::io::Error> {
|
||||
OpenOptions::new().write(true).create_new(true).open(path)
|
||||
fn safe_create_file(path: &str, overwrite: bool) -> Result<File, std::io::Error> {
|
||||
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> {
|
||||
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 example_path = format!("data/examples/{day}.txt");
|
||||
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,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create module file: {e}");
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::template::Day;
|
|||
|
||||
static MARKER: &str = "<!--- benchmarking table --->";
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
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)]
|
||||
pub enum Error {
|
||||
BrokenPipe,
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::{cmp, env, process};
|
|||
use crate::template::ANSI_BOLD;
|
||||
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 (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:
|
||||
/// 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.)
|
||||
fn run_timed<I: Clone, T>(
|
||||
fn run_timed<I: Copy, T>(
|
||||
func: impl Fn(I) -> T,
|
||||
input: I,
|
||||
hook: impl Fn(&T),
|
||||
) -> (T, Duration, u128) {
|
||||
let timer = Instant::now();
|
||||
let result = {
|
||||
let input = input.clone();
|
||||
|
||||
#[cfg(feature = "dhat-heap")]
|
||||
let _profiler = dhat::Profiler::new_heap();
|
||||
|
||||
|
@ -52,27 +50,20 @@ fn run_timed<I: Clone, T>(
|
|||
(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();
|
||||
|
||||
print!(" > {ANSI_ITALIC}benching{ANSI_RESET}");
|
||||
let _ = stdout.flush();
|
||||
|
||||
let bench_iterations = cmp::min(
|
||||
10000,
|
||||
cmp::max(
|
||||
Duration::from_secs(1).as_nanos() / cmp::max(base_time.as_nanos(), 10),
|
||||
10,
|
||||
),
|
||||
);
|
||||
let bench_iterations =
|
||||
(Duration::from_secs(1).as_nanos() / cmp::max(base_time.as_nanos(), 10)).clamp(10, 10000);
|
||||
|
||||
let mut timers: Vec<Duration> = vec![];
|
||||
|
||||
for _ in 0..bench_iterations {
|
||||
// need a clone here to make the borrow checker happy.
|
||||
let cloned = input.clone();
|
||||
let timer = Instant::now();
|
||||
black_box(func(black_box(cloned)));
|
||||
black_box(func(black_box(input)));
|
||||
timers.push(timer.elapsed());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,17 +31,10 @@ impl Timings {
|
|||
|
||||
/// Rehydrate timings from a JSON file. If not present, returns empty timings.
|
||||
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())
|
||||
.and_then(Timings::try_from);
|
||||
|
||||
match s {
|
||||
Ok(timings) => timings,
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
Timings::default()
|
||||
}
|
||||
}
|
||||
.and_then(Timings::try_from)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Merge two sets of timings, overwriting `self` with `other` if present.
|
||||
|
|
Loading…
Add table
Reference in a new issue