diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 761f96e..6309f5b 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -14,7 +14,7 @@ concurrency:
cancel-in-progress: true
env:
- MSRV: "1.74"
+ MSRV: "1.75"
CARGO_TERM_COLOR: always
jobs:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9e58642..73e230b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -26,22 +26,17 @@ repos:
- id: beautysh
- repo: https://github.com/codespell-project/codespell
- rev: v2.2.6
+ rev: v2.3.0
hooks:
- id: codespell
args: ["--ignore-words-list", "crate"]
exclude: Cargo.lock|input/.*|aoc2023/.*/day15.rs
- repo: https://github.com/hadolint/hadolint
- rev: v2.12.1-beta
+ rev: v2.13.1-beta
hooks:
- id: hadolint-docker
- - repo: https://github.com/executablebooks/mdformat
- rev: 0.7.17
- hooks:
- - id: mdformat
-
- repo: https://github.com/AndrejOrsula/pre-commit-cargo
rev: 0.3.0
hooks:
diff --git a/Dockerfile b/Dockerfile
index c8940bb..441173c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-ARG RUST_VERSION=1.74
+ARG RUST_VERSION=latest
FROM rust:${RUST_VERSION}
### Use bash as the default shell
diff --git a/README.md b/README.md
index c2fb39c..202dd8b 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles.
## Edition
-### [Advent of Code 2023](https://adventofcode.com/2023)
+
> All benchmarks are run on a *Dell Precision 5550* laptop with an *Intel Core i7-10875H* CPU.
@@ -105,10 +105,11 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles.
| 252.4 µs | 61.18 ms |
| 101.2 µs | 2.5839 s |
| 79.73 µs | 2.4001 s |
-| 0.000 µs | 0.000 µs |
+| — | — |
+
## Instructions
diff --git a/aoc2023/Cargo.toml b/aoc2023/Cargo.toml
index 89d452f..494f9a2 100644
--- a/aoc2023/Cargo.toml
+++ b/aoc2023/Cargo.toml
@@ -2,21 +2,22 @@
name = "aoc2023"
description = "Advent of Code 2023"
edition = "2021"
-rust-version = "1.74"
+rust-version = "1.75"
version = "0.1.0"
authors.workspace = true
keywords.workspace = true
license.workspace = true
readme.workspace = true
repository.workspace = true
+publish = false
[dependencies]
aoc-runner = { workspace = true }
aoc-runner-derive = { workspace = true }
indoc = { workspace = true }
-derive_more = { version = "0.99" }
-itertools = { version = "0.12" }
+derive_more = { version = "1", features = ["full"] }
+itertools = { version = "0.13" }
num = { version = "0.4" }
num-integer = { version = "0.1" }
pathfinding = { version = "4.4" }
diff --git a/aoc2023/src/day1.rs b/aoc2023/src/day1.rs
index ac6526e..f8143c1 100644
--- a/aoc2023/src/day1.rs
+++ b/aoc2023/src/day1.rs
@@ -1,12 +1,8 @@
-use aoc_runner_derive::{aoc, aoc_generator};
-
-#[aoc_generator(day1)]
-fn parse(input: &str) -> String {
- input.to_owned()
-}
+use aoc_runner_derive::aoc;
#[aoc(day1, part1)]
-fn part1(input: &str) -> u32 {
+#[must_use]
+pub fn part1(input: &str) -> u32 {
input
.lines()
.map(|line| {
@@ -20,7 +16,8 @@ fn part1(input: &str) -> u32 {
}
#[aoc(day1, part2)]
-fn part2(input: &str) -> u32 {
+#[must_use]
+pub fn part2(input: &str) -> u32 {
input
.lines()
.map(|line| {
@@ -149,18 +146,18 @@ mod tests {
use indoc::indoc;
#[test]
- fn part1_example() {
+ pub fn part1_example() {
const SAMPLE: &str = indoc! {"
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
"};
- assert_eq!(part1(&parse(SAMPLE)), 142);
+ assert_eq!(part1(SAMPLE), 142);
}
#[test]
- fn part2_example() {
+ pub fn part2_example() {
const SAMPLE: &str = indoc! {"
two1nine
eightwothree
@@ -170,6 +167,6 @@ mod tests {
zoneight234
7pqrstsixteen
"};
- assert_eq!(part2(&parse(SAMPLE)), 281);
+ assert_eq!(part2(SAMPLE), 281);
}
}
diff --git a/aoc2023/src/day10.rs b/aoc2023/src/day10.rs
index 6162188..2c8282f 100644
--- a/aoc2023/src/day10.rs
+++ b/aoc2023/src/day10.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day10)]
fn parse(input: &str) -> utils::Map {
let mut grid = pathfinding::matrix::Matrix::new(
input.lines().count(),
@@ -25,13 +24,17 @@ fn parse(input: &str) -> utils::Map {
}
#[aoc(day10, part1)]
-fn part1(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
// The furthest point from the start is always the middle of the loop
input.get_loop().len() / 2
}
#[aoc(day10, part2)]
-fn part2(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
// Construct a grid that only contains the loop
let mut enclosure =
pathfinding::matrix::Matrix::new(input.grid.rows, input.grid.columns, utils::Tile::Ground);
@@ -174,7 +177,7 @@ mod tests {
use indoc::indoc;
#[test]
- fn part1_example() {
+ pub fn part1_example() {
const SAMPLES: [&str; 2] = [
indoc! {"
.....
@@ -192,12 +195,12 @@ mod tests {
"},
];
- assert_eq!(part1(&parse(SAMPLES[0])), 4);
- assert_eq!(part1(&parse(SAMPLES[1])), 8);
+ assert_eq!(part1(SAMPLES[0]), 4);
+ assert_eq!(part1(SAMPLES[1]), 8);
}
#[test]
- fn part2_example() {
+ pub fn part2_example() {
const SAMPLES: [&str; 3] = [
indoc! {"
...........
@@ -236,8 +239,8 @@ mod tests {
"},
];
- assert_eq!(part2(&parse(SAMPLES[0])), 4);
- assert_eq!(part2(&parse(SAMPLES[1])), 8);
- assert_eq!(part2(&parse(SAMPLES[2])), 10);
+ assert_eq!(part2(SAMPLES[0]), 4);
+ assert_eq!(part2(SAMPLES[1]), 8);
+ assert_eq!(part2(SAMPLES[2]), 10);
}
}
diff --git a/aoc2023/src/day11.rs b/aoc2023/src/day11.rs
index e319bc4..410281b 100644
--- a/aoc2023/src/day11.rs
+++ b/aoc2023/src/day11.rs
@@ -1,23 +1,25 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day11, part1)]
fn parse1(input: &str) -> Vec<(usize, usize)> {
utils::parse_expanded_galaxies(input, 1)
}
-#[aoc_generator(day11, part2)]
fn parse2(input: &str) -> Vec<(usize, usize)> {
utils::parse_expanded_galaxies(input, 999_999)
}
#[aoc(day11, part1)]
-fn part1(input: &[(usize, usize)]) -> usize {
- utils::sum_galactic_distances(input)
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse1(input);
+ utils::sum_galactic_distances(&input)
}
#[aoc(day11, part2)]
-fn part2(input: &[(usize, usize)]) -> usize {
- utils::sum_galactic_distances(input)
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse2(input);
+ utils::sum_galactic_distances(&input)
}
mod utils {
@@ -133,13 +135,19 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse1(SAMPLE)), 374);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 374);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&utils::parse_expanded_galaxies(SAMPLE, 9)), 1030);
- assert_eq!(part2(&utils::parse_expanded_galaxies(SAMPLE, 99)), 8410);
+ pub fn part2_example() {
+ assert_eq!(
+ utils::sum_galactic_distances(&utils::parse_expanded_galaxies(SAMPLE, 9)),
+ 1030
+ );
+ assert_eq!(
+ utils::sum_galactic_distances(&utils::parse_expanded_galaxies(SAMPLE, 99)),
+ 8410
+ );
}
}
diff --git a/aoc2023/src/day12.rs b/aoc2023/src/day12.rs
index 5f32ca4..f656dbf 100644
--- a/aoc2023/src/day12.rs
+++ b/aoc2023/src/day12.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day12)]
fn parse(input: &str) -> Vec {
input
.lines()
@@ -19,7 +18,8 @@ fn parse(input: &str) -> Vec {
}
#[aoc(day12, part1)]
-fn part1(input: &[utils::SpringSequence]) -> usize {
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
input
.iter()
.map(utils::SpringSequence::discover_arrangements)
@@ -27,7 +27,9 @@ fn part1(input: &[utils::SpringSequence]) -> usize {
}
#[aoc(day12, part2)]
-fn part2(input: &[utils::SpringSequence]) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
input
.iter()
.map(|sequence| {
@@ -155,12 +157,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 21);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 21);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 525_152);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 525_152);
}
}
diff --git a/aoc2023/src/day13.rs b/aoc2023/src/day13.rs
index 1c5be80..e3741ca 100644
--- a/aoc2023/src/day13.rs
+++ b/aoc2023/src/day13.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day13)]
fn parse(input: &str) -> Vec {
input
.split("\n\n")
@@ -9,7 +8,9 @@ fn parse(input: &str) -> Vec {
}
#[aoc(day13, part1)]
-fn part1(input: &[utils::Pattern]) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
input
.iter()
.map(|pattern| {
@@ -19,9 +20,11 @@ fn part1(input: &[utils::Pattern]) -> usize {
}
#[aoc(day13, part2)]
-fn part2(input: &[utils::Pattern]) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
use rayon::prelude::*;
+ let input = parse(input);
input
.iter()
.par_bridge()
@@ -99,12 +102,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 405);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 405);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 400);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 400);
}
}
diff --git a/aoc2023/src/day14.rs b/aoc2023/src/day14.rs
index e466852..bc03baa 100644
--- a/aoc2023/src/day14.rs
+++ b/aoc2023/src/day14.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day14)]
fn parse(input: &str) -> utils::Platform {
let mut matrix = pathfinding::matrix::Matrix::new(
input.lines().count(),
@@ -16,17 +15,19 @@ fn parse(input: &str) -> utils::Platform {
}
#[aoc(day14, part1)]
-fn part1(input: &utils::Platform) -> usize {
- let mut input = input.clone();
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let mut input = parse(input);
input.slide_rocks_north();
input.compute_load()
}
#[aoc(day14, part2)]
-fn part2(input: &utils::Platform) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
const TARGET_N_SPINS: usize = 1_000_000_000;
- let mut input = input.clone();
+ let mut input = parse(input);
let mut visited: rustc_hash::FxHashMap =
[(input.clone(), 0)].into_iter().collect();
@@ -153,12 +154,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 136);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 136);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 64);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 64);
}
}
diff --git a/aoc2023/src/day15.rs b/aoc2023/src/day15.rs
index 6b029eb..1cbc4fd 100644
--- a/aoc2023/src/day15.rs
+++ b/aoc2023/src/day15.rs
@@ -1,20 +1,23 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day15)]
fn parse(input: &str) -> Vec {
input.split(',').map(|x| x.trim().to_owned()).collect()
}
#[aoc(day15, part1)]
-fn part1(input: &[String]) -> u32 {
+#[must_use]
+pub fn part1(input: &str) -> u32 {
+ let input = parse(input);
input.iter().map(|step| u32::from(utils::hash(step))).sum()
}
#[aoc(day15, part2)]
-fn part2(input: &[String]) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
let mut boxes = vec![smallvec::SmallVec::<[_; 5]>::new(); 256];
- for step in input {
- let (label, focal_length) = step.split_once(|c| c == '=' || c == '-').unwrap();
+ for step in &input {
+ let (label, focal_length) = step.split_once(['=', '-']).unwrap();
let current_box = boxes.get_mut(utils::hash(label) as usize).unwrap();
let slot_index = current_box.iter().position(|&(l, _)| l == label);
if step.contains('=') {
@@ -63,12 +66,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 1320);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 1320);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 145);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 145);
}
}
diff --git a/aoc2023/src/day16.rs b/aoc2023/src/day16.rs
index f570303..252daf6 100644
--- a/aoc2023/src/day16.rs
+++ b/aoc2023/src/day16.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day16)]
fn parse(input: &str) -> utils::Cave {
let mut matrix = pathfinding::matrix::Matrix::new(
input.lines().count(),
@@ -16,15 +15,19 @@ fn parse(input: &str) -> utils::Cave {
}
#[aoc(day16, part1)]
-fn part1(input: &utils::Cave) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
let beam = utils::Beam::new((0, 0), utils::Direction::East);
input.get_energized_tiles(beam).len()
}
#[aoc(day16, part2)]
-fn part2(input: &utils::Cave) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
use rayon::prelude::*;
+ let input = parse(input);
(0..input.columns)
.map(|x| utils::Beam::new((x, 0), utils::Direction::South))
.chain(
@@ -181,12 +184,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 46);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 46);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 51);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 51);
}
}
diff --git a/aoc2023/src/day17.rs b/aoc2023/src/day17.rs
index abb0fd0..7a6718f 100644
--- a/aoc2023/src/day17.rs
+++ b/aoc2023/src/day17.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day17)]
fn parse(input: &str) -> utils::Map {
let mut matrix = pathfinding::matrix::Matrix::new(
input.lines().count(),
@@ -16,12 +15,16 @@ fn parse(input: &str) -> utils::Map {
}
#[aoc(day17, part1)]
-fn part1(input: &utils::Map) -> u32 {
+#[must_use]
+pub fn part1(input: &str) -> u32 {
+ let input = parse(input);
input.find_shortest_path(0, 3)
}
#[aoc(day17, part2)]
-fn part2(input: &utils::Map) -> u32 {
+#[must_use]
+pub fn part2(input: &str) -> u32 {
+ let input = parse(input);
input.find_shortest_path(4, 10)
}
@@ -191,12 +194,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 102);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 102);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 94);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 94);
}
}
diff --git a/aoc2023/src/day18.rs b/aoc2023/src/day18.rs
index 12a7dfb..8c780b6 100644
--- a/aoc2023/src/day18.rs
+++ b/aoc2023/src/day18.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day18, part1)]
fn parse1(input: &str) -> Vec<(utils::Direction, u32)> {
use itertools::Itertools;
@@ -16,7 +15,6 @@ fn parse1(input: &str) -> Vec<(utils::Direction, u32)> {
.collect()
}
-#[aoc_generator(day18, part2)]
fn parse2(input: &str) -> Vec<(utils::Direction, u32)> {
use itertools::Itertools;
@@ -38,13 +36,17 @@ fn parse2(input: &str) -> Vec<(utils::Direction, u32)> {
}
#[aoc(day18, part1)]
-fn part1(input: &[(utils::Direction, u32)]) -> u64 {
- utils::compute_area(input)
+#[must_use]
+pub fn part1(input: &str) -> u64 {
+ let input = parse1(input);
+ utils::compute_area(&input)
}
#[aoc(day18, part2)]
-fn part2(input: &[(utils::Direction, u32)]) -> u64 {
- utils::compute_area(input)
+#[must_use]
+pub fn part2(input: &str) -> u64 {
+ let input = parse2(input);
+ utils::compute_area(&input)
}
mod utils {
@@ -116,12 +118,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse1(SAMPLE)), 62);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 62);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse2(SAMPLE)), 952_408_144_115);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 952_408_144_115);
}
}
diff --git a/aoc2023/src/day19.rs b/aoc2023/src/day19.rs
index ccc192e..f81155d 100644
--- a/aoc2023/src/day19.rs
+++ b/aoc2023/src/day19.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day19)]
fn parse(input: &str) -> utils::SortingSystem {
let (workflows, part_ratings) = input.split_once("\n\n").unwrap();
@@ -61,12 +60,16 @@ fn parse(input: &str) -> utils::SortingSystem {
}
#[aoc(day19, part1)]
-fn part1(input: &utils::SortingSystem) -> u64 {
- utils::count_accepted(input, "in")
+#[must_use]
+pub fn part1(input: &str) -> u64 {
+ let input = parse(input);
+ utils::count_accepted(&input, "in")
}
#[aoc(day19, part2)]
-fn part2(input: &utils::SortingSystem) -> u64 {
+#[must_use]
+pub fn part2(input: &str) -> u64 {
+ let input = parse(input);
use strum::IntoEnumIterator;
utils::count_all_accepted_combinations_recursively(
&input.workflows,
@@ -262,12 +265,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 19114);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 19114);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 167_409_079_868_000);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 167_409_079_868_000);
}
}
diff --git a/aoc2023/src/day2.rs b/aoc2023/src/day2.rs
index 715d95c..c19c519 100644
--- a/aoc2023/src/day2.rs
+++ b/aoc2023/src/day2.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day2)]
fn parse(input: &str) -> Vec {
use std::str::FromStr;
@@ -39,11 +38,13 @@ fn parse(input: &str) -> Vec {
}
#[aoc(day2, part1)]
-fn part1(input: &[utils::Game]) -> u32 {
+#[must_use]
+pub fn part1(input: &str) -> u32 {
const MAX_N_RED: u8 = 12;
const MAX_N_GREEN: u8 = 13;
const MAX_N_BLUE: u8 = 14;
+ let input = parse(input);
input
.iter()
.filter_map(|game| {
@@ -65,7 +66,9 @@ fn part1(input: &[utils::Game]) -> u32 {
}
#[aoc(day2, part2)]
-fn part2(input: &[utils::Game]) -> u32 {
+#[must_use]
+pub fn part2(input: &str) -> u32 {
+ let input = parse(input);
input
.iter()
.map(|game| {
@@ -92,6 +95,7 @@ mod utils {
}
#[derive(Default)]
+ #[allow(clippy::struct_field_names)]
pub struct CubeSet {
pub n_red: u8,
pub n_green: u8,
@@ -141,12 +145,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 8);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 8);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 2286);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 2286);
}
}
diff --git a/aoc2023/src/day20.rs b/aoc2023/src/day20.rs
index 203cb38..231cc21 100644
--- a/aoc2023/src/day20.rs
+++ b/aoc2023/src/day20.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day20)]
fn parse(input: &str) -> utils::Modules {
let mut modules: rustc_hash::FxHashMap = input
.lines()
@@ -48,8 +47,9 @@ fn parse(input: &str) -> utils::Modules {
}
#[aoc(day20, part1)]
-fn part1(input: &utils::Modules) -> usize {
- let mut input = input.clone();
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let mut input = parse(input);
let (n_low, n_high) = (0..1000).fold((0, 0), |(mut acc_low, mut acc_high), _| {
let mut active_pulses = std::collections::VecDeque::default();
@@ -80,8 +80,9 @@ fn part1(input: &utils::Modules) -> usize {
}
#[aoc(day20, part2)]
-fn part2(input: &utils::Modules) -> usize {
- let mut input = input.clone();
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let mut input = parse(input);
// Find all modules that branch into a conjunction that is connected to the final "rx" module
let mut final_module_sources = vec!["rx".to_string()];
@@ -260,12 +261,12 @@ mod tests {
];
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLES[0])), 32_000_000);
- assert_eq!(part1(&parse(SAMPLES[1])), 11_687_500);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLES[0]), 32_000_000);
+ assert_eq!(part1(SAMPLES[1]), 11_687_500);
}
#[test]
#[ignore]
- fn part2_example() {}
+ pub fn part2_example() {}
}
diff --git a/aoc2023/src/day21.rs b/aoc2023/src/day21.rs
index 357ce62..9f5186f 100644
--- a/aoc2023/src/day21.rs
+++ b/aoc2023/src/day21.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day21)]
fn parse(input: &str) -> utils::Map {
let mut grid =
pathfinding::grid::Grid::new(input.lines().count(), input.lines().next().unwrap().len());
@@ -25,12 +24,16 @@ fn parse(input: &str) -> utils::Map {
}
#[aoc(day21, part1)]
-fn part1(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
input.count_reachable_plots(64, false)
}
#[aoc(day21, part2)]
-fn part2(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
input.count_reachable_plots2(26_501_365)
}
@@ -248,12 +251,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
+ pub fn part1_example() {
assert_eq!(parse(SAMPLE).count_reachable_plots(6, false), 16);
}
#[test]
- fn part2_example() {
+ pub fn part2_example() {
assert_eq!(parse(SAMPLE).count_reachable_plots(6, true), 16);
assert_eq!(parse(SAMPLE).count_reachable_plots(10, true), 50);
assert_eq!(parse(SAMPLE).count_reachable_plots(50, true), 1594);
diff --git a/aoc2023/src/day22.rs b/aoc2023/src/day22.rs
index 982e790..2abd209 100644
--- a/aoc2023/src/day22.rs
+++ b/aoc2023/src/day22.rs
@@ -1,7 +1,6 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
/// Parsed bricks are already settled on the ground and sorted by their Z coordinate.
-#[aoc_generator(day22)]
fn parse(input: &str) -> utils::Brickfall {
use itertools::Itertools;
use std::str::FromStr;
@@ -17,14 +16,18 @@ fn parse(input: &str) -> utils::Brickfall {
}
#[aoc(day22, part1)]
-fn part1(input: &utils::Brickfall) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
(0..input.len())
.filter(|&i| input.bricks_affected_by(i).all(|x| !x))
.count()
}
#[aoc(day22, part2)]
-fn part2(input: &utils::Brickfall) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
(0..input.len())
.map(|i| input.bricks_affected_by(i).filter(|&x| x).count())
.sum()
@@ -155,12 +158,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 5);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 5);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 7);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 7);
}
}
diff --git a/aoc2023/src/day23.rs b/aoc2023/src/day23.rs
index 8a5efa1..5e7de3a 100644
--- a/aoc2023/src/day23.rs
+++ b/aoc2023/src/day23.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day23)]
fn parse(input: &str) -> utils::Map {
let mut matrix = pathfinding::matrix::Matrix::new(
input.lines().count(),
@@ -22,12 +21,16 @@ fn parse(input: &str) -> utils::Map {
}
#[aoc(day23, part1)]
-fn part1(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
input.longest_path_len(true)
}
#[aoc(day23, part2)]
-fn part2(input: &utils::Map) -> usize {
+#[must_use]
+pub fn part2(input: &str) -> usize {
+ let input = parse(input);
input.longest_path_len(false)
}
@@ -231,12 +234,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 94);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 94);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 154);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 154);
}
}
diff --git a/aoc2023/src/day24.rs b/aoc2023/src/day24.rs
index 304d923..bc3d3c6 100644
--- a/aoc2023/src/day24.rs
+++ b/aoc2023/src/day24.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day24)]
fn parse(input: &str) -> utils::Hail {
use itertools::Itertools;
input
@@ -24,7 +23,9 @@ fn parse(input: &str) -> utils::Hail {
}
#[aoc(day24, part1)]
-fn part1(input: &utils::Hail) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
input.count_intersections((200_000_000_000_000, 400_000_000_000_000))
}
@@ -34,9 +35,12 @@ fn part1(input: &utils::Hail) -> usize {
#[aoc(day24, part2)]
#[allow(clippy::similar_names)]
#[cfg(feature = "z3")]
-fn part2(input: &utils::Hail) -> u64 {
+#[must_use]
+pub fn part2(input: &str) -> u64 {
use z3::ast::Ast;
+ let input = parse(input);
+
let context = z3::Context::new(&z3::Config::default());
let solver = z3::Solver::new(&context);
@@ -158,13 +162,13 @@ mod tests {
"};
#[test]
- fn part1_example() {
+ pub fn part1_example() {
assert_eq!(parse(SAMPLE).count_intersections((7, 27)), 2);
}
#[test]
#[cfg(feature = "z3")]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 47);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 47);
}
}
diff --git a/aoc2023/src/day25.rs b/aoc2023/src/day25.rs
index f7b68db..bdf254b 100644
--- a/aoc2023/src/day25.rs
+++ b/aoc2023/src/day25.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day25)]
fn parse(input: &str) -> petgraph::Graph {
let mut graph = petgraph::Graph::default();
let mut nodes = std::collections::HashMap::new();
@@ -22,7 +21,9 @@ fn parse(input: &str) -> petgraph::Graph {
}
#[aoc(day25, part1)]
-fn part1(input: &petgraph::Graph) -> usize {
+#[must_use]
+pub fn part1(input: &str) -> usize {
+ let input = parse(input);
let min_cut_res: Result<_, ()> =
rustworkx_core::connectivity::stoer_wagner_min_cut(&input, |_| Ok(1));
let (min_cut, partition) = min_cut_res.unwrap().unwrap();
@@ -39,7 +40,7 @@ mod tests {
use indoc::indoc;
#[test]
- fn part1_example() {
+ pub fn part1_example() {
const SAMPLE: &str = indoc! {"
jqt: rhn xhk nvd
rsh: frs pzl lsr
@@ -56,6 +57,6 @@ mod tests {
frs: qnr lhk lsr
"};
- assert_eq!(part1(&parse(SAMPLE)), 54);
+ assert_eq!(part1(SAMPLE), 54);
}
}
diff --git a/aoc2023/src/day3.rs b/aoc2023/src/day3.rs
index afaa6d8..71d28cd 100644
--- a/aoc2023/src/day3.rs
+++ b/aoc2023/src/day3.rs
@@ -1,12 +1,7 @@
-use aoc_runner_derive::{aoc, aoc_generator};
-
-#[aoc_generator(day3)]
-fn parse(input: &str) -> String {
- input.to_owned()
-}
+use aoc_runner_derive::aoc;
#[aoc(day3, part1)]
-fn part1(input: &str) -> u32 {
+pub fn part1(input: &str) -> u32 {
// Sum of all numbers that are surrounded by symbols
let mut sum = 0;
@@ -79,7 +74,7 @@ fn part1(input: &str) -> u32 {
}
#[aoc(day3, part2)]
-fn part2(input: &str) -> u32 {
+pub fn part2(input: &str) -> u32 {
// Sum of all products between two numbers that are connected by a gear ('*')
let mut sum = 0;
@@ -225,12 +220,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 4361);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 4361);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 467_835);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 467_835);
}
}
diff --git a/aoc2023/src/day4.rs b/aoc2023/src/day4.rs
index 6d0b5c9..0c7010c 100644
--- a/aoc2023/src/day4.rs
+++ b/aoc2023/src/day4.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day4)]
fn parse(input: &str) -> Vec {
input
.lines()
@@ -27,7 +26,9 @@ fn parse(input: &str) -> Vec {
}
#[aoc(day4, part1)]
-fn part1(input: &[utils::Card]) -> u32 {
+#[must_use]
+pub fn part1(input: &str) -> u32 {
+ let input = parse(input);
input
.iter()
.map(|card| match card.get_n_matches() {
@@ -38,7 +39,9 @@ fn part1(input: &[utils::Card]) -> u32 {
}
#[aoc(day4, part2)]
-fn part2(input: &[utils::Card]) -> u32 {
+#[must_use]
+pub fn part2(input: &str) -> u32 {
+ let input = parse(input);
let mut card_count: Vec = vec![1; input.len()];
input
.iter()
@@ -88,12 +91,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 13);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 13);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 30);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 30);
}
}
diff --git a/aoc2023/src/day5.rs b/aoc2023/src/day5.rs
index ad93c41..ca1fed3 100644
--- a/aoc2023/src/day5.rs
+++ b/aoc2023/src/day5.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day5)]
fn parse(input: &str) -> utils::Almanac {
use itertools::Itertools;
@@ -40,7 +39,9 @@ fn parse(input: &str) -> utils::Almanac {
}
#[aoc(day5, part1)]
-fn part1(input: &utils::Almanac) -> u64 {
+#[must_use]
+pub fn part1(input: &str) -> u64 {
+ let input = parse(input);
let utils::Almanac { seeds, mappings } = input;
seeds
.iter()
@@ -59,7 +60,9 @@ fn part1(input: &utils::Almanac) -> u64 {
}
#[aoc(day5, part2)]
-fn part2(input: &utils::Almanac) -> u64 {
+#[must_use]
+pub fn part2(input: &str) -> u64 {
+ let input = parse(input);
let utils::Almanac { seeds, mappings } = input;
seeds
.chunks(2)
@@ -196,12 +199,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 35);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 35);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 46);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 46);
}
}
diff --git a/aoc2023/src/day6.rs b/aoc2023/src/day6.rs
index 267727b..35d9769 100644
--- a/aoc2023/src/day6.rs
+++ b/aoc2023/src/day6.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day6)]
fn parse(input: &str) -> smallvec::SmallVec<[utils::RaceData; 4]> {
use itertools::Itertools;
@@ -20,13 +19,16 @@ fn parse(input: &str) -> smallvec::SmallVec<[utils::RaceData; 4]> {
}
#[aoc(day6, part1)]
-fn part1(input: &[utils::RaceData]) -> u64 {
+pub fn part1(input: &str) -> u64 {
+ let input = parse(input);
input.iter().map(utils::RaceData::n_record_breaks).product()
}
#[aoc(day6, part2)]
-fn part2(input: &[utils::RaceData]) -> u64 {
- utils::RaceData::merge(input).n_record_breaks1()
+#[must_use]
+pub fn part2(input: &str) -> u64 {
+ let input = parse(input);
+ utils::RaceData::merge(&input).n_record_breaks1()
}
mod utils {
@@ -77,12 +79,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 288);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 288);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 71503);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 71503);
}
}
diff --git a/aoc2023/src/day7.rs b/aoc2023/src/day7.rs
index f5921e7..5aa8d22 100644
--- a/aoc2023/src/day7.rs
+++ b/aoc2023/src/day7.rs
@@ -1,23 +1,17 @@
-use aoc_runner_derive::{aoc, aoc_generator};
-
-#[aoc_generator(day7, part1)]
-fn parse1(input: &str) -> Vec> {
- utils::parse(input)
-}
-
-#[aoc_generator(day7, part2)]
-fn parse2(input: &str) -> Vec> {
- utils::parse(input)
-}
+use aoc_runner_derive::aoc;
#[aoc(day7, part1)]
-fn part1(input: &[utils::CardHandWithBid]) -> u64 {
- utils::solve(input)
+#[must_use]
+pub fn part1(input: &str) -> u64 {
+ let input: Vec> = utils::parse(input);
+ utils::solve(&input)
}
#[aoc(day7, part2)]
-fn part2(input: &[utils::CardHandWithBid]) -> u64 {
- utils::solve(input)
+#[must_use]
+pub fn part2(input: &str) -> u64 {
+ let input: Vec> = utils::parse(input);
+ utils::solve(&input)
}
mod utils {
@@ -300,12 +294,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse1(SAMPLE)), 6440);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 6440);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse2(SAMPLE)), 5905);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 5905);
}
}
diff --git a/aoc2023/src/day8.rs b/aoc2023/src/day8.rs
index 0c577b5..cc79d4a 100644
--- a/aoc2023/src/day8.rs
+++ b/aoc2023/src/day8.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day8)]
fn parse(input: &str) -> utils::Network {
use itertools::Itertools;
@@ -35,7 +34,9 @@ fn parse(input: &str) -> utils::Network {
}
#[aoc(day8, part1)]
-fn part1(input: &utils::Network) -> u64 {
+#[must_use]
+pub fn part1(input: &str) -> u64 {
+ let input = parse(input);
// Begin at "AAA"
let mut current_node = "AAA";
@@ -58,7 +59,8 @@ fn part1(input: &utils::Network) -> u64 {
}
#[aoc(day8, part2)]
-fn part2(input: &utils::Network) -> u64 {
+pub fn part2(input: &str) -> u64 {
+ let input = parse(input);
// Find all nodes that end with 'A'
let mut nodes: smallvec::SmallVec<[&str; 8]> = input
.map
@@ -117,7 +119,7 @@ mod tests {
use indoc::indoc;
#[test]
- fn part1_example() {
+ pub fn part1_example() {
const SAMPLE: &str = indoc! {"
LLR
@@ -125,11 +127,11 @@ mod tests {
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)
"};
- assert_eq!(part1(&parse(SAMPLE)), 6);
+ assert_eq!(part1(SAMPLE), 6);
}
#[test]
- fn part2_example() {
+ pub fn part2_example() {
const SAMPLE: &str = indoc! {"
LR
@@ -142,6 +144,6 @@ mod tests {
22Z = (22B, 22B)
XXX = (XXX, XXX)
"};
- assert_eq!(part2(&parse(SAMPLE)), 6);
+ assert_eq!(part2(SAMPLE), 6);
}
}
diff --git a/aoc2023/src/day9.rs b/aoc2023/src/day9.rs
index 5d9a90b..ae864f3 100644
--- a/aoc2023/src/day9.rs
+++ b/aoc2023/src/day9.rs
@@ -1,6 +1,5 @@
-use aoc_runner_derive::{aoc, aoc_generator};
+use aoc_runner_derive::aoc;
-#[aoc_generator(day9)]
fn parse(input: &str) -> Vec> {
input
.lines()
@@ -13,7 +12,9 @@ fn parse(input: &str) -> Vec> {
}
#[aoc(day9, part1)]
-fn part1(input: &[Vec]) -> i32 {
+#[must_use]
+pub fn part1(input: &str) -> i32 {
+ let input = parse(input);
input
.iter()
.map(|seq| utils::predict_next_recursively(seq))
@@ -21,12 +22,14 @@ fn part1(input: &[Vec]) -> i32 {
}
#[aoc(day9, part2)]
-fn part2(input: &[Vec]) -> i32 {
+#[must_use]
+pub fn part2(input: &str) -> i32 {
+ let input = parse(input);
input
- .to_owned()
+ .clone()
.iter_mut()
.map(|arr| {
- arr.reverse();
+ (*arr).reverse();
arr
})
.map(|seq| utils::predict_next_recursively(seq))
@@ -58,12 +61,12 @@ mod tests {
"};
#[test]
- fn part1_example() {
- assert_eq!(part1(&parse(SAMPLE)), 114);
+ pub fn part1_example() {
+ assert_eq!(part1(SAMPLE), 114);
}
#[test]
- fn part2_example() {
- assert_eq!(part2(&parse(SAMPLE)), 2);
+ pub fn part2_example() {
+ assert_eq!(part2(SAMPLE), 2);
}
}