├── rustfmt.toml
├── docs
├── index.html
├── logo.png
└── pie-2015.svg
├── .gitignore
├── tests
├── year2021
│ ├── day24.rs
│ ├── day06.rs
│ ├── day07.rs
│ ├── day17.rs
│ ├── day12.rs
│ ├── day02.rs
│ ├── day09.rs
│ ├── day01.rs
│ ├── day21.rs
│ ├── day23.rs
│ ├── day03.rs
│ ├── day25.rs
│ ├── day05.rs
│ ├── day11.rs
│ ├── day15.rs
│ ├── day14.rs
│ ├── day10.rs
│ ├── day13.rs
│ ├── day04.rs
│ ├── day18.rs
│ ├── day20.rs
│ ├── day08.rs
│ └── day16.rs
├── year2024
│ ├── day14.rs
│ ├── day18.rs
│ ├── day20.rs
│ ├── day11.rs
│ ├── day09.rs
│ ├── day01.rs
│ ├── day21.rs
│ ├── day02.rs
│ ├── day10.rs
│ ├── day19.rs
│ ├── day22.rs
│ ├── day04.rs
│ ├── day06.rs
│ ├── day08.rs
│ ├── day03.rs
│ ├── day17.rs
│ ├── day05.rs
│ ├── day13.rs
│ ├── day23.rs
│ ├── day12.rs
│ ├── day16.rs
│ ├── day25.rs
│ ├── day07.rs
│ ├── day24.rs
│ └── day15.rs
├── year2015
│ ├── day16.rs
│ ├── day17.rs
│ ├── day18.rs
│ ├── day19.rs
│ ├── day20.rs
│ ├── day21.rs
│ ├── day22.rs
│ ├── day23.rs
│ ├── day25.rs
│ ├── day01.rs
│ ├── day03.rs
│ ├── day04.rs
│ ├── day10.rs
│ ├── day24.rs
│ ├── day02.rs
│ ├── day11.rs
│ ├── day12.rs
│ ├── day08.rs
│ ├── day09.rs
│ ├── day07.rs
│ ├── day14.rs
│ ├── day06.rs
│ ├── day05.rs
│ ├── day15.rs
│ └── day13.rs
├── year2016
│ ├── day05.rs
│ ├── day08.rs
│ ├── day10.rs
│ ├── day13.rs
│ ├── day16.rs
│ ├── day18.rs
│ ├── day22.rs
│ ├── day23.rs
│ ├── day25.rs
│ ├── day19.rs
│ ├── day14.rs
│ ├── day09.rs
│ ├── day17.rs
│ ├── day20.rs
│ ├── day02.rs
│ ├── day03.rs
│ ├── day01.rs
│ ├── day04.rs
│ ├── day24.rs
│ ├── day15.rs
│ ├── day06.rs
│ ├── day07.rs
│ ├── day11.rs
│ ├── day21.rs
│ └── day12.rs
├── year2017
│ ├── day06.rs
│ ├── day16.rs
│ ├── day18.rs
│ ├── day21.rs
│ ├── day17.rs
│ ├── day23.rs
│ ├── day11.rs
│ ├── day14.rs
│ ├── day05.rs
│ ├── day10.rs
│ ├── day22.rs
│ ├── day13.rs
│ ├── day01.rs
│ ├── day03.rs
│ ├── day15.rs
│ ├── day24.rs
│ ├── day08.rs
│ ├── day09.rs
│ ├── day12.rs
│ ├── day02.rs
│ ├── day20.rs
│ ├── day19.rs
│ ├── day04.rs
│ ├── day07.rs
│ └── day25.rs
├── year2018
│ ├── day10.rs
│ ├── day16.rs
│ ├── day18.rs
│ ├── day19.rs
│ ├── day21.rs
│ ├── day05.rs
│ ├── day11.rs
│ ├── day14.rs
│ ├── day01.rs
│ ├── day08.rs
│ ├── day22.rs
│ ├── day03.rs
│ ├── day09.rs
│ ├── day20.rs
│ ├── day06.rs
│ ├── day15.rs
│ ├── day25.rs
│ ├── day17.rs
│ ├── day02.rs
│ ├── day12.rs
│ ├── day13.rs
│ ├── day07.rs
│ ├── day23.rs
│ ├── day24.rs
│ └── day04.rs
├── year2019
│ ├── day07.rs
│ ├── day08.rs
│ ├── day11.rs
│ ├── day13.rs
│ ├── day15.rs
│ ├── day17.rs
│ ├── day19.rs
│ ├── day21.rs
│ ├── day23.rs
│ ├── day25.rs
│ ├── day01.rs
│ ├── day04.rs
│ ├── day03.rs
│ ├── day24.rs
│ ├── day12.rs
│ ├── day16.rs
│ ├── day09.rs
│ ├── day06.rs
│ ├── day22.rs
│ ├── day05.rs
│ ├── day14.rs
│ ├── day18.rs
│ ├── day02.rs
│ └── day10.rs
├── year2023
│ ├── day20.rs
│ ├── day21.rs
│ ├── day23.rs
│ ├── day15.rs
│ ├── day06.rs
│ ├── day09.rs
│ ├── day07.rs
│ ├── day24.rs
│ ├── day22.rs
│ ├── day12.rs
│ ├── day14.rs
│ ├── day03.rs
│ ├── day11.rs
│ ├── day16.rs
│ ├── day13.rs
│ ├── day17.rs
│ ├── day01.rs
│ ├── day25.rs
│ ├── day10.rs
│ ├── day18.rs
│ ├── day04.rs
│ ├── day08.rs
│ ├── day02.rs
│ ├── day19.rs
│ └── day05.rs
├── year2025
│ ├── day12.rs
│ ├── day09.rs
│ ├── day01.rs
│ ├── day05.rs
│ ├── day06.rs
│ ├── day03.rs
│ ├── day10.rs
│ ├── day04.rs
│ ├── day02.rs
│ ├── day07.rs
│ ├── day08.rs
│ └── day11.rs
├── year2020
│ ├── day15.rs
│ ├── day23.rs
│ ├── day17.rs
│ ├── day05.rs
│ ├── day13.rs
│ ├── day25.rs
│ ├── day12.rs
│ ├── day02.rs
│ ├── day01.rs
│ ├── day09.rs
│ ├── day06.rs
│ ├── day10.rs
│ ├── day08.rs
│ ├── day22.rs
│ ├── day11.rs
│ ├── day21.rs
│ ├── day18.rs
│ ├── day14.rs
│ ├── day16.rs
│ ├── day07.rs
│ ├── day24.rs
│ ├── day03.rs
│ ├── day19.rs
│ └── day04.rs
└── year2022
│ ├── day06.rs
│ ├── day02.rs
│ ├── day17.rs
│ ├── day08.rs
│ ├── day20.rs
│ ├── day12.rs
│ ├── day14.rs
│ ├── day09.rs
│ ├── day04.rs
│ ├── day24.rs
│ ├── day23.rs
│ ├── day01.rs
│ ├── day25.rs
│ ├── day18.rs
│ ├── day05.rs
│ ├── day03.rs
│ ├── day22.rs
│ ├── day21.rs
│ ├── day13.rs
│ ├── day07.rs
│ ├── day19.rs
│ ├── day16.rs
│ ├── day11.rs
│ └── day15.rs
├── justfile
├── src
├── year2025
│ ├── day12.rs
│ ├── day07.rs
│ ├── day03.rs
│ ├── day01.rs
│ ├── day05.rs
│ ├── day06.rs
│ ├── day11.rs
│ ├── day02.rs
│ └── day04.rs
├── util
│ ├── ansi.rs
│ ├── bitset.rs
│ └── integer.rs
├── year2015
│ ├── day01.rs
│ ├── day02.rs
│ ├── day03.rs
│ └── day16.rs
├── year2019
│ ├── day09.rs
│ ├── day05.rs
│ ├── day01.rs
│ └── day21.rs
├── year2017
│ ├── day01.rs
│ ├── day09.rs
│ ├── day02.rs
│ ├── day19.rs
│ ├── day08.rs
│ └── day17.rs
├── year2016
│ ├── day03.rs
│ ├── day20.rs
│ ├── day06.rs
│ ├── day02.rs
│ ├── day09.rs
│ ├── day25.rs
│ ├── day15.rs
│ └── day23.rs
├── year2020
│ ├── day03.rs
│ ├── day05.rs
│ └── day10.rs
├── year2022
│ ├── day02.rs
│ ├── day01.rs
│ ├── day10.rs
│ └── day04.rs
├── year2024
│ ├── day01.rs
│ ├── day25.rs
│ └── day05.rs
├── year2021
│ ├── day06.rs
│ ├── day01.rs
│ └── day07.rs
├── year2023
│ ├── day04.rs
│ └── day02.rs
└── year2018
│ └── day02.rs
├── .github
└── workflows
│ ├── checks.yml
│ └── docs.yml
└── LICENSE.md
/rustfmt.toml:
--------------------------------------------------------------------------------
1 | use_small_heuristics = "Max"
2 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maneatingape/advent-of-code-rust/HEAD/docs/logo.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Cargo
2 | target/
3 | Cargo.lock
4 |
5 | # macOS
6 | .DS_Store
7 |
8 | # Don't commit input files
9 | input
10 |
--------------------------------------------------------------------------------
/tests/year2021/day24.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No test
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No test
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2024/day14.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No test
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No test
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2024/day18.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No test
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No test
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2024/day20.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No test
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No test
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day16.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day17.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day18.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day19.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day20.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day21.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day22.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day23.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2015/day25.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day05.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day08.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day10.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day13.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day16.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day18.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day22.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day23.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day25.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2017/day06.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2017/day16.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2017/day18.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2017/day21.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2018/day10.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2018/day16.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2018/day18.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2018/day19.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2018/day21.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day07.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day08.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day11.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day13.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day15.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day17.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day19.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day21.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day23.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2019/day25.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2023/day20.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2023/day21.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // No example data
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // No example data
9 | }
10 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | lint:
2 | cargo fmt -- `find . -name "*.rs"`
3 | cargo clippy --all-targets --all-features
4 |
5 | docs:
6 | cargo doc --document-private-items --open
7 |
--------------------------------------------------------------------------------
/tests/year2025/day12.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // Specific to real actual input.
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // Not applicable.
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2023/day23.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn part1_test() {
3 | // Dependent on actual input structure.
4 | }
5 |
6 | #[test]
7 | fn part2_test() {
8 | // Dependent on actual input structure.
9 | }
10 |
--------------------------------------------------------------------------------
/tests/year2016/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day19::*;
2 |
3 | const EXAMPLE: &str = "5";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 3);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 2);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day01::*;
2 |
3 | const EXAMPLE: &str = "()())";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), -1);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 5);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day03::*;
2 |
3 | const EXAMPLE: &str = "^v^v^v^v^v";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 2);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 11);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day04::*;
2 |
3 | const EXAMPLE: &str = "cxsaadws";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 218);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 455);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day10::*;
2 |
3 | const EXAMPLE: &str = "12";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 124496);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 1766402);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2016/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day14::*;
2 |
3 | const EXAMPLE: &str = "abc";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 22728);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), 22551);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day17::*;
2 |
3 | const EXAMPLE: &str = "3";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 638);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 1222153);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day23::*;
2 |
3 | const EXAMPLE: &str = "123";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 14641);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 913);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2020/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day15::*;
2 |
3 | const EXAMPLE: &str = "0,3,6";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 436);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 175594);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2016/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day09::*;
2 |
3 | const EXAMPLE: &str = "X(8x2)(3x3)ABCY";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 18);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), 20);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2016/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day17::*;
2 |
3 | const EXAMPLE: &str = "ihgpwlah";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), "DDRRRD");
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 370);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day11::*;
2 |
3 | const EXAMPLE: &str = "se,sw,se,sw,sw,s,n";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 3);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 4);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day14::*;
2 |
3 | const EXAMPLE: &str = "flqrgnkx";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 8108);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 1242);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2018/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day05::*;
2 |
3 | const EXAMPLE: &str = "dabAcCaCBAcCcaDA";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 10);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 4);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2018/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day11::*;
2 |
3 | const EXAMPLE: &str = "18";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), "33,45");
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), "90,269,16");
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2019/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day01::*;
2 |
3 | const EXAMPLE: &str = "100756";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 33583);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 50346);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2019/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day04::*;
2 |
3 | const EXAMPLE: &str = "100000-200000";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 1231);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 898);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day24::*;
2 |
3 | const EXAMPLE: &str = "1 2 3 4 5 7 8 9 10 11";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 99);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 44);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2018/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day14::*;
2 |
3 | const EXAMPLE: &str = "594142";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), "1291321443");
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 2018);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2021/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day06::*;
2 |
3 | const EXAMPLE: &str = "3,4,3,1,2";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 5934);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 26984457539);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2024/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day11::*;
2 |
3 | const EXAMPLE: &str = "125 17";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 55312);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 65601038650482);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 2x3x4
5 | 1x1x10";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 101);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 48);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2015/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day11::*;
2 |
3 | const EXAMPLE: &str = "ghijklmn";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), "ghjaabcc");
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), "ghjbbcdd");
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2015/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day12::*;
2 |
3 | const EXAMPLE: &str = r#"[1,{"c":"red","b":2},3]"#;
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 6);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), 4);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2020/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day23::*;
2 |
3 | const EXAMPLE: &str = "389125467";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 67384529);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 149245887792);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2021/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day07::*;
2 |
3 | const EXAMPLE: &str = "16,1,2,0,4,2,7,1,2,14";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 37);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 168);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2024/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day09::*;
2 |
3 | const EXAMPLE: &str = "2333133121414131402";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 1928);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 2858);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2018/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | +1
5 | -2
6 | +3
7 | +1";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 3);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 2);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2020/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day17::*;
2 |
3 | const EXAMPLE: &str = "\
4 | .#.
5 | ..#
6 | ###";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 112);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 848);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2022/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day06::*;
2 |
3 | const EXAMPLE: &str = "mjqjpqmgbljsphdztnvjfqwrcgsmlb";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 7);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), 19);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0
5 | 3
6 | 0
7 | 1
8 | -3";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 5);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 10);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2017/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day10::*;
2 |
3 | const EXAMPLE: &str = "1,2,3";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 0);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), "3efbe78a8d82f29979031a4aa0b16a9d");
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2017/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ..#
5 | #..
6 | ...";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 5587);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 2511944);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2018/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day08::*;
2 |
3 | const EXAMPLE: &str = "2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 138);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 66);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2019/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | R8,U5,L5,D3
5 | U7,R6,D4,L4";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 6);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 30);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2020/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | FBFBBFFLRR
5 | FBFBBFFRLR";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 357);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 356);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2021/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day17::*;
2 |
3 | const EXAMPLE: &str = "target area: x=20..30, y=-10..-5";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 45);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 112);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2022/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | A Y
5 | B X
6 | C Z
7 | ";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 15);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 12);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2017/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0: 3
5 | 1: 2
6 | 4: 4
7 | 6: 4";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 24);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 10);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2018/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | depth: 510
5 | target: 10,10";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 114);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 45);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2020/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 939
5 | 7,13,x,x,59,x,31,19";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 295);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 1068781);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2020/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 5764801
5 | 17807724";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 14897079);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), "n/a");
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2016/day20.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day20::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 5-8
5 | 0-2
6 | 4-7
7 | 10-4294967295";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 3);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 2);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2020/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | F10
5 | N3
6 | F7
7 | R90
8 | F11";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 25);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 286);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2015/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day08::*;
2 |
3 | const EXAMPLE: &str = r#"""
4 | "abc"
5 | "aaa\"aaa"
6 | "\x27"
7 | "#;
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(input), 12);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(input), 19);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2016/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ULL
5 | RRDDD
6 | LURDL
7 | UUUUD";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), "1985");
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), "5DB3");
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2016/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 101 201 301
5 | 102 102 402
6 | 203 203 303";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 2);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 2);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2022/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day17::*;
2 |
3 | const EXAMPLE: &str = ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(input), 3068);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(input), 1514285714288);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2018/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #1 @ 1,3: 4x4
5 | #2 @ 3,1: 4x4
6 | #3 @ 5,5: 2x2";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 4);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 3);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2018/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day09::*;
2 |
3 | const EXAMPLE: &str = "10 players; last marble is worth 1618 points";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 8317);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 74765078);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2022/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 30373
5 | 25512
6 | 65332
7 | 33549
8 | 35390";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 21);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 8);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2023/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day15::*;
2 |
3 | const EXAMPLE: &str = "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 1320);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 145);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2020/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1-3 a: abcde
5 | 1-3 b: cdefg
6 | 2-9 c: ccccccccc";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 2);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 1);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2022/day20.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day20::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1
5 | 2
6 | -3
7 | 3
8 | -2
9 | 0
10 | 4";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 3);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 1623178306);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2023/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Time: 7 15 30
5 | Distance: 9 40 200";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 288);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 71503);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2018/day20.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day20::*;
2 |
3 | const EXAMPLE: &str = "^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$";
4 |
5 | #[test]
6 | fn part1_test() {
7 | let input = parse(EXAMPLE);
8 | assert_eq!(part1(&input), 31);
9 | }
10 |
11 | #[test]
12 | fn part2_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part2(&input), 0);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/year2023/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0 3 6 9 12 15
5 | 1 3 6 10 15 21
6 | 10 13 16 21 30 45";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 114);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 2);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2017/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day01::*;
2 |
3 | const FIRST_EXAMPLE: &str = "1122";
4 |
5 | const SECOND_EXAMPLE: &str = "1212";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(FIRST_EXAMPLE);
10 | assert_eq!(part1(input), 3);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(SECOND_EXAMPLE);
16 | assert_eq!(part2(input), 6);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2017/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day03::*;
2 |
3 | const FIRST_EXAMPLE: &str = "1024";
4 |
5 | const SECOND_EXAMPLE: &str = "805";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(FIRST_EXAMPLE);
10 | assert_eq!(part1(&input), 31);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(SECOND_EXAMPLE);
16 | assert_eq!(part2(&input), 806);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2017/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Generator A starts with 65
5 | Generator B starts with 8921";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 588);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 309);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2020/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1721
5 | 979
6 | 366
7 | 299
8 | 675
9 | 1456";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 514579);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 241861950);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2022/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Sabqponm
5 | abcryxxl
6 | accszExk
7 | acctuvwj
8 | abdefghi";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 31);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 29);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2022/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day14::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 498,4 -> 498,6 -> 496,6
5 | 503,4 -> 502,4 -> 502,9 -> 494,9";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 24);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 93);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2024/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 3 4
5 | 4 3
6 | 2 5
7 | 1 3
8 | 3 9
9 | 3 3";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 11);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 31);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2024/day21.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day21::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 029A
5 | 980A
6 | 179A
7 | 456A
8 | 379A";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 126384);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 154115708116294);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2017/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0/2
5 | 2/2
6 | 2/3
7 | 3/4
8 | 3/5
9 | 0/1
10 | 10/1
11 | 9/10";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 31);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 19);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2018/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1, 1
5 | 1, 6
6 | 8, 3
7 | 3, 4
8 | 5, 5
9 | 8, 9";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 17);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2_testable(&input, 32), 16);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2019/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ....#
5 | #..#.
6 | #..##
7 | ..#..
8 | #....";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 2129920);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2_testable(&input, 10), 99);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2021/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | start-A
5 | start-b
6 | A-c
7 | A-b
8 | b-d
9 | A-end
10 | b-end";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 10);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 36);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2022/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | R 4
5 | U 4
6 | L 3
7 | D 1
8 | R 4
9 | D 1
10 | L 5
11 | R 2";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 13);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 1);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2025/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 7,1
5 | 11,1
6 | 11,7
7 | 9,7
8 | 9,5
9 | 2,5
10 | 2,3
11 | 7,3";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 50);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 24);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2022/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 2-4,6-8
5 | 2-3,4-5
6 | 5-7,7-9
7 | 2-8,3-7
8 | 6-6,4-6
9 | 2-6,4-8";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 2);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 4);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2023/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 32T3K 765
5 | T55J5 684
6 | KK677 28
7 | KTJJT 220
8 | QQQJA 483";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 6440);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 5905);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2016/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day01::*;
2 |
3 | const FIRST_EXAMPLE: &str = "R5, L5, R5, R3";
4 | const SECOND_EXAMPLE: &str = "R8, R4, R4, R8";
5 |
6 | #[test]
7 | fn part1_test() {
8 | let input = parse(FIRST_EXAMPLE);
9 | assert_eq!(part1(&input), 12);
10 | }
11 |
12 | #[test]
13 | fn part2_test() {
14 | let input = parse(SECOND_EXAMPLE);
15 | assert_eq!(part2(&input), 4);
16 | }
17 |
--------------------------------------------------------------------------------
/tests/year2016/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | aaaaa-bbb-z-y-x-123[abxyz]
5 | a-b-c-d-e-f-g-h-987[abcde]
6 | not-a-real-room-404[oarel]
7 | totally-real-room-200[decoy]";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 1514);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | // No example data
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2016/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ###########
5 | #0.1.....2#
6 | #.#######.#
7 | #4.......3#
8 | ###########";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 14);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 20);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2021/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | forward 5
5 | down 5
6 | forward 8
7 | up 3
8 | down 8
9 | forward 2";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 150);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 900);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2021/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 2199943210
5 | 3987894921
6 | 9856789892
7 | 8767896789
8 | 9899965678";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 15);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 1134);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2022/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #.######
5 | #>>.<^<#
6 | #.<..<<#
7 | #>v.><>#
8 | #<^v^^>#
9 | ######.#";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 18);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 54);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2015/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | London to Dublin = 464
5 | London to Belfast = 518
6 | Dublin to Belfast = 141";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 605);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 982);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2021/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 199
5 | 200
6 | 208
7 | 210
8 | 200
9 | 207
10 | 240
11 | 269
12 | 260
13 | 263";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 7);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 5);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2021/day21.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day21::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Player 1 starting position: 4
5 | Player 2 starting position: 8";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 739785);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 444356092776315);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2024/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 7 6 4 2 1
5 | 1 2 7 8 9
6 | 9 7 6 2 1
7 | 1 3 2 4 5
8 | 8 6 4 4 1
9 | 1 3 6 7 9";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 2);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 4);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2025/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | L68
5 | L30
6 | R48
7 | L5
8 | R60
9 | L55
10 | L1
11 | L99
12 | R14
13 | L82";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 3);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 6);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2017/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | b inc 5 if a > 1
5 | a inc 1 if b < 5
6 | c dec -10 if a >= 1
7 | c inc -20 if c == 10";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 1);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 10);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2022/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day23::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ....#..
5 | ..###.#
6 | #...#.#
7 | .#...##
8 | #.###..
9 | ##.#.##
10 | .#..#..";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 110);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 20);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2025/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 3-5
5 | 10-14
6 | 16-20
7 | 12-18
8 |
9 | 1
10 | 5
11 | 8
12 | 11
13 | 17
14 | 32";
15 |
16 | #[test]
17 | fn part1_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part1(&input), 3);
20 | }
21 |
22 | #[test]
23 | fn part2_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part2(&input), 14);
26 | }
27 |
--------------------------------------------------------------------------------
/tests/year2025/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 123 328 51 64
5 | 45 64 387 23
6 | 6 98 215 314
7 | * + * + ";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 4277556);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 3263827);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2018/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #######
5 | #.G...#
6 | #...EG#
7 | #.#.#G#
8 | #..G#E#
9 | #.....#
10 | #######";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 27730);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 4988);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2020/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day09::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 35 20 15 25 47
5 | 40 62 55 65 95
6 | 102 117 150 182 127
7 | 219 299 277 309 576";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let result = decrypt::<5>(EXAMPLE);
12 | assert_eq!(result.0, 127);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let result = decrypt::<5>(EXAMPLE);
18 | assert_eq!(result.1, 62);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2021/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day23::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #############
5 | #...........#
6 | ###B#C#B#D###
7 | #A#D#C#A#
8 | #########";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 12521);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 44169);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2023/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 19, 13, 30 @ -2, 1, -2
5 | 18, 19, 22 @ -1, -1, -2
6 | 20, 25, 34 @ -2, -2, -4
7 | 12, 31, 28 @ -1, -2, -1
8 | 20, 19, 15 @ 1, -5, -3";
9 |
10 | #[test]
11 | fn part1_test() {
12 | // No example data
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 47);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2025/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 987654321111111
5 | 811111111111119
6 | 234234234234278
7 | 818181911112111";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 357);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 3121910778619);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2017/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day09::*;
2 |
3 | const FIRST_EXAMPLE: &str = "{{},{},{},{}}";
4 |
5 | const SECOND_EXAMPLE: &str = "<{o\"i!a,<{i";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(FIRST_EXAMPLE);
10 | assert_eq!(part1(&input), 3);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(SECOND_EXAMPLE);
16 | assert_eq!(part2(&input), 10);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2019/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day12::*;
2 |
3 | const EXAMPLE: &str = "
4 |
5 |
6 |
7 | ";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 14645);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 4686774924);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2020/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | abc
5 |
6 | a
7 | b
8 | c
9 |
10 | ab
11 | ac
12 |
13 | a
14 | a
15 | a
16 | a
17 |
18 | b";
19 |
20 | #[test]
21 | fn part1_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part1(&input), 11);
24 | }
25 |
26 | #[test]
27 | fn part2_test() {
28 | let input = parse(EXAMPLE);
29 | assert_eq!(part2(&input), 6);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/year2020/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day10::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 28 33 18 42 31 14 46 20 48 47
5 | 24 23 49 45 19 38 39 11 1 32
6 | 25 35 8 17 7 9 4 2 34 10 3";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 220);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 19208);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2017/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0 <-> 2
5 | 1 <-> 1
6 | 2 <-> 0, 3, 4
7 | 3 <-> 2, 4
8 | 4 <-> 2, 3, 6
9 | 5 <-> 6
10 | 6 <-> 4, 5";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 6);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 2);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2020/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | nop +0
5 | acc +1
6 | jmp +4
7 | acc +3
8 | jmp -3
9 | acc -99
10 | acc +1
11 | jmp -4
12 | acc +6";
13 |
14 | #[test]
15 | fn part1_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part1(&input), 5);
18 | }
19 |
20 | #[test]
21 | fn part2_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part2(&input), 8);
24 | }
25 |
--------------------------------------------------------------------------------
/tests/year2020/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Player 1:
5 | 9
6 | 2
7 | 6
8 | 3
9 | 1
10 |
11 | Player 2:
12 | 5
13 | 8
14 | 4
15 | 7
16 | 10";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), 306);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), 291);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2024/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day10::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 89010123
5 | 78121874
6 | 87430965
7 | 96549874
8 | 45678903
9 | 32019012
10 | 01329801
11 | 10456732";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 36);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 81);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2023/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1,0,1~1,2,1
5 | 0,0,2~2,0,2
6 | 0,2,3~2,2,3
7 | 0,0,4~0,2,4
8 | 2,0,5~2,2,5
9 | 0,1,6~2,1,6
10 | 1,1,8~1,1,9";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 5);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 7);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2016/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Disc #1 has 5 positions; at time=0, it is at position 4.
5 | Disc #2 has 2 positions; at time=0, it is at position 1.";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1(&input), 5);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2(&input), 85);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2024/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day19::*;
2 |
3 | const EXAMPLE: &str = "\
4 | r, wr, b, g, bwu, rb, gb, br
5 |
6 | brwrr
7 | bggr
8 | gbbr
9 | rrbgbr
10 | ubwu
11 | bwurrg
12 | brgr
13 | bbrgwb";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 6);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 16);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2019/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day16::*;
2 |
3 | const FIRST_EXAMPLE: &str = "80871224585914546619083218645595";
4 | const SECOND_EXAMPLE: &str = "03036732577212944063491565474664";
5 |
6 | #[test]
7 | fn part1_test() {
8 | let input = parse(FIRST_EXAMPLE);
9 | assert_eq!(part1(&input), 24176176);
10 | }
11 |
12 | #[test]
13 | fn part2_test() {
14 | let input = parse(SECOND_EXAMPLE);
15 | assert_eq!(part2(&input), 84462026);
16 | }
17 |
--------------------------------------------------------------------------------
/tests/year2021/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 00100
5 | 11110
6 | 10110
7 | 10111
8 | 10101
9 | 01111
10 | 00111
11 | 11100
12 | 10000
13 | 11001
14 | 00010
15 | 01010";
16 |
17 | #[test]
18 | fn part1_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part1(&input), 198);
21 | }
22 |
23 | #[test]
24 | fn part2_test() {
25 | let input = parse(EXAMPLE);
26 | assert_eq!(part2(&input), 230);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/year2022/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day01::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1000
5 | 2000
6 | 3000
7 |
8 | 4000
9 |
10 | 5000
11 | 6000
12 |
13 | 7000
14 | 8000
15 | 9000
16 |
17 | 10000";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1(&input), 24000);
23 | }
24 |
25 | #[test]
26 | fn part2_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part2(&input), 45000);
29 | }
30 |
--------------------------------------------------------------------------------
/tests/year2022/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1=-0-2
5 | 12111
6 | 2=0=
7 | 21
8 | 2=01
9 | 111
10 | 20012
11 | 112
12 | 1=-1=
13 | 1-12
14 | 12
15 | 1=
16 | 122";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), "2=-1=0");
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), "n/a");
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2024/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day22::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | 1
5 | 10
6 | 100
7 | 2024";
8 |
9 | const SECOND_EXAMPLE: &str = "\
10 | 1
11 | 2
12 | 3
13 | 2024";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(FIRST_EXAMPLE);
18 | assert_eq!(part1(&input), 37327623);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(SECOND_EXAMPLE);
24 | assert_eq!(part2(&input), 23);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2017/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day02::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | 5 1 9 5
5 | 7 5 3
6 | 2 4 6 8";
7 |
8 | const SECOND_EXAMPLE: &str = "\
9 | 5 9 2 8
10 | 9 4 7 3
11 | 3 8 6 5";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(FIRST_EXAMPLE);
16 | assert_eq!(part1(&input), 18);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(SECOND_EXAMPLE);
22 | assert_eq!(part2(&input), 9);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2015/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 123 -> b
5 | 456 -> c
6 | b AND c -> d
7 | b OR c -> e
8 | d LSHIFT 2 -> f
9 | e RSHIFT 2 -> g
10 | f OR g -> h
11 | NOT h -> a";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 65153);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 49165);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2018/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1,-1,0,1
5 | 2,0,-1,0
6 | 3,2,-1,0
7 | 0,0,3,1
8 | 0,0,-1,-1
9 | 2,3,-2,0
10 | -2,2,0,0
11 | 2,-2,0,-1
12 | 1,-1,0,-1
13 | 3,2,0,2";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 3);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), "n/a");
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2022/day18.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day18::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 2,2,2
5 | 1,2,2
6 | 3,2,2
7 | 2,1,2
8 | 2,3,2
9 | 2,2,1
10 | 2,2,3
11 | 2,2,4
12 | 2,2,6
13 | 1,2,5
14 | 3,2,5
15 | 2,1,5
16 | 2,3,5";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), 64);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), 58);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2021/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | v...>>.vv>
5 | .vv>>.vv..
6 | >>.>v>...v
7 | >>v>>.>.v.
8 | v>v.vv.v..
9 | >.>>..v...
10 | .vv..>.>v.
11 | v.v..>>v.v
12 | ....v..v.>";
13 |
14 | #[test]
15 | fn part1_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part1(&input), 58);
18 | }
19 |
20 | #[test]
21 | fn part2_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part2(&input), "n/a");
24 | }
25 |
--------------------------------------------------------------------------------
/tests/year2025/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day10::*;
2 |
3 | const EXAMPLE: &str = "\
4 | [.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
5 | [...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
6 | [.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 7);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | // No working part two yet.
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2017/day20.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day20::*;
2 |
3 | const EXAMPLE: &str = "\
4 | p=<-6,0,0>, v=< 3,0,0>, a=< 0,0,0>
5 | p=<-4,0,0>, v=< 2,0,0>, a=< 0,0,0>
6 | p=<-2,0,0>, v=< 1,0,0>, a=< 0,0,0>
7 | p=< 3,0,0>, v=<-1,0,0>, a=< 0,0,0>";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 3);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 1);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2020/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day11::*;
2 |
3 | const EXAMPLE: &str = "\
4 | L.LL.LL.LL
5 | LLLLLLL.LL
6 | L.L.L..L..
7 | LLLL.LL.LL
8 | L.LL.LL.LL
9 | L.LLLLL.LL
10 | ..L.L.....
11 | LLLLLLLLLL
12 | L.LLLLLL.L
13 | L.LLLLL.LL";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 37);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 26);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2021/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 0,9 -> 5,9
5 | 8,0 -> 0,8
6 | 9,4 -> 3,4
7 | 2,2 -> 2,1
8 | 7,0 -> 7,4
9 | 6,4 -> 2,0
10 | 0,9 -> 2,9
11 | 3,4 -> 1,4
12 | 0,0 -> 8,8
13 | 5,5 -> 8,2";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 5);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 12);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2023/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ???.### 1,1,3
5 | .??..??...?##. 1,1,3
6 | ?#?#?#?#?#?#?#? 1,3,1,6
7 | ????.#...#... 4,1,1
8 | ????.######..#####. 1,6,5
9 | ?###???????? 3,2,1";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 21);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 525152);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2024/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | MMMSXXMASM
5 | MSAMXMSMSA
6 | AMXSXMAAMM
7 | MSAMASMSMX
8 | XMASAMXAMM
9 | XXAMMXXAMA
10 | SMSMSASXSS
11 | SAXAMASAAA
12 | MAMMMXMMMM
13 | MXMXAXMASX";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 18);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 9);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2024/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ....#.....
5 | .........#
6 | ..........
7 | ..#.......
8 | .......#..
9 | ..........
10 | .#..^.....
11 | ........#.
12 | #.........
13 | ......#...";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 41);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 6);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2025/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ..@@.@@@@.
5 | @@@.@.@.@@
6 | @@@@@.@.@@
7 | @.@@@@..@.
8 | @@.@@@@.@@
9 | .@@@@@@@.@
10 | .@.@.@.@@@
11 | @.@@@.@@@@
12 | .@@@@@@@@.
13 | @.@.@@@.@.";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 13);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 43);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2018/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day17::*;
2 |
3 | const EXAMPLE: &str = "\
4 | x=495, y=2..7
5 | y=7, x=495..501
6 | x=501, y=3..7
7 | x=498, y=2..4
8 | x=506, y=1..2
9 | x=498, y=10..13
10 | x=504, y=10..13
11 | y=13, x=498..504";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part1(&input), 57);
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part2(&input), 29);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2019/day09.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day09::*;
2 |
3 | const FIRST_EXAMPLE: &str = "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99";
4 | const SECOND_EXAMPLE: &str = "1102,34915192,34915192,7,4,7,99,0";
5 |
6 | #[test]
7 | fn part1_test() {
8 | let input = parse(FIRST_EXAMPLE);
9 | assert_eq!(part1(&input), 109);
10 | }
11 |
12 | #[test]
13 | fn part2_test() {
14 | let input = parse(SECOND_EXAMPLE);
15 | assert_eq!(part2(&input), 1219070632396864);
16 | }
17 |
--------------------------------------------------------------------------------
/tests/year2021/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day11::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 5483143223
5 | 2745854711
6 | 5264556173
7 | 6141336146
8 | 6357385478
9 | 4167524645
10 | 2176841721
11 | 6882881134
12 | 4846848554
13 | 5283751526";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 1656);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 195);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2021/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1163751742
5 | 1381373672
6 | 2136511328
7 | 3694931569
8 | 7463417111
9 | 1319128137
10 | 1359912421
11 | 3125421639
12 | 1293138521
13 | 2311944581";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 40);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 315);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2023/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day14::*;
2 |
3 | const EXAMPLE: &str = "\
4 | O....#....
5 | O.OO#....#
6 | .....##...
7 | OO.#O....O
8 | .O.....O#.
9 | O.#..O.#.#
10 | ..O..#O..O
11 | .......O..
12 | #....###..
13 | #OO..#....";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 136);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 64);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2019/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | COM)BBB
5 | BBB)CCC
6 | CCC)DDD
7 | DDD)EEE
8 | EEE)FFF
9 | BBB)GGG
10 | GGG)HHH
11 | DDD)III
12 | EEE)JJJ
13 | JJJ)KKK
14 | KKK)LLL
15 | KKK)YOU
16 | III)SAN";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), 54);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), 4);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2023/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 467..114..
5 | ...*......
6 | ..35..633.
7 | ......#...
8 | 617*......
9 | .....+.58.
10 | ..592.....
11 | ......755.
12 | ...$.*....
13 | .664.598..";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 4361);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 467835);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2023/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day11::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ...#......
5 | .......#..
6 | #.........
7 | ..........
8 | ......#...
9 | .#........
10 | .........#
11 | ..........
12 | .......#..
13 | #...#.....";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 374);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 82000210);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2023/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day16::*;
2 |
3 | const EXAMPLE: &str = "\
4 | .|...\\....
5 | |.-.\\.....
6 | .....|-...
7 | ........|.
8 | ..........
9 | .........\\
10 | ..../.\\\\..
11 | .-.-/..|..
12 | .|....-|.\\
13 | ..//.|....";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 46);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 51);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2017/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day19::*;
2 |
3 | const EXAMPLE: &str = "\
4 | . | .
5 | . | +--+ .
6 | . A | C .
7 | . F---|----E|--+ .
8 | . | | | D .
9 | . +B-+ +--+ .
10 | . .";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), "ABCDEF");
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 38);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2022/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ....[D]....
5 | [N].[C]....
6 | [Z].[M].[P]
7 | .1...2...3.
8 |
9 | move 1 from 2 to 1
10 | move 3 from 1 to 3
11 | move 2 from 2 to 1
12 | move 1 from 1 to 2";
13 |
14 | #[test]
15 | fn part1_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part1(&input), "CMZ");
18 | }
19 |
20 | #[test]
21 | fn part2_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part2(&input), "MCD");
24 | }
25 |
--------------------------------------------------------------------------------
/tests/year2022/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | vJrwpWtwJgWrhcsFMMfFFhFp
5 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
6 | PmmdzqPrVvPwwTWBwg
7 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
8 | ttgJtRGJQctTZtZT
9 | CrZsJsPPZsGzwwsLwLmpwMDw";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 157);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 70);
21 | }
22 |
--------------------------------------------------------------------------------
/src/year2025/day12.rs:
--------------------------------------------------------------------------------
1 | //! # Christmas Tree Farm
2 | use crate::util::iter::*;
3 | use crate::util::parse::*;
4 |
5 | pub fn parse(input: &str) -> &str {
6 | input
7 | }
8 |
9 | pub fn part1(input: &str) -> usize {
10 | input
11 | .iter_unsigned::()
12 | .skip(6)
13 | .chunk::<8>()
14 | .filter(|[w, h, presents @ ..]| (w / 3) * (h / 3) >= presents.iter().sum::())
15 | .count()
16 | }
17 |
18 | pub fn part2(_input: &str) -> &'static str {
19 | "n/a"
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2020/day21.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day21::*;
2 |
3 | const EXAMPLE: &str = "\
4 | mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
5 | trh fvjkl sbzzf mxmxvkd (contains dairy)
6 | sqjhc fvjkl (contains soy)
7 | sqjhc mxmxvkd sbzzf (contains fish)";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 5);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), "mxmxvkd,sqjhc,fvjkl");
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2015/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day14::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.
5 | Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.";
6 |
7 | #[test]
8 | fn part1_test() {
9 | let input = parse(EXAMPLE);
10 | assert_eq!(part1_testable(&input, 1000), 1120);
11 | }
12 |
13 | #[test]
14 | fn part2_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(part2_testable(&input, 1000), 689);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/year2025/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day02::*;
2 |
3 | const EXAMPLE: &str = "
4 | 11-22,95-115,998-1012,1188511880-1188511890,222220-222224,
5 | 1698522-1698528,446443-446449,38593856-38593862,565653-565659,
6 | 824824821-824824827,2121212118-2121212124";
7 |
8 | #[test]
9 | fn part1_test() {
10 | let input = parse(EXAMPLE);
11 | assert_eq!(part1(&input), 1227775554);
12 | }
13 |
14 | #[test]
15 | fn part2_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part2(&input), 4174379265);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/year2016/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day06::*;
2 |
3 | const EXAMPLE: &str = "\
4 | eedadn
5 | drvtee
6 | eandsr
7 | raavrd
8 | atevrs
9 | tsrnev
10 | sdttsa
11 | rasrtv
12 | nssdts
13 | ntnada
14 | svetve
15 | tesnvt
16 | vntsnd
17 | vrdear
18 | dvrsen
19 | enarar";
20 |
21 | #[test]
22 | fn part1_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part1(&input), "easter");
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(EXAMPLE);
30 | assert_eq!(part2(&input), "advent");
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2019/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | deal into new stack
5 | cut -2
6 | deal with increment 7
7 | cut 8
8 | cut -4
9 | deal with increment 7
10 | cut 3
11 | deal with increment 9
12 | deal with increment 3
13 | cut -1";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(input), 1219);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(input), 117607927195067);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2016/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day07::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | abba[mnop]qrst
5 | abcd[bddb]xyyx
6 | aaaa[qwer]tyui
7 | ioxxoj[asdfgh]zxcvbn";
8 |
9 | const SECOND_EXAMPLE: &str = "\
10 | aba[bab]xyz
11 | xyx[xyx]xyx
12 | aaa[kek]eke
13 | zazbz[bzb]cdb";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(FIRST_EXAMPLE);
18 | assert_eq!(part1(&input), 2);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(SECOND_EXAMPLE);
24 | assert_eq!(part2(&input), 3);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2023/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #.##..##.
5 | ..#.##.#.
6 | ##......#
7 | ##......#
8 | ..#.##.#.
9 | ..##..##.
10 | #.#.##.#.
11 |
12 | #...##..#
13 | #....#..#
14 | ..##..###
15 | #####.##.
16 | #####.##.
17 | ..##..###
18 | #....#..#";
19 |
20 | #[test]
21 | fn part1_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part1(&input), 405);
24 | }
25 |
26 | #[test]
27 | fn part2_test() {
28 | let input = parse(EXAMPLE);
29 | assert_eq!(part2(&input), 400);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/year2024/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ............
5 | ........0...
6 | .....0......
7 | .......0....
8 | ....0.......
9 | ......A.....
10 | ............
11 | ............
12 | ........A...
13 | .........A..
14 | ............
15 | ............";
16 |
17 | #[test]
18 | fn part1_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part1(&input), 14);
21 | }
22 |
23 | #[test]
24 | fn part2_test() {
25 | let input = parse(EXAMPLE);
26 | assert_eq!(part2(&input), 34);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/year2020/day18.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day18::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1 + 2 * 3 + 4 * 5 + 6
5 | 1 + (2 * 3) + (4 * (5 + 6))
6 | 2 * 3 + (4 * 5)
7 | 5 + (8 * 3 + 9 + 3 * 4 * 3)
8 | 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))
9 | ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 26457);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 694173);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2024/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day03::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";
5 |
6 | const SECOND_EXAMPLE: &str = "\
7 | xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(FIRST_EXAMPLE);
12 | assert_eq!(part1(&input), 161);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(SECOND_EXAMPLE);
18 | assert_eq!(part2(&input), 48);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2018/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day02::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | abcdef
5 | bababc
6 | abbcde
7 | abcccd
8 | aabcdd
9 | abcdee
10 | ababab";
11 |
12 | const SECOND_EXAMPLE: &str = "\
13 | abcde
14 | fghij
15 | klmno
16 | pqrst
17 | fguij
18 | axcye
19 | wvxyz";
20 |
21 | #[test]
22 | fn part1_test() {
23 | let input = parse(FIRST_EXAMPLE);
24 | assert_eq!(part1(&input), 12);
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(SECOND_EXAMPLE);
30 | assert_eq!(part2(&input), "fgij");
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2015/day06.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day06::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | turn on 0,0 through 999,999
5 | toggle 0,0 through 999,0
6 | turn off 499,499 through 500,500";
7 |
8 | const SECOND_EXAMPLE: &str = "\
9 | turn on 0,0 through 0,0
10 | toggle 0,0 through 999,999";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(FIRST_EXAMPLE);
15 | assert_eq!(part1(&input), 998996);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(SECOND_EXAMPLE);
21 | assert_eq!(part2(&input), 2000001);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2015/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day05::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | ugknbfddgicrmopn
5 | aaa
6 | jchzalrnumimnmhp
7 | haegwjzuvuyypxyu
8 | dvszwmarrgswjxmb";
9 |
10 | const SECOND_EXAMPLE: &str = "\
11 | qjhvhtzxzqqjkmpb
12 | xxyxx
13 | uurcxstgmygtbstg
14 | ieodomkazucvgmuy";
15 |
16 | #[test]
17 | fn part1_test() {
18 | let input = parse(FIRST_EXAMPLE);
19 | assert_eq!(part1(&input), 2);
20 | }
21 |
22 | #[test]
23 | fn part2_test() {
24 | let input = parse(SECOND_EXAMPLE);
25 | assert_eq!(part2(&input), 2);
26 | }
27 |
--------------------------------------------------------------------------------
/tests/year2021/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day14::*;
2 |
3 | const EXAMPLE: &str = "\
4 | NNCB
5 |
6 | CH -> B
7 | HH -> N
8 | CB -> H
9 | NH -> C
10 | HB -> C
11 | HC -> B
12 | HN -> C
13 | NN -> C
14 | BH -> H
15 | NC -> B
16 | NB -> B
17 | BN -> B
18 | BB -> N
19 | BC -> B
20 | CC -> N
21 | CN -> C";
22 |
23 | #[test]
24 | fn part1_test() {
25 | let input = parse(EXAMPLE);
26 | assert_eq!(part1(&input), 1588);
27 | }
28 |
29 | #[test]
30 | fn part2_test() {
31 | let input = parse(EXAMPLE);
32 | assert_eq!(part2(&input), 2188189693529);
33 | }
34 |
--------------------------------------------------------------------------------
/tests/year2017/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day04::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | aa bb cc dd ee
5 | aa bb cc dd aa
6 | aa bb cc dd aaa";
7 |
8 | const SECOND_EXAMPLE: &str = "\
9 | abcde fghij
10 | abcde xyz ecdab
11 | a ab abc abd abf abj
12 | iiii oiii ooii oooi oooo
13 | oiii ioii iioi iiio";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(FIRST_EXAMPLE);
18 | assert_eq!(part1(&input), 2);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(SECOND_EXAMPLE);
24 | assert_eq!(part2(&input), 3);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2019/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day05::*;
2 |
3 | const FIRST_EXAMPLE: &str = "3,0,4,0,99";
4 |
5 | const SECOND_EXAMPLE: &str = "\
6 | 3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,
7 | 1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,
8 | 999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(FIRST_EXAMPLE);
13 | assert_eq!(part1(&input), 1);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(SECOND_EXAMPLE);
19 | assert_eq!(part2(&input), 999);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2023/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day17::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 2413432311323
5 | 3215453535623
6 | 3255245654254
7 | 3446585845452
8 | 4546657867536
9 | 1438598798454
10 | 4457876987766
11 | 3637877979653
12 | 4654967986887
13 | 4564679986453
14 | 1224686865563
15 | 2546548887735
16 | 4322674655533";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), 102);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), 94);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2016/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day11::*;
2 |
3 | const EXAMPLE: &str = "\
4 | The first floor contains a hydrogen-compatible microchip and a lithium-compatible microchip.
5 | The second floor contains a hydrogen generator.
6 | The third floor contains a lithium generator.
7 | The fourth floor contains nothing relevant.";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 11);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 35);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2023/day01.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day01::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | 1abc2
5 | pqr3stu8vwx
6 | a1b2c3d4e5f
7 | treb7uchet";
8 |
9 | const SECOND_EXAMPLE: &str = "\
10 | two1nine
11 | eightwothree
12 | abcone2threexyz
13 | xtwone3four
14 | 4nineeightseven2
15 | zoneight234
16 | 7pqrstsixteen";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(FIRST_EXAMPLE);
21 | assert_eq!(part1(&input), 142);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(SECOND_EXAMPLE);
27 | assert_eq!(part2(&input), 281);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2022/day22.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day22::*;
2 |
3 | const EXAMPLE: &str = "\
4 | @ ...#
5 | .#..
6 | #...
7 | ....
8 | ...#.......#
9 | ........#...
10 | ..#....#....
11 | ..........#.
12 | ...#....
13 | .....#..
14 | .#......
15 | ......#.
16 |
17 | 10R5L5R10L4R5L5";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1(&input), 6032);
23 | }
24 |
25 | #[test]
26 | fn part2_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part2(&input), 5031);
29 | }
30 |
--------------------------------------------------------------------------------
/tests/year2023/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | jqt: rhn xhk nvd
5 | rsh: frs pzl lsr
6 | xhk: hfx
7 | cmg: qnr nvd lhk bvb
8 | rhn: xhk bvb hfx
9 | bvb: xhk hfx
10 | pzl: lsr hfx nvd
11 | qnr: nvd
12 | ntq: jqt hfx bvb xhk
13 | nvd: lhk
14 | lsr: lhk
15 | rzs: qnr cmg lsr rsh
16 | frs: qnr lhk lsr";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), 54);
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), "n/a");
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2022/day21.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day21::*;
2 |
3 | const EXAMPLE: &str = "\
4 | root: pppw + sjmn
5 | dbpl: 5
6 | cczh: sllz + lgvd
7 | zczc: 2
8 | ptdq: humn - dvpt
9 | dvpt: 3
10 | lfqf: 4
11 | humn: 5
12 | ljgn: 2
13 | sjmn: drzm * dbpl
14 | sllz: 4
15 | pppw: cczh / lfqf
16 | lgvd: ljgn * ptdq
17 | drzm: hmdt - zczc
18 | hmdt: 32";
19 |
20 | #[test]
21 | fn part1_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part1(&input), 152);
24 | }
25 |
26 | #[test]
27 | fn part2_test() {
28 | let input = parse(EXAMPLE);
29 | assert_eq!(part2(&input), 301);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/year2023/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day10::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | .....
5 | .S-7.
6 | .|.|.
7 | .L-J.
8 | .....";
9 |
10 | const SECOND_EXAMPLE: &str = "\
11 | ...........
12 | .S-------7.
13 | .|F-----7|.
14 | .||.....||.
15 | .||.....||.
16 | .|L-7.F-J|.
17 | .|..|.|..|.
18 | .L--J.L--J.
19 | ...........";
20 |
21 | #[test]
22 | fn part1_test() {
23 | let input = parse(FIRST_EXAMPLE);
24 | assert_eq!(part1(&input), 4);
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(SECOND_EXAMPLE);
30 | assert_eq!(part2(&input), 4);
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2024/day17.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day17::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | Register A: 729
5 | Register B: 0
6 | Register C: 0
7 |
8 | Program: 0,1,5,4,3,0";
9 |
10 | const SECOND_EXAMPLE: &str = "\
11 | Register A: 2024
12 | Register B: 0
13 | Register C: 0
14 |
15 | Program: 0,3,5,4,3,0";
16 |
17 | #[test]
18 | fn part1_test() {
19 | let input = parse(FIRST_EXAMPLE);
20 | assert_eq!(part1(&input), "4,6,3,5,6,3,5,2,1,0");
21 | }
22 |
23 | #[test]
24 | fn part2_test() {
25 | let input = parse(SECOND_EXAMPLE);
26 | assert_eq!(part2(&input), 117440);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/year2017/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | pbga (66)
5 | xhth (57)
6 | ebii (61)
7 | havc (66)
8 | ktlj (57)
9 | fwft (72) -> ktlj, cntj, xhth
10 | qoyq (66)
11 | padx (45) -> pbga, havc, qoyq
12 | tknk (41) -> ugml, padx, fwft
13 | jptl (61)
14 | ugml (68) -> gyxo, ebii, jptl
15 | gyxo (61)
16 | cntj (57)";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part1(&input), "tknk");
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part2(&input), 60);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2023/day18.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day18::*;
2 |
3 | const EXAMPLE: &str = "\
4 | R 6 (#70c710)
5 | D 5 (#0dc571)
6 | L 2 (#5713f0)
7 | D 2 (#d2c081)
8 | R 2 (#59c680)
9 | D 2 (#411b91)
10 | L 5 (#8ceee2)
11 | U 2 (#caa173)
12 | L 1 (#1b58a2)
13 | U 2 (#caa171)
14 | R 2 (#7807d2)
15 | U 3 (#a77fa3)
16 | L 2 (#015232)
17 | U 2 (#7a21e3)";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1(&input), 62);
23 | }
24 |
25 | #[test]
26 | fn part2_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part2(&input), 952408144115);
29 | }
30 |
--------------------------------------------------------------------------------
/src/util/ansi.rs:
--------------------------------------------------------------------------------
1 | //! [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
2 | //!
3 | //! These codes allow command line applications to show colored or styled text in most terminals.
4 | //! Advanced commands can move the cursor or clear the screen.
5 | pub const RESET: &str = "\x1b[0m";
6 | pub const BOLD: &str = "\x1b[1m";
7 | pub const RED: &str = "\x1b[31m";
8 | pub const GREEN: &str = "\x1b[32m";
9 | pub const YELLOW: &str = "\x1b[33m";
10 | pub const BLUE: &str = "\x1b[94m";
11 | pub const WHITE: &str = "\x1b[97m";
12 | pub const HOME: &str = "\x1b[H";
13 | pub const CLEAR: &str = "\x1b[J";
14 |
--------------------------------------------------------------------------------
/tests/year2018/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | initial state: #..#.#..##......###...###
5 |
6 | ...## => #
7 | ..#.. => #
8 | .#... => #
9 | .#.#. => #
10 | .#.## => #
11 | .##.. => #
12 | .#### => #
13 | #.#.# => #
14 | #.### => #
15 | ##.#. => #
16 | ##.## => #
17 | ###.. => #
18 | ###.# => #
19 | ####. => #";
20 |
21 | #[test]
22 | fn part1_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part1(&input), 325);
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(EXAMPLE);
30 | assert_eq!(part2(&input), 50000000501);
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2018/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day13::*;
2 |
3 | const FIRST_EXAMPLE: &str = r"/->-\ .
4 | | | /----\ .
5 | | /-+--+-\ | .
6 | | | | | v | .
7 | \-+-/ \-+--/ .
8 | \------/ .";
9 |
10 | const SECOND_EXAMPLE: &str = r"/>-<\ .
11 | | | .
12 | | /<+-\ .
13 | | | | v .
14 | \>+ | .
15 | | ^ .
16 | \<->/ .";
17 |
18 | #[test]
19 | fn part1_test() {
20 | let input = parse(FIRST_EXAMPLE);
21 | assert_eq!(part1(&input), "7,3");
22 | }
23 |
24 | #[test]
25 | fn part2_test() {
26 | let input = parse(SECOND_EXAMPLE);
27 | assert_eq!(part2(&input), "6,4");
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2020/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day14::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
5 | mem[8] = 11
6 | mem[7] = 101
7 | mem[8] = 0";
8 |
9 | const SECOND_EXAMPLE: &str = "\
10 | mask = 000000000000000000000000000000X1001X
11 | mem[42] = 100
12 | mask = 00000000000000000000000000000000X0XX
13 | mem[26] = 1";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(FIRST_EXAMPLE);
18 | assert_eq!(part1(&input), 165);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(SECOND_EXAMPLE);
24 | assert_eq!(part2(&input), 208);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2021/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day10::*;
2 |
3 | const EXAMPLE: &str = "\
4 | [({(<(())[]>[[{[]{<()<>>
5 | [(()[<>])]({[<{<<[]>>(
6 | {([(<{}[<>[]}>{[]{[(<()>
7 | (((({<>}<{<{<>}{[]{[]{}
8 | [[<[([]))<([[{}[[()]]]
9 | [{[{({}]{}}([{[{{{}}([]
10 | {<[[]]>}<{[{[{[]{()[[[]
11 | [<(<(<(<{}))><([]([]()
12 | <{([([[(<>()){}]>(<<{{
13 | <{([{{}}[<[[[<>{}]]]>[]]";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 26397);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 288957);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2022/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | [1,1,3,1,1]
5 | [1,1,5,1,1]
6 |
7 | [[1],[2,3,4]]
8 | [[1],4]
9 |
10 | [9]
11 | [[8,7,6]]
12 |
13 | [[4,4],4,4]
14 | [[4,4],4,4,4]
15 |
16 | [7,7,7,7]
17 | [7,7,7]
18 |
19 | []
20 | [3]
21 |
22 | [[[]]]
23 | [[]]
24 |
25 | [1,[2,[3,[4,[5,6,7]]]],8,9]
26 | [1,[2,[3,[4,[5,6,0]]]],8,9]";
27 |
28 | #[test]
29 | fn part1_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part1(&input), 13);
32 | }
33 |
34 | #[test]
35 | fn part2_test() {
36 | let input = parse(EXAMPLE);
37 | assert_eq!(part2(&input), 140);
38 | }
39 |
--------------------------------------------------------------------------------
/tests/year2019/day14.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day14::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 157 ORE => 5 NZVS
5 | 165 ORE => 6 DCFZ
6 | 44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
7 | 12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
8 | 179 ORE => 7 PSHF
9 | 177 ORE => 5 HKGWZ
10 | 7 DCFZ, 7 PSHF => 2 XJWVT
11 | 165 ORE => 2 GPVTF
12 | 3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT";
13 |
14 | #[test]
15 | fn part1_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part1(&input), 13312);
18 | }
19 |
20 | #[test]
21 | fn part2_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part2(&input), 82892753);
24 | }
25 |
--------------------------------------------------------------------------------
/tests/year2022/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | $ cd /
5 | $ ls
6 | dir a
7 | 14848514 b.txt
8 | 8504156 c.dat
9 | dir d
10 | $ cd a
11 | $ ls
12 | dir e
13 | 29116 f
14 | 2557 g
15 | 62596 h.lst
16 | $ cd e
17 | $ ls
18 | 584 i
19 | $ cd ..
20 | $ cd ..
21 | $ cd d
22 | $ ls
23 | 4060174 j
24 | 8033020 d.log
25 | 5626152 d.ext
26 | 7214296 k";
27 |
28 | #[test]
29 | fn part1_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part1(&input), 95437);
32 | }
33 |
34 | #[test]
35 | fn part2_test() {
36 | let input = parse(EXAMPLE);
37 | assert_eq!(part2(&input), 24933642);
38 | }
39 |
--------------------------------------------------------------------------------
/tests/year2016/day21.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day21::*;
2 |
3 | const EXAMPLE: &str = "\
4 | swap position 4 with position 0
5 | swap letter d with letter b
6 | reverse positions 0 through 4
7 | rotate left 1 step
8 | move position 1 to position 4
9 | move position 3 to position 0
10 | rotate based on position of letter b
11 | rotate based on position of letter d";
12 |
13 | #[test]
14 | fn part1_test() {
15 | let input = parse(EXAMPLE);
16 | assert_eq!(scramble(&input, b"abcde"), "decab");
17 | }
18 |
19 | #[test]
20 | fn part2_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(unscramble(&input, b"decab"), "abcde");
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2023/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
5 | Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
6 | Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
7 | Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
8 | Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
9 | Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11";
10 |
11 | #[test]
12 | fn part1_test() {
13 | let input = parse(EXAMPLE);
14 | assert_eq!(part1(&input), 13);
15 | }
16 |
17 | #[test]
18 | fn part2_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part2(&input), 30);
21 | }
22 |
--------------------------------------------------------------------------------
/tests/year2016/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2016::day12::*;
2 |
3 | const EXAMPLE: &str = "\
4 | cpy 1 a
5 | cpy 1 b
6 | cpy 26 d
7 | jnz c 2
8 | jnz 1 5
9 | cpy 7 c
10 | inc d
11 | dec c
12 | jnz c -2
13 | cpy a c
14 | inc a
15 | dec b
16 | jnz b -2
17 | cpy c b
18 | dec d
19 | jnz d -6
20 | cpy 1000 c // Test value
21 | cpy 1000 d // Test value
22 | inc a
23 | dec d
24 | jnz d -2
25 | dec c
26 | jnz c -5";
27 |
28 | #[test]
29 | fn part1_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part1(&input), 1317811);
32 | }
33 |
34 | #[test]
35 | fn part2_test() {
36 | let input = parse(EXAMPLE);
37 | assert_eq!(part2(&input), 10227465);
38 | }
39 |
--------------------------------------------------------------------------------
/tests/year2023/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day08::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | LLR
5 |
6 | AAA = (BBB, BBB)
7 | BBB = (AAA, ZZZ)
8 | ZZZ = (ZZZ, ZZZ)";
9 |
10 | const SECOND_EXAMPLE: &str = "\
11 | LR
12 |
13 | 11A = (11B, XXX)
14 | 11B = (XXX, 11Z)
15 | 11Z = (11B, XXX)
16 | 22A = (22B, XXX)
17 | 22B = (22C, 22C)
18 | 22C = (22Z, 22Z)
19 | 22Z = (22B, 22B)
20 | XXX = (XXX, XXX)";
21 |
22 | #[test]
23 | fn part1_test() {
24 | let input = parse(FIRST_EXAMPLE);
25 | assert_eq!(part1(&input), 6);
26 | }
27 |
28 | #[test]
29 | fn part2_test() {
30 | let input = parse(SECOND_EXAMPLE);
31 | assert_eq!(part2(&input), 6);
32 | }
33 |
--------------------------------------------------------------------------------
/tests/year2015/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
5 | Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3
6 | Filler 1: capacity -200, durability -300, flavor -600, texture -300, calories 0
7 | Filler 2: capacity -200, durability -300, flavor -600, texture -300, calories 0";
8 |
9 | #[test]
10 | fn part1_test() {
11 | let input = parse(EXAMPLE);
12 | assert_eq!(part1(&input), 62842880);
13 | }
14 |
15 | #[test]
16 | fn part2_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part2(&input), 57600000);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/year2025/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | .......S.......
5 | ...............
6 | .......^.......
7 | ...............
8 | ......^.^......
9 | ...............
10 | .....^.^.^.....
11 | ...............
12 | ....^.^...^....
13 | ...............
14 | ...^.^...^.^...
15 | ...............
16 | ..^...^.....^..
17 | ...............
18 | .^.^.^.^.^...^.
19 | ...............";
20 |
21 | #[test]
22 | fn part1_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part1(&input), 21);
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(EXAMPLE);
30 | assert_eq!(part2(&input), 40);
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2021/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 6,10
5 | 0,14
6 | 9,10
7 | 0,3
8 | 10,4
9 | 4,11
10 | 6,0
11 | 6,12
12 | 4,1
13 | 0,13
14 | 10,12
15 | 3,4
16 | 3,0
17 | 8,4
18 | 1,10
19 | 2,14
20 | 8,10
21 | 9,0
22 |
23 | fold along y=7
24 | fold along x=5";
25 |
26 | const EXPECTED: &str = "
27 | #####
28 | #...#
29 | #...#
30 | #...#
31 | #####
32 | .....
33 | .....";
34 |
35 | #[test]
36 | fn part1_test() {
37 | let input = parse(EXAMPLE);
38 | assert_eq!(part1(&input), 17);
39 | }
40 |
41 | #[test]
42 | fn part2_test() {
43 | let input = parse(EXAMPLE);
44 | assert_eq!(part2(&input), EXPECTED);
45 | }
46 |
--------------------------------------------------------------------------------
/tests/year2023/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
5 | Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
6 | Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
7 | Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
8 | Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
9 |
10 | #[test]
11 | fn part1_test() {
12 | let input = parse(EXAMPLE);
13 | assert_eq!(part1(&input), 8);
14 | }
15 |
16 | #[test]
17 | fn part2_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part2(&input), 2286);
20 | }
21 |
--------------------------------------------------------------------------------
/tests/year2024/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 47|53
5 | 97|13
6 | 97|61
7 | 97|47
8 | 75|29
9 | 61|13
10 | 75|53
11 | 29|13
12 | 97|29
13 | 53|29
14 | 61|53
15 | 97|53
16 | 61|29
17 | 47|13
18 | 75|47
19 | 97|75
20 | 47|61
21 | 75|61
22 | 47|29
23 | 75|13
24 | 53|13
25 |
26 | 75,47,61,53,29
27 | 97,61,53,29,13
28 | 75,29,13
29 | 75,97,47,61,53
30 | 61,13,29
31 | 97,13,75,29,47";
32 |
33 | #[test]
34 | fn part1_test() {
35 | let input = parse(EXAMPLE);
36 | assert_eq!(part1(&input), 143);
37 | }
38 |
39 | #[test]
40 | fn part2_test() {
41 | let input = parse(EXAMPLE);
42 | assert_eq!(part2(&input), 123);
43 | }
44 |
--------------------------------------------------------------------------------
/tests/year2024/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Button A: X+94, Y+34
5 | Button B: X+22, Y+67
6 | Prize: X=8400, Y=5400
7 |
8 | Button A: X+26, Y+66
9 | Button B: X+67, Y+21
10 | Prize: X=12748, Y=12176
11 |
12 | Button A: X+17, Y+86
13 | Button B: X+84, Y+37
14 | Prize: X=7870, Y=6450
15 |
16 | Button A: X+69, Y+23
17 | Button B: X+27, Y+71
18 | Prize: X=18641, Y=10279";
19 |
20 | #[test]
21 | fn part1_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part1(&input), 480);
24 | }
25 |
26 | #[test]
27 | fn part2_test() {
28 | let input = parse(EXAMPLE);
29 | assert_eq!(part2(&input), 875318608908);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/year2025/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 162,817,812
5 | 57,618,57
6 | 906,360,560
7 | 592,479,940
8 | 352,342,300
9 | 466,668,158
10 | 542,29,236
11 | 431,825,988
12 | 739,650,466
13 | 52,470,668
14 | 216,146,977
15 | 819,987,18
16 | 117,168,530
17 | 805,96,715
18 | 346,949,466
19 | 970,615,88
20 | 941,993,340
21 | 862,61,35
22 | 984,92,344
23 | 425,690,689";
24 |
25 | #[test]
26 | fn part1_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part1_testable(&input, 10), 40);
29 | }
30 |
31 | #[test]
32 | fn part2_test() {
33 | let input = parse(EXAMPLE);
34 | assert_eq!(part2(&input), 25272);
35 | }
36 |
--------------------------------------------------------------------------------
/src/year2015/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Not Quite Lisp
2 | //!
3 | //! The input is first converted into bytes. This is safe as it contains only ASCII characters.
4 | //! Then each parenthesis is parsed into either +1 or -1.
5 | pub fn parse(input: &str) -> Vec {
6 | input.trim().bytes().map(|b| if b == b'(' { 1 } else { -1 }).collect()
7 | }
8 |
9 | pub fn part1(input: &[i32]) -> i32 {
10 | input.iter().sum()
11 | }
12 |
13 | pub fn part2(input: &[i32]) -> usize {
14 | let mut floor = 0;
15 | input
16 | .iter()
17 | .position(|&b| {
18 | floor += b;
19 | floor < 0
20 | })
21 | .map(|i| i + 1)
22 | .unwrap()
23 | }
24 |
--------------------------------------------------------------------------------
/tests/year2024/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day23::*;
2 |
3 | const EXAMPLE: &str = "\
4 | kh-tc
5 | qp-kh
6 | de-cg
7 | ka-co
8 | yn-aq
9 | qp-ub
10 | cg-tb
11 | vc-aq
12 | tb-ka
13 | wh-tc
14 | yn-cg
15 | kh-ub
16 | ta-co
17 | de-co
18 | tc-td
19 | tb-wq
20 | wh-td
21 | ta-ka
22 | td-qp
23 | aq-cg
24 | wq-ub
25 | ub-vc
26 | de-ta
27 | wq-aq
28 | wq-vc
29 | wh-yn
30 | ka-de
31 | kh-ta
32 | co-tc
33 | wh-qp
34 | tb-vc
35 | td-yn";
36 |
37 | #[test]
38 | fn part1_test() {
39 | let input = parse(EXAMPLE);
40 | assert_eq!(part1(&input), 7);
41 | }
42 |
43 | #[test]
44 | fn part2_test() {
45 | let input = parse(EXAMPLE);
46 | assert_eq!(part2(&input), "co,de,ka,ta");
47 | }
48 |
--------------------------------------------------------------------------------
/src/year2019/day09.rs:
--------------------------------------------------------------------------------
1 | //! # Sensor Boost
2 | //!
3 | //! This problem is essentially a unit test for the full intcode computer.
4 | use super::intcode::*;
5 | use crate::util::parse::*;
6 |
7 | pub fn parse(input: &str) -> Vec {
8 | input.iter_signed().collect()
9 | }
10 |
11 | pub fn part1(input: &[i64]) -> i64 {
12 | run(input, 1)
13 | }
14 |
15 | pub fn part2(input: &[i64]) -> i64 {
16 | run(input, 2)
17 | }
18 |
19 | fn run(input: &[i64], value: i64) -> i64 {
20 | let mut computer = Computer::new(input);
21 | computer.input(value);
22 |
23 | match computer.run() {
24 | State::Output(result) => result,
25 | _ => unreachable!(),
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/year2022/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day19::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Blueprint 1:
5 | Each ore robot costs 4 ore.
6 | Each clay robot costs 2 ore.
7 | Each obsidian robot costs 3 ore and 14 clay.
8 | Each geode robot costs 2 ore and 7 obsidian.
9 |
10 | Blueprint 2:
11 | Each ore robot costs 2 ore.
12 | Each clay robot costs 3 ore.
13 | Each obsidian robot costs 3 ore and 8 clay.
14 | Each geode robot costs 3 ore and 12 obsidian.";
15 |
16 | #[test]
17 | fn part1_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part1(&input), 33);
20 | }
21 |
22 | #[test]
23 | fn part2_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part2(&input), 3472);
26 | }
27 |
--------------------------------------------------------------------------------
/tests/year2024/day12.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day12::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | RRRRIICCFF
5 | RRRRIICCCF
6 | VVRRRCCFFF
7 | VVRCCCJFFF
8 | VVVVCJJCFE
9 | VVIVCCJJEE
10 | VVIIICJJEE
11 | MIIIIIJJEE
12 | MIIISIJEEE
13 | MMMISSJEEE";
14 |
15 | const SECOND_EXAMPLE: &str = "\
16 | AAAAAA
17 | AAABBA
18 | AAABBA
19 | ABBAAA
20 | ABBAAA
21 | AAAAAA";
22 |
23 | #[test]
24 | fn part1_test() {
25 | let input = parse(FIRST_EXAMPLE);
26 | assert_eq!(part1(&input), 1930);
27 | }
28 |
29 | #[test]
30 | fn part2_test() {
31 | let input = parse(FIRST_EXAMPLE);
32 | assert_eq!(part2(&input), 1206);
33 | let input = parse(SECOND_EXAMPLE);
34 | assert_eq!(part2(&input), 368);
35 | }
36 |
--------------------------------------------------------------------------------
/tests/year2024/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day16::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #################
5 | #...#...#...#..E#
6 | #.#.#.#.#.#.#.#.#
7 | #.#.#.#...#...#.#
8 | #.#.#.#.###.#.#.#
9 | #...#.#.#.....#.#
10 | #.#.#.#.#.#####.#
11 | #.#...#.#.#.....#
12 | #.#.#####.#.###.#
13 | #.#.#.......#...#
14 | #.#.###.#####.###
15 | #.#.#...#.....#.#
16 | #.#.#.#####.###.#
17 | #.#.#.........#.#
18 | #.#.#.#########.#
19 | #S#.............#
20 | #################";
21 |
22 | #[test]
23 | fn part1_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part1(&input), 11048);
26 | }
27 |
28 | #[test]
29 | fn part2_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part2(&input), 64);
32 | }
33 |
--------------------------------------------------------------------------------
/tests/year2018/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Step C must be finished before step A can begin.
5 | Step C must be finished before step F can begin.
6 | Step A must be finished before step B can begin.
7 | Step A must be finished before step D can begin.
8 | Step B must be finished before step E can begin.
9 | Step D must be finished before step E can begin.
10 | Step F must be finished before step E can begin.";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), "CABDFE");
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2_testable(&input, 2, 0), 15);
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2021/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
5 |
6 | 22 13 17 11 0
7 | 8 2 23 4 24
8 | 21 9 14 16 7
9 | 6 10 3 18 5
10 | 1 12 20 15 19
11 |
12 | 3 15 0 2 22
13 | 9 18 13 17 5
14 | 19 8 7 25 23
15 | 20 11 10 24 4
16 | 14 21 16 12 6
17 |
18 | 14 21 17 24 4
19 | 10 16 15 9 19
20 | 18 8 23 26 20
21 | 22 11 13 6 5
22 | 2 0 12 3 7";
23 |
24 | #[test]
25 | fn part1_test() {
26 | let input = parse(EXAMPLE);
27 | assert_eq!(part1(&input), 4512);
28 | }
29 |
30 | #[test]
31 | fn part2_test() {
32 | let input = parse(EXAMPLE);
33 | assert_eq!(part2(&input), 1924);
34 | }
35 |
--------------------------------------------------------------------------------
/tests/year2024/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | #####
5 | .####
6 | .####
7 | .####
8 | .#.#.
9 | .#...
10 | .....
11 |
12 | #####
13 | ##.##
14 | .#.##
15 | ...##
16 | ...#.
17 | ...#.
18 | .....
19 |
20 | .....
21 | #....
22 | #....
23 | #...#
24 | #.#.#
25 | #.###
26 | #####
27 |
28 | .....
29 | .....
30 | #.#..
31 | ###..
32 | ###.#
33 | ###.#
34 | #####
35 |
36 | .....
37 | .....
38 | .....
39 | #....
40 | #.#..
41 | #.#.#
42 | #####";
43 |
44 | #[test]
45 | fn part1_test() {
46 | let input = parse(EXAMPLE);
47 | assert_eq!(part1(input), 3);
48 | }
49 |
50 | #[test]
51 | fn part2_test() {
52 | let input = parse(EXAMPLE);
53 | assert_eq!(part2(input), "n/a");
54 | }
55 |
--------------------------------------------------------------------------------
/tests/year2018/day23.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day23::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | pos=<0,0,0>, r=4
5 | pos=<1,0,0>, r=1
6 | pos=<4,0,0>, r=3
7 | pos=<0,2,0>, r=1
8 | pos=<0,5,0>, r=3
9 | pos=<0,0,3>, r=1
10 | pos=<1,1,1>, r=1
11 | pos=<1,1,2>, r=1
12 | pos=<1,3,1>, r=1";
13 |
14 | const SECOND_EXAMPLE: &str = "\
15 | pos=<10,12,12>, r=2
16 | pos=<12,14,12>, r=2
17 | pos=<16,12,12>, r=4
18 | pos=<14,14,14>, r=6
19 | pos=<50,50,50>, r=200
20 | pos=<10,10,10>, r=5";
21 |
22 | #[test]
23 | fn part1_test() {
24 | let input = parse(FIRST_EXAMPLE);
25 | assert_eq!(part1(&input), 7);
26 | }
27 |
28 | #[test]
29 | fn part2_test() {
30 | let input = parse(SECOND_EXAMPLE);
31 | assert_eq!(part2(&input), 36);
32 | }
33 |
--------------------------------------------------------------------------------
/tests/year2021/day18.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day18::*;
2 |
3 | const EXAMPLE: &str = "\
4 | [[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
5 | [[[5,[2,8]],4],[5,[[9,9],0]]]
6 | [6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
7 | [[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
8 | [[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
9 | [[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
10 | [[[[5,4],[7,7]],8],[[8,3],8]]
11 | [[9,3],[[9,9],[6,[4,9]]]]
12 | [[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
13 | [[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 4140);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 3993);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2025/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2025::day11::*;
2 |
3 | const EXAMPLE_ONE: &str = "\
4 | aaa: you hhh
5 | you: bbb ccc
6 | bbb: ddd eee
7 | ccc: ddd eee fff
8 | ddd: ggg
9 | eee: out
10 | fff: out
11 | ggg: out
12 | hhh: ccc fff iii
13 | iii: out";
14 |
15 | const EXAMPLE_TWO: &str = "\
16 | svr: aaa bbb
17 | aaa: fft
18 | fft: ccc
19 | bbb: tty
20 | tty: ccc
21 | ccc: ddd eee
22 | ddd: hub
23 | hub: fff
24 | eee: dac
25 | dac: fff
26 | fff: ggg hhh
27 | ggg: out
28 | hhh: out";
29 |
30 | #[test]
31 | fn part1_test() {
32 | let input = parse(EXAMPLE_ONE);
33 | assert_eq!(part1(&input), 5);
34 | }
35 |
36 | #[test]
37 | fn part2_test() {
38 | let input = parse(EXAMPLE_TWO);
39 | assert_eq!(part2(&input), 2);
40 | }
41 |
--------------------------------------------------------------------------------
/tests/year2020/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day16::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | class: 1-3 or 5-7
5 | row: 6-11 or 33-44
6 | seat: 13-40 or 45-50
7 |
8 | your ticket:
9 | 7,1,14
10 |
11 | nearby tickets:
12 | 7,3,47
13 | 40,4,50
14 | 55,2,20
15 | 38,6,12";
16 |
17 | const SECOND_EXAMPLE: &str = "\
18 | departure: 0-1 or 4-19
19 | row: 0-5 or 8-19
20 | seat: 0-13 or 16-19
21 |
22 | your ticket:
23 | 11,12,13
24 |
25 | nearby tickets:
26 | 3,9,18
27 | 15,1,5
28 | 5,14,9";
29 |
30 | #[test]
31 | fn part1_test() {
32 | let input = parse(FIRST_EXAMPLE);
33 | assert_eq!(part1(&input), 71);
34 | }
35 |
36 | #[test]
37 | fn part2_test() {
38 | let input = parse(SECOND_EXAMPLE);
39 | assert_eq!(part2(&input), 12);
40 | }
41 |
--------------------------------------------------------------------------------
/tests/year2024/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 190: 10 19
5 | 3267: 81 40 27
6 | 83: 17 5
7 | 156: 15 6
8 | 7290: 6 8 6 15
9 | 161011: 16 10 13
10 | 192: 17 8 14
11 | 21037: 9 7 18 13
12 | 292: 11 6 16 20";
13 |
14 | const EXAMPLE2: &str = "\
15 | 190: 10 19
16 | 11174: 15 8 9 79 74
17 | 729: 6 6 7 37 650";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1(&input), 3749);
23 | let input2 = parse(EXAMPLE2);
24 | assert_eq!(part1(&input2), 190);
25 | }
26 |
27 | #[test]
28 | fn part2_test() {
29 | let input = parse(EXAMPLE);
30 | assert_eq!(part2(&input), 11387);
31 | let input2 = parse(EXAMPLE2);
32 | assert_eq!(part2(&input2), 11364);
33 | }
34 |
--------------------------------------------------------------------------------
/tests/year2019/day18.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day18::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | #################
5 | #i.G..c...e..H.p#
6 | ########.########
7 | #j.A..b...f..D.o#
8 | ########@########
9 | #k.E..a...g..B.n#
10 | ########.########
11 | #l.F..d...h..C.m#
12 | #################";
13 |
14 | const SECOND_EXAMPLE: &str = "\
15 | #############
16 | #g#f.D#..h#l#
17 | #F###e#E###.#
18 | #dCba@#@BcIJ#
19 | #############
20 | #nK.L@#@G...#
21 | #M###N#H###.#
22 | #o#m..#i#jk.#
23 | #############";
24 |
25 | #[test]
26 | fn part1_test() {
27 | let input = parse(FIRST_EXAMPLE);
28 | assert_eq!(part1(&input), 136);
29 | }
30 |
31 | #[test]
32 | fn part2_test() {
33 | let input = parse(SECOND_EXAMPLE);
34 | assert_eq!(part2(&input), 72);
35 | }
36 |
--------------------------------------------------------------------------------
/tests/year2019/day02.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day02::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 1, 0, 0, 0,
5 | 2, 32, 0, 0,
6 | 2, 33, 1, 1,
7 | 2, 34, 2, 2,
8 | 1, 35, 0, 0,
9 | 1, 1, 0, 0,
10 | 1, 2, 0, 0,
11 | 99, 0, 0, 0,
12 | 0, 1000000, 10000, 7350720,
13 | 0, 0, 0, 0,
14 | 0, 0, 0, 0,
15 | 0, 0, 0, 0,
16 | 0, 0, 0, 0,
17 | 0, 0, 0, 0,
18 | 0, 0, 0, 0,
19 | 0, 0, 0, 0,
20 | 0, 0, 0, 0,
21 | 0, 0, 0, 0,
22 | 0, 0, 0, 0,
23 | 0, 0, 0, 0,
24 | 0, 0, 0, 0,
25 | 0, 0, 0, 0,
26 | 0, 0, 0, 0,
27 | 0, 0, 0, 0,
28 | 0, 0, 0, 0";
29 |
30 | #[test]
31 | fn part1_test() {
32 | let input = parse(EXAMPLE);
33 | assert_eq!(part1(&input), 19370720);
34 | }
35 |
36 | #[test]
37 | fn part2_test() {
38 | let input = parse(EXAMPLE);
39 | assert_eq!(part2(&input), 1234);
40 | }
41 |
--------------------------------------------------------------------------------
/tests/year2023/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day19::*;
2 |
3 | const EXAMPLE: &str = "\
4 | px{a<2006:qkq,m>2090:A,rfg}
5 | pv{a>1716:R,A}
6 | lnx{m>1548:A,A}
7 | rfg{s<537:gd,x>2440:R,A}
8 | qs{s>3448:A,lnx}
9 | qkq{x<1416:A,crn}
10 | crn{x>2662:A,R}
11 | in{s<1351:px,qqz}
12 | qqz{s>2770:qs,m<1801:hdj,R}
13 | gd{a>3333:R,R}
14 | hdj{m>838:A,pv}
15 |
16 | {x=787,m=2655,a=1222,s=2876}
17 | {x=1679,m=44,a=2067,s=496}
18 | {x=2036,m=264,a=79,s=2244}
19 | {x=2461,m=1339,a=466,s=291}
20 | {x=2127,m=1623,a=2188,s=1013}";
21 |
22 | #[test]
23 | fn part1_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part1(&input), 19114);
26 | }
27 |
28 | #[test]
29 | fn part2_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part2(&input), 167409079868000);
32 | }
33 |
--------------------------------------------------------------------------------
/src/year2019/day05.rs:
--------------------------------------------------------------------------------
1 | //! # Sunny with a Chance of Asteroids
2 | use super::intcode::*;
3 | use crate::util::parse::*;
4 |
5 | pub fn parse(input: &str) -> Vec {
6 | input.iter_signed().collect()
7 | }
8 |
9 | pub fn part1(input: &[i64]) -> i64 {
10 | run(input, 1)
11 | }
12 |
13 | pub fn part2(input: &[i64]) -> i64 {
14 | run(input, 5)
15 | }
16 |
17 | /// Start `IntCode` computer sending a single initial value.
18 | /// Receives multiple values from the output channel returning only the last one.
19 | fn run(input: &[i64], value: i64) -> i64 {
20 | let mut computer = Computer::new(input);
21 | computer.input(value);
22 |
23 | let mut result = 0;
24 | while let State::Output(next) = computer.run() {
25 | result = next;
26 | }
27 | result
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2023/day05.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2023::day05::*;
2 |
3 | const EXAMPLE: &str = "\
4 | seeds: 79 14 55 13
5 |
6 | seed-to-soil map:
7 | 50 98 2
8 | 52 50 48
9 |
10 | soil-to-fertilizer map:
11 | 0 15 37
12 | 37 52 2
13 | 39 0 15
14 |
15 | fertilizer-to-water map:
16 | 49 53 8
17 | 0 11 42
18 | 42 0 7
19 | 57 7 4
20 |
21 | water-to-light map:
22 | 88 18 7
23 | 18 25 70
24 |
25 | light-to-temperature map:
26 | 45 77 23
27 | 81 45 19
28 | 68 64 13
29 |
30 | temperature-to-humidity map:
31 | 0 69 1
32 | 1 0 69
33 |
34 | humidity-to-location map:
35 | 60 56 37
36 | 56 93 4";
37 |
38 | #[test]
39 | fn part1_test() {
40 | let input = parse(EXAMPLE);
41 | assert_eq!(part1(&input), 35);
42 | }
43 |
44 | #[test]
45 | fn part2_test() {
46 | let input = parse(EXAMPLE);
47 | assert_eq!(part2(&input), 46);
48 | }
49 |
--------------------------------------------------------------------------------
/.github/workflows/checks.yml:
--------------------------------------------------------------------------------
1 | name: Checks
2 |
3 | on:
4 | push:
5 | branches: main
6 | pull_request:
7 | branches: main
8 |
9 | jobs:
10 | lint:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - run: rustup install nightly --profile default
15 | - run: rustup default nightly
16 | - run: cargo fmt --check -- `find . -name "*.rs"`
17 | - run: cargo clippy --all-targets --all-features -- --deny warnings
18 |
19 | test-stable:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v4
23 | - run: rustup default 1.92
24 | - run: cargo test
25 |
26 | test-nightly:
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: actions/checkout@v4
30 | - run: rustup default nightly
31 | - run: cargo test --features simd
32 |
--------------------------------------------------------------------------------
/tests/year2019/day10.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2019::day10::*;
2 |
3 | const EXAMPLE: &str = "\
4 | .#..##.###...#######
5 | ##.############..##.
6 | .#.######.########.#
7 | .###.#######.####.#.
8 | #####.##.#.##.###.##
9 | ..#####..#.#########
10 | ####################
11 | #.####....###.#.#.##
12 | ##.#################
13 | #####.##.###..####..
14 | ..######..##.#######
15 | ####.##.####...##..#
16 | .#####..#.######.###
17 | ##...#.##########...
18 | #.##########.#######
19 | .####.#.###.###.#.##
20 | ....##.##.###..#####
21 | .#.#.###########.###
22 | #.#.#.#####.####.###
23 | ###.##.####.##.#..##";
24 |
25 | #[test]
26 | fn part1_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part1(&input), 210);
29 | }
30 |
31 | #[test]
32 | fn part2_test() {
33 | let input = parse(EXAMPLE);
34 | assert_eq!(part2(&input), 802);
35 | }
36 |
--------------------------------------------------------------------------------
/src/year2017/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Inverse Captcha
2 | //!
3 | //! Modern hardware is so good at shuffling memory around that it's faster to rotate the entire
4 | //! array instead of stepping through elements one at a time with an index modulo array length.
5 | use crate::util::parse::*;
6 |
7 | pub fn parse(input: &str) -> &[u8] {
8 | input.trim().as_bytes()
9 | }
10 |
11 | pub fn part1(input: &[u8]) -> u32 {
12 | captcha(input, 1)
13 | }
14 |
15 | pub fn part2(input: &[u8]) -> u32 {
16 | captcha(input, input.len() / 2)
17 | }
18 |
19 | fn captcha(input: &[u8], offset: usize) -> u32 {
20 | let mut rotated = input.to_vec();
21 | rotated.rotate_left(offset);
22 |
23 | input
24 | .iter()
25 | .zip(rotated.iter())
26 | .filter_map(|(a, b)| (a == b).then_some(a.to_decimal() as u32))
27 | .sum()
28 | }
29 |
--------------------------------------------------------------------------------
/src/year2016/day03.rs:
--------------------------------------------------------------------------------
1 | //! # Squares With Three Sides
2 | //!
3 | //! We rely on the [`iter`] and [`parse`] utility modules to extract integers from surrounding
4 | //! text then group together in chunks of three.
5 | //!
6 | //! [`iter`]: crate::util::iter
7 | //! [`parse`]: crate::util::parse
8 | use crate::util::iter::*;
9 | use crate::util::parse::*;
10 |
11 | pub fn parse(input: &str) -> Vec {
12 | input.iter_unsigned().collect()
13 | }
14 |
15 | pub fn part1(input: &[u32]) -> usize {
16 | count(input.iter())
17 | }
18 |
19 | pub fn part2(input: &[u32]) -> usize {
20 | (0..3).map(|skip| count(input.iter().skip(skip).step_by(3))).sum()
21 | }
22 |
23 | fn count<'a, I>(iter: I) -> usize
24 | where
25 | I: Iterator- ,
26 | {
27 | iter.chunk::<3>().filter(|&[&a, &b, &c]| a + b > c && a + c > b && b + c > a).count()
28 | }
29 |
--------------------------------------------------------------------------------
/tests/year2020/day07.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day07::*;
2 |
3 | const EXAMPLE: &str = "\
4 | light red bags contain 1 bright white bag, 2 muted yellow bags.
5 | dark orange bags contain 3 bright white bags, 4 muted yellow bags.
6 | bright white bags contain 1 shiny gold bag.
7 | muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
8 | shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
9 | dark olive bags contain 3 faded blue bags, 4 dotted black bags.
10 | vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
11 | faded blue bags contain no other bags.
12 | dotted black bags contain no other bags.";
13 |
14 | #[test]
15 | fn part1_test() {
16 | let input = parse(EXAMPLE);
17 | assert_eq!(part1(&input), 4);
18 | }
19 |
20 | #[test]
21 | fn part2_test() {
22 | let input = parse(EXAMPLE);
23 | assert_eq!(part2(&input), 32);
24 | }
25 |
--------------------------------------------------------------------------------
/src/util/bitset.rs:
--------------------------------------------------------------------------------
1 | //! Add `biterator` method that treats an integer as a set, iterating over each element where
2 | //! the respective bit is set. For example `1101` would return 0, 2 and 3.
3 | use crate::util::integer::*;
4 |
5 | pub trait BitOps {
6 | fn biterator(self) -> Bitset;
7 | }
8 |
9 | impl> BitOps for T {
10 | fn biterator(self) -> Bitset {
11 | Bitset { t: self }
12 | }
13 | }
14 |
15 | pub struct Bitset {
16 | t: T,
17 | }
18 |
19 | impl> Iterator for Bitset {
20 | type Item = usize;
21 |
22 | #[inline]
23 | fn next(&mut self) -> Option {
24 | if self.t == T::ZERO {
25 | None
26 | } else {
27 | let tz = self.t.trailing_zeros();
28 | self.t = self.t ^ (T::ONE << tz);
29 | Some(tz as usize)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/year2018/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Immune System:
5 | 17 units each with 5390 hit points (weak to radiation, bludgeoning) with an attack that does 4507 fire damage at initiative 2
6 | 989 units each with 1274 hit points (immune to fire; weak to bludgeoning, slashing) with an attack that does 25 slashing damage at initiative 3
7 |
8 | Infection:
9 | 801 units each with 4706 hit points (weak to radiation) with an attack that does 116 bludgeoning damage at initiative 1
10 | 4485 units each with 2961 hit points (immune to radiation; weak to fire, cold) with an attack that does 12 slashing damage at initiative 4";
11 |
12 | #[test]
13 | fn part1_test() {
14 | let input = parse(EXAMPLE);
15 | assert_eq!(part1(&input), 5216);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse(EXAMPLE);
21 | assert_eq!(part2(&input), 51);
22 | }
23 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Docs
2 |
3 | on:
4 | push:
5 | branches: docs
6 |
7 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
8 | permissions:
9 | contents: read
10 | pages: write
11 | id-token: write
12 |
13 | jobs:
14 | deploy:
15 | runs-on: ubuntu-latest
16 | environment:
17 | name: github-pages
18 | url: ${{ steps.deployment.outputs.page_url }}
19 | steps:
20 | - uses: actions/checkout@v4
21 | - run: rustup default 1.92
22 | - run: cargo doc
23 | env:
24 | RUSTDOCFLAGS: "--document-private-items --default-theme=ayu --deny warnings"
25 | - run: rm target/doc/.lock
26 | - run: cp docs/* target/doc
27 | - uses: actions/upload-pages-artifact@v3
28 | with:
29 | path: 'target/doc'
30 | - uses: actions/configure-pages@v4
31 | - uses: actions/deploy-pages@v4
32 | id: deployment
33 |
--------------------------------------------------------------------------------
/tests/year2022/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day16::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
5 | Valve BB has flow rate=13; tunnels lead to valves CC, AA
6 | Valve CC has flow rate=2; tunnels lead to valves DD, BB
7 | Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
8 | Valve EE has flow rate=3; tunnels lead to valves FF, DD
9 | Valve FF has flow rate=0; tunnels lead to valves EE, GG
10 | Valve GG has flow rate=0; tunnels lead to valves FF, HH
11 | Valve HH has flow rate=22; tunnel leads to valve GG
12 | Valve II has flow rate=0; tunnels lead to valves AA, JJ
13 | Valve JJ has flow rate=21; tunnel leads to valve II";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 1651);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 1707);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/year2021/day20.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day20::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#.\
5 | .#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..\
6 | #.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....\
7 | #.#....###..#.##......#.....#..#..#..##..#...##.######.####.####\
8 | .#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.\
9 | #.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..\
10 | #.##.#....##..#.####....##...##..#...#......#.#.......#.......##\
11 | ..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
12 |
13 | #..#.
14 | #....
15 | ##..#
16 | ..#..
17 | ..###";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1(&input), 35);
23 | }
24 |
25 | #[test]
26 | fn part2_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part2(&input), 3351);
29 | }
30 |
--------------------------------------------------------------------------------
/src/year2020/day03.rs:
--------------------------------------------------------------------------------
1 | //! # Toboggan Trajectory
2 | //!
3 | //! Two dimensional grids of ASCII characters are a common Advent of Code theme,
4 | //! so we use our utility [`Grid`] class to parse the data.
5 | //!
6 | //! [`Grid`]: crate::util::grid
7 | use crate::util::grid::*;
8 | use crate::util::point::*;
9 |
10 | pub fn parse(input: &str) -> Grid {
11 | Grid::parse(input)
12 | }
13 |
14 | pub fn part1(input: &Grid) -> usize {
15 | toboggan(input, 3, 1)
16 | }
17 |
18 | pub fn part2(input: &Grid) -> usize {
19 | [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
20 | .into_iter()
21 | .map(|(dx, dy)| toboggan(input, dx, dy))
22 | .product()
23 | }
24 |
25 | fn toboggan(grid: &Grid, dx: i32, dy: i32) -> usize {
26 | (0..grid.height / dy)
27 | .filter(|&i| {
28 | let point = Point::new((i * dx) % grid.width, i * dy);
29 | grid[point] == b'#'
30 | })
31 | .count()
32 | }
33 |
--------------------------------------------------------------------------------
/src/year2022/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Rock Paper Scissors
2 | //!
3 | //! With so few combinations it's possible to precompute the values for each scenario by hand
4 | //! then quickly look them up for each game.
5 |
6 | /// Map each line from one of the 9 possible combinations ("A", "B" or "C" followed by "X", "Y" or "Z")
7 | /// to between 0 and 8 inclusive.
8 | pub fn parse(input: &str) -> Vec {
9 | input.as_bytes().chunks_exact(4).map(|c| (3 * (c[0] - b'A') + c[2] - b'X') as usize).collect()
10 | }
11 |
12 | /// Map each index to a score using a small precomputed lookup table.
13 | pub fn part1(input: &[usize]) -> u32 {
14 | let score = [4, 8, 3, 1, 5, 9, 7, 2, 6];
15 | input.iter().map(|&i| score[i]).sum()
16 | }
17 |
18 | /// Map each index to a (different) score using a second small precomputed lookup table.
19 | pub fn part2(input: &[usize]) -> u32 {
20 | let score = [3, 4, 8, 1, 5, 9, 2, 6, 7];
21 | input.iter().map(|&i| score[i]).sum()
22 | }
23 |
--------------------------------------------------------------------------------
/tests/year2018/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2018::day04::*;
2 |
3 | const EXAMPLE: &str = "\
4 | [1518-11-01 00:00] Guard #10 begins shift
5 | [1518-11-01 00:05] falls asleep
6 | [1518-11-01 00:25] wakes up
7 | [1518-11-01 00:30] falls asleep
8 | [1518-11-01 00:55] wakes up
9 | [1518-11-01 23:58] Guard #99 begins shift
10 | [1518-11-02 00:40] falls asleep
11 | [1518-11-02 00:50] wakes up
12 | [1518-11-03 00:05] Guard #10 begins shift
13 | [1518-11-03 00:24] falls asleep
14 | [1518-11-03 00:29] wakes up
15 | [1518-11-04 00:02] Guard #99 begins shift
16 | [1518-11-04 00:36] falls asleep
17 | [1518-11-04 00:46] wakes up
18 | [1518-11-05 00:03] Guard #99 begins shift
19 | [1518-11-05 00:45] falls asleep
20 | [1518-11-05 00:55] wakes up";
21 |
22 | #[test]
23 | fn part1_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part1(&input), 240);
26 | }
27 |
28 | #[test]
29 | fn part2_test() {
30 | let input = parse(EXAMPLE);
31 | assert_eq!(part2(&input), 4455);
32 | }
33 |
--------------------------------------------------------------------------------
/tests/year2017/day25.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2017::day25::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Begin in state A.
5 | Perform a diagnostic checksum after 6 steps.
6 |
7 | In state A:
8 | If the current value is 0:
9 | - Write the value 1.
10 | - Move one slot to the right.
11 | - Continue with state B.
12 | If the current value is 1:
13 | - Write the value 0.
14 | - Move one slot to the left.
15 | - Continue with state B.
16 |
17 | In state B:
18 | If the current value is 0:
19 | - Write the value 1.
20 | - Move one slot to the left.
21 | - Continue with state A.
22 | If the current value is 1:
23 | - Write the value 1.
24 | - Move one slot to the right.
25 | - Continue with state A.";
26 |
27 | #[test]
28 | fn part1_test() {
29 | let input = parse(EXAMPLE);
30 | assert_eq!(part1(&input), 3);
31 | }
32 |
33 | #[test]
34 | fn part2_test() {
35 | let input = parse(EXAMPLE);
36 | assert_eq!(part2(&input), "n/a");
37 | }
38 |
--------------------------------------------------------------------------------
/src/year2025/day07.rs:
--------------------------------------------------------------------------------
1 | //! # Laboratories
2 | type Input = (u64, u64);
3 |
4 | pub fn parse(input: &str) -> Input {
5 | let lines: Vec<_> = input.lines().map(str::as_bytes).collect();
6 | let width = lines[0].len();
7 | let center = width / 2;
8 |
9 | let mut splits = 0;
10 | let mut timelines = vec![0; width];
11 | timelines[center] = 1;
12 |
13 | for (y, row) in lines.iter().skip(2).step_by(2).enumerate() {
14 | for x in ((center - y)..(center + y + 1)).step_by(2) {
15 | let count = timelines[x];
16 |
17 | if count > 0 && row[x] == b'^' {
18 | splits += 1;
19 | timelines[x] = 0;
20 | timelines[x - 1] += count;
21 | timelines[x + 1] += count;
22 | }
23 | }
24 | }
25 |
26 | (splits, timelines.iter().sum())
27 | }
28 |
29 | pub fn part1(input: &Input) -> u64 {
30 | input.0
31 | }
32 |
33 | pub fn part2(input: &Input) -> u64 {
34 | input.1
35 | }
36 |
--------------------------------------------------------------------------------
/src/year2024/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Historian Hysteria
2 | //!
3 | //! For part 2, the time needed to allocate memory and grow the map is a large percentage
4 | //! of the total. Creating the [`FastMap`] with capacity 1000 reduces this.
5 | use crate::util::hash::*;
6 | use crate::util::iter::*;
7 | use crate::util::parse::*;
8 |
9 | type Input = (Vec, Vec);
10 |
11 | pub fn parse(input: &str) -> Input {
12 | input.iter_unsigned::().chunk::<2>().map(|[l, r]| (l, r)).unzip()
13 | }
14 |
15 | pub fn part1(input: &Input) -> u32 {
16 | let (mut left, mut right) = input.clone();
17 |
18 | left.sort_unstable();
19 | right.sort_unstable();
20 |
21 | left.iter().zip(right).map(|(l, r)| l.abs_diff(r)).sum()
22 | }
23 |
24 | pub fn part2(input: &Input) -> u32 {
25 | let (left, right) = input;
26 |
27 | let mut freq = FastMap::with_capacity(1_000);
28 | right.iter().for_each(|r| *freq.entry(r).or_insert(0) += 1);
29 |
30 | left.iter().filter_map(|l| freq.get(l).map(|f| l * f)).sum()
31 | }
32 |
--------------------------------------------------------------------------------
/src/year2022/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Calorie Counting
2 | //! Sums groups of numbers separated by blank lines into a `vec` sorted in ascending order.
3 | //!
4 | //! Since we don't care what order the highest values are returned in [`select_nth_unstable`] would
5 | //! also work, and in theory is a little faster, however the difference was negligible when benchmarking.
6 | //!
7 | //! [`select_nth_unstable`]: slice::select_nth_unstable
8 | use crate::util::parse::*;
9 |
10 | /// Parse and group lines.
11 | pub fn parse(input: &str) -> Vec {
12 | let mut elves: Vec = input.split("\n\n").map(|s| s.iter_unsigned::().sum()).collect();
13 | elves.sort_unstable();
14 | elves
15 | }
16 |
17 | /// Use a reverse iterator to find the elf with the most calories.
18 | pub fn part1(input: &[u32]) -> u32 {
19 | input.iter().rev().take(1).sum()
20 | }
21 |
22 | /// Use a reverse iterator to sum the calories of the 3 highest elves.
23 | pub fn part2(input: &[u32]) -> u32 {
24 | input.iter().rev().take(3).sum()
25 | }
26 |
--------------------------------------------------------------------------------
/src/year2015/day02.rs:
--------------------------------------------------------------------------------
1 | //! # I Was Told There Would Be No Math
2 | //!
3 | //! To extract the numbers when parsing the input we use our utility [`iter_unsigned`] and [`chunk`]
4 | //! functions.
5 | //!
6 | //! Sorting the dimensions in ascending order makes calculating the smallest side or smallest
7 | //! perimeter straightforward.
8 | //!
9 | //! [`iter_unsigned`]: crate::util::parse
10 | //! [`chunk`]: crate::util::iter
11 | use crate::util::iter::*;
12 | use crate::util::parse::*;
13 |
14 | type Input = Vec<[u32; 3]>;
15 |
16 | pub fn parse(input: &str) -> Input {
17 | input
18 | .iter_unsigned()
19 | .chunk::<3>()
20 | .map(|mut chunk| {
21 | chunk.sort_unstable();
22 | chunk
23 | })
24 | .collect()
25 | }
26 |
27 | pub fn part1(input: &Input) -> u32 {
28 | input.iter().map(|[l, w, h]| 2 * (l * w + w * h + h * l) + l * w).sum()
29 | }
30 |
31 | pub fn part2(input: &Input) -> u32 {
32 | input.iter().map(|[l, w, h]| 2 * (l + w) + (l * w * h)).sum()
33 | }
34 |
--------------------------------------------------------------------------------
/tests/year2022/day11.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day11::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Monkey 0:
5 | Starting items: 79, 98
6 | Operation: new = old * 19
7 | Test: divisible by 23
8 | If true: throw to monkey 2
9 | If false: throw to monkey 3
10 |
11 | Monkey 1:
12 | Starting items: 54, 65, 75, 74
13 | Operation: new = old + 6
14 | Test: divisible by 19
15 | If true: throw to monkey 2
16 | If false: throw to monkey 0
17 |
18 | Monkey 2:
19 | Starting items: 79, 60, 97
20 | Operation: new = old * old
21 | Test: divisible by 13
22 | If true: throw to monkey 1
23 | If false: throw to monkey 3
24 |
25 | Monkey 3:
26 | Starting items: 74
27 | Operation: new = old + 3
28 | Test: divisible by 17
29 | If true: throw to monkey 0
30 | If false: throw to monkey 1";
31 |
32 | #[test]
33 | fn part1_test() {
34 | let input = parse(EXAMPLE);
35 | assert_eq!(part1(&input), 10605);
36 | }
37 |
38 | #[test]
39 | fn part2_test() {
40 | let input = parse(EXAMPLE);
41 | assert_eq!(part2(&input), 2713310158);
42 | }
43 |
--------------------------------------------------------------------------------
/src/year2025/day03.rs:
--------------------------------------------------------------------------------
1 | //! # Lobby
2 | use std::mem::replace;
3 |
4 | pub fn parse(input: &str) -> Vec<&str> {
5 | input.lines().collect()
6 | }
7 |
8 | pub fn part1(input: &[&str]) -> u64 {
9 | solve::<2>(input)
10 | }
11 |
12 | pub fn part2(input: &[&str]) -> u64 {
13 | solve::<12>(input)
14 | }
15 |
16 | fn solve(input: &[&str]) -> u64 {
17 | let mut batteries = [0; N];
18 |
19 | input
20 | .iter()
21 | .map(|&bank| {
22 | let end = bank.len() - N;
23 | batteries.copy_from_slice(&bank.as_bytes()[end..]);
24 |
25 | for mut next in bank[..end].bytes().rev() {
26 | for battery in &mut batteries {
27 | if next < *battery {
28 | break;
29 | }
30 | next = replace(battery, next);
31 | }
32 | }
33 |
34 | batteries.iter().fold(0, |joltage, &b| 10 * joltage + (b - b'0') as u64)
35 | })
36 | .sum()
37 | }
38 |
--------------------------------------------------------------------------------
/tests/year2020/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | sesenwnenenewseeswwswswwnenewsewsw
5 | neeenesenwnwwswnenewnwwsewnenwseswesw
6 | seswneswswsenwwnwse
7 | nwnwneseeswswnenewneswwnewseswneseene
8 | swweswneswnenwsewnwneneseenw
9 | eesenwseswswnenwswnwnwsewwnwsene
10 | sewnenenenesenwsewnenwwwse
11 | wenwwweseeeweswwwnwwe
12 | wsweesenenewnwwnwsenewsenwwsesesenwne
13 | neeswseenwwswnwswswnw
14 | nenwswwsewswnenenewsenwsenwnesesenew
15 | enewnwewneswsewnwswenweswnenwsenwsw
16 | sweneswneswneneenwnewenewwneswswnese
17 | swwesenesewenwneswnwwneseswwne
18 | enesenwswwswneneswsenwnewswseenwsese
19 | wnwnesenesenenwwnenwsewesewsesesew
20 | nenewswnwewswnenesenwnesewesw
21 | eneswnwswnwsenenwnwnwwseeswneewsenese
22 | neswnwewnwnwseenwseesewsenwsweewe
23 | wseweeenwnesenwwwswnew";
24 |
25 | #[test]
26 | fn part1_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part1(&input), 10);
29 | }
30 |
31 | #[test]
32 | fn part2_test() {
33 | let input = parse(EXAMPLE);
34 | assert_eq!(part2(&input), 2208);
35 | }
36 |
--------------------------------------------------------------------------------
/src/year2021/day06.rs:
--------------------------------------------------------------------------------
1 | //! # Lanternfish
2 | //!
3 | //! The key observation is that all fish of the same age behave the same, so we only
4 | //! need to store the *total* of each fish per day, rather than each fish individually.
5 | //!
6 | //! Another optimization trick is rather than modifying the array by removing the fish at day 0,
7 | //! then shifting each fish total down by 1, we can simply increment what we consider the
8 | //! head of the array modulo 9 to achieve the same effect in place.
9 | use crate::util::parse::*;
10 |
11 | type Input = [u64; 9];
12 |
13 | pub fn parse(input: &str) -> Input {
14 | let mut fish = [0_u64; 9];
15 | input.iter_unsigned().for_each(|i: usize| fish[i] += 1);
16 | fish
17 | }
18 |
19 | pub fn part1(input: &Input) -> u64 {
20 | simulate(input, 80)
21 | }
22 |
23 | pub fn part2(input: &Input) -> u64 {
24 | simulate(input, 256)
25 | }
26 |
27 | fn simulate(input: &Input, days: usize) -> u64 {
28 | let mut fish = *input;
29 | (0..days).for_each(|day| fish[(day + 7) % 9] += fish[day % 9]);
30 | fish.iter().sum()
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2015/day13.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2015::day13::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Alice would gain 54 happiness units by sitting next to Bob.
5 | Alice would lose 79 happiness units by sitting next to Carol.
6 | Alice would lose 2 happiness units by sitting next to David.
7 | Bob would gain 83 happiness units by sitting next to Alice.
8 | Bob would lose 7 happiness units by sitting next to Carol.
9 | Bob would lose 63 happiness units by sitting next to David.
10 | Carol would lose 62 happiness units by sitting next to Alice.
11 | Carol would gain 60 happiness units by sitting next to Bob.
12 | Carol would gain 55 happiness units by sitting next to David.
13 | David would gain 46 happiness units by sitting next to Alice.
14 | David would lose 7 happiness units by sitting next to Bob.
15 | David would gain 41 happiness units by sitting next to Carol.";
16 |
17 | #[test]
18 | fn part1_test() {
19 | let input = parse(EXAMPLE);
20 | assert_eq!(part1(&input), 330);
21 | }
22 |
23 | #[test]
24 | fn part2_test() {
25 | let input = parse(EXAMPLE);
26 | assert_eq!(part2(&input), 286);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/year2020/day03.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day03::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ..##.........##.........##.........##.........##.........##.......
5 | #...#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
6 | .#....#..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
7 | ..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
8 | .#...##..#..#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
9 | ..#.##.......#.##.......#.##.......#.##.......#.##.......#.##.....
10 | .#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
11 | .#........#.#........#.#........#.#........#.#........#.#........#
12 | #.##...#...#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
13 | #...##....##...##....##...##....##...##....##...##....##...##....#
14 | .#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#";
15 |
16 | #[test]
17 | fn part1_test() {
18 | let input = parse(EXAMPLE);
19 | assert_eq!(part1(&input), 7);
20 | }
21 |
22 | #[test]
23 | fn part2_test() {
24 | let input = parse(EXAMPLE);
25 | assert_eq!(part2(&input), 336);
26 | }
27 |
--------------------------------------------------------------------------------
/src/year2016/day20.rs:
--------------------------------------------------------------------------------
1 | //! # Firewall Rules
2 | use crate::util::iter::*;
3 | use crate::util::parse::*;
4 |
5 | type Range = [u64; 2];
6 |
7 | /// The trick to merge ranges efficiently is to sort by the *starting* index.
8 | pub fn parse(input: &str) -> Vec {
9 | let mut ranges: Vec<_> = input.iter_unsigned().chunk::<2>().collect();
10 | ranges.sort_unstable_by_key(|r| r[0]);
11 | ranges
12 | }
13 |
14 | pub fn part1(input: &[Range]) -> u64 {
15 | let mut index = 0;
16 |
17 | for &[start, end] in input {
18 | if index < start {
19 | return index;
20 | }
21 | // Ends are not sorted so only increase.
22 | index = index.max(end + 1);
23 | }
24 |
25 | unreachable!()
26 | }
27 |
28 | pub fn part2(input: &[Range]) -> u64 {
29 | let mut index = 0;
30 | let mut total = 0;
31 |
32 | for &[start, end] in input {
33 | if index < start {
34 | total += start - index;
35 | }
36 | // Ends are not sorted so only increase.
37 | index = index.max(end + 1);
38 | }
39 |
40 | total
41 | }
42 |
--------------------------------------------------------------------------------
/src/year2025/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Secret Entrance
2 | //!
3 | //! Part two left turns are easier if we first "reverse" the dial, then treat it as a right turn.
4 | use crate::util::parse::*;
5 |
6 | type Input = (i32, i32);
7 |
8 | pub fn parse(input: &str) -> Input {
9 | let directions = input.bytes().filter(|&b| b.is_ascii_uppercase());
10 | let amounts = input.iter_signed::();
11 |
12 | let mut dial = 50;
13 | let mut part_one = 0;
14 | let mut part_two = 0;
15 |
16 | for (direction, amount) in directions.zip(amounts) {
17 | if direction == b'R' {
18 | part_two += (dial + amount) / 100;
19 | dial = (dial + amount) % 100;
20 | } else {
21 | let reversed = (100 - dial) % 100;
22 | part_two += (reversed + amount) / 100;
23 | dial = (dial - amount).rem_euclid(100);
24 | }
25 | part_one += i32::from(dial == 0);
26 | }
27 |
28 | (part_one, part_two)
29 | }
30 |
31 | pub fn part1(input: &Input) -> i32 {
32 | input.0
33 | }
34 |
35 | pub fn part2(input: &Input) -> i32 {
36 | input.1
37 | }
38 |
--------------------------------------------------------------------------------
/src/year2021/day01.rs:
--------------------------------------------------------------------------------
1 | //! # Sonar Sweep
2 | //!
3 | //! The built-in [`windows`] method comes in handy for this solution. For part 1 a straightforward
4 | //! sliding window of size 2 allows us to compare each 2 consecutive values.
5 | //!
6 | //! For part 2 we can use a trick to simplify. If we consider the first 2 windows of 3 elements
7 | //! each:
8 | //!
9 | //! ```none
10 | //! A1 A2 A3
11 | //! B1 B2 B3
12 | //! ```
13 | //!
14 | //! then the middle 2 elements are always in common, so the subsequent window is greater only
15 | //! if the last element is greater than the first. This means we can pick a sliding window of
16 | //! size 4 and compare the first and last elements, without having to sum intermediate elements.
17 | //!
18 | //! [`windows`]: slice::windows
19 | use crate::util::parse::*;
20 |
21 | pub fn parse(input: &str) -> Vec {
22 | input.iter_unsigned().collect()
23 | }
24 |
25 | pub fn part1(input: &[u32]) -> usize {
26 | input.windows(2).filter(|w| w[0] < w[1]).count()
27 | }
28 |
29 | pub fn part2(input: &[u32]) -> usize {
30 | input.windows(4).filter(|w| w[0] < w[3]).count()
31 | }
32 |
--------------------------------------------------------------------------------
/tests/year2022/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2022::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | Sensor at x=2, y=18: closest beacon is at x=-2, y=15
5 | Sensor at x=9, y=16: closest beacon is at x=10, y=16
6 | Sensor at x=13, y=2: closest beacon is at x=15, y=3
7 | Sensor at x=12, y=14: closest beacon is at x=10, y=16
8 | Sensor at x=10, y=20: closest beacon is at x=10, y=16
9 | Sensor at x=14, y=17: closest beacon is at x=10, y=16
10 | Sensor at x=8, y=7: closest beacon is at x=2, y=10
11 | Sensor at x=2, y=0: closest beacon is at x=2, y=10
12 | Sensor at x=0, y=11: closest beacon is at x=2, y=10
13 | Sensor at x=20, y=14: closest beacon is at x=25, y=17
14 | Sensor at x=17, y=20: closest beacon is at x=21, y=22
15 | Sensor at x=16, y=7: closest beacon is at x=15, y=3
16 | Sensor at x=14, y=3: closest beacon is at x=15, y=3
17 | Sensor at x=20, y=1: closest beacon is at x=15, y=3";
18 |
19 | #[test]
20 | fn part1_test() {
21 | let input = parse(EXAMPLE);
22 | assert_eq!(part1_testable(&input, 10), 26);
23 | }
24 |
25 | #[test]
26 | fn part2_test() {
27 | let input = parse(EXAMPLE);
28 | assert_eq!(part2_testable(&input, 20), 56000011);
29 | }
30 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | **Copyright © 2023-2025 maneatingape**
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/year2019/day01.rs:
--------------------------------------------------------------------------------
1 | //! # The Tyranny of the Rocket Equation
2 | //!
3 | //! The title of the problem is a reference to the
4 | //! [real life equation](https://en.wikipedia.org/wiki/Tsiolkovsky_rocket_equation).
5 | use crate::util::parse::*;
6 |
7 | /// The [`iter_unsigned`] utility method extracts and parses numbers from surrounding text.
8 | ///
9 | /// [`iter_unsigned`]: crate::util::parse
10 | pub fn parse(input: &str) -> Vec {
11 | input.iter_unsigned().collect()
12 | }
13 |
14 | /// Calculate fuel requirements following the formula.
15 | pub fn part1(input: &[u32]) -> u32 {
16 | input.iter().map(|mass| mass / 3 - 2).sum()
17 | }
18 |
19 | /// Calculate the fuel requirements taking into account that fuel needs more fuel to lift it.
20 | /// Mass of 8 or below results in zero or negative fuel so we can stop.
21 | pub fn part2(input: &[u32]) -> u32 {
22 | input
23 | .iter()
24 | .copied()
25 | .map(|mut mass| {
26 | let mut fuel = 0;
27 | while mass > 8 {
28 | mass = mass / 3 - 2;
29 | fuel += mass;
30 | }
31 | fuel
32 | })
33 | .sum()
34 | }
35 |
--------------------------------------------------------------------------------
/tests/year2021/day08.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day08::*;
2 |
3 | const EXAMPLE: &str = "\
4 | be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
5 | edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
6 | fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
7 | fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
8 | aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
9 | fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
10 | dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
11 | bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
12 | egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
13 | gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce";
14 |
15 | #[test]
16 | fn part1_test() {
17 | let input = parse(EXAMPLE);
18 | assert_eq!(part1(&input), 26);
19 | }
20 |
21 | #[test]
22 | fn part2_test() {
23 | let input = parse(EXAMPLE);
24 | assert_eq!(part2(&input), 61229);
25 | }
26 |
--------------------------------------------------------------------------------
/src/year2020/day05.rs:
--------------------------------------------------------------------------------
1 | //! # Binary Boarding
2 | //!
3 | //! The entire part one description is an obfuscated way to describe that each seat id is a 10 bit
4 | //! binary number, where `B` and `R` mean a 1 bit in that position and `F` and `L` mean a 0 bit.
5 | //!
6 | //! To solve part two we can have a little fun. Since we know that only a single seat is missing
7 | //! if we [XOR](https://en.wikipedia.org/wiki/XOR_gate) together all the seat ids from
8 | //! `min` to `max` then XOR with the actual seat ids, the result will be our missing seat id.
9 | pub struct Input {
10 | min: u32,
11 | max: u32,
12 | xor: u32,
13 | }
14 |
15 | pub fn parse(input: &str) -> Input {
16 | let (min, max, xor) = input.lines().fold((u32::MAX, u32::MIN, 0), |(min, max, xor), line| {
17 | let id = line.bytes().fold(0, |acc, b| (acc << 1) | (b == b'B' || b == b'R') as u32);
18 | (min.min(id), max.max(id), xor ^ id)
19 | });
20 |
21 | Input { min, max, xor }
22 | }
23 |
24 | pub fn part1(input: &Input) -> u32 {
25 | input.max
26 | }
27 |
28 | pub fn part2(input: &Input) -> u32 {
29 | let rows = (input.min..=input.max).fold(0, |acc, b| acc ^ b);
30 | rows ^ input.xor
31 | }
32 |
--------------------------------------------------------------------------------
/src/year2023/day04.rs:
--------------------------------------------------------------------------------
1 | //! # Scratchcards
2 | //!
3 | //! Part two is a dynamic programming problem. Starting with 1 copy of each card we add the extra
4 | //! number of copies to the number of following cards equal to the number of winning numbers.
5 | use crate::util::parse::*;
6 |
7 | pub fn parse(input: &str) -> Vec {
8 | input
9 | .lines()
10 | .map(|line| {
11 | // Numbers are at most 99 so we can use a fixed size array instead of a HashSet.
12 | let mut found = [false; 100];
13 | let (win, have) = line.split_once('|').unwrap();
14 | win.iter_unsigned::().skip(1).for_each(|i| found[i] = true);
15 | have.iter_unsigned::().filter(|&i| found[i]).count()
16 | })
17 | .collect()
18 | }
19 |
20 | pub fn part1(input: &[usize]) -> u32 {
21 | input.iter().map(|&n| (1 << n) >> 1).sum()
22 | }
23 |
24 | pub fn part2(input: &[usize]) -> u32 {
25 | // Start with a single copy of each card.
26 | let mut copies = vec![1; input.len()];
27 |
28 | for (i, &n) in input.iter().enumerate() {
29 | (0..n).for_each(|j| copies[i + j + 1] += copies[i]);
30 | }
31 |
32 | copies.iter().sum()
33 | }
34 |
--------------------------------------------------------------------------------
/src/year2016/day06.rs:
--------------------------------------------------------------------------------
1 | //! # Signals and Noise
2 | //!
3 | //! The cardinality of uppercase letters is only 26 so we can use a fixed size array to
4 | //! count the frequency of each character efficiently.
5 | type Input = (String, String);
6 |
7 | pub fn parse(input: &str) -> Input {
8 | let width = input.lines().next().unwrap().len();
9 | let stride = width + 1;
10 | let input = input.as_bytes();
11 |
12 | let to_index = |b: u8| (b - b'a') as usize;
13 | let to_char = |i: usize| ((i as u8) + b'a') as char;
14 |
15 | (0..width)
16 | .map(|offset| {
17 | let mut freq = [0; 26];
18 | input.iter().skip(offset).step_by(stride).for_each(|&b| freq[to_index(b)] += 1);
19 |
20 | let (max, _) =
21 | freq.iter().enumerate().filter(|&(_, &f)| f > 0).max_by_key(|&(_, &f)| f).unwrap();
22 | let (min, _) =
23 | freq.iter().enumerate().filter(|&(_, &f)| f > 0).min_by_key(|&(_, &f)| f).unwrap();
24 |
25 | (to_char(max), to_char(min))
26 | })
27 | .unzip()
28 | }
29 |
30 | pub fn part1(input: &Input) -> &str {
31 | &input.0
32 | }
33 |
34 | pub fn part2(input: &Input) -> &str {
35 | &input.1
36 | }
37 |
--------------------------------------------------------------------------------
/src/year2017/day09.rs:
--------------------------------------------------------------------------------
1 | //! # Stream Processing
2 | //!
3 | //! Computes both parts in a single pass.
4 | type Input = (u32, u32);
5 |
6 | pub fn parse(input: &str) -> Input {
7 | let mut iter = input.bytes();
8 | let mut groups = 0;
9 | let mut depth = 1;
10 | let mut characters = 0;
11 |
12 | while let Some(b) = iter.next() {
13 | match b {
14 | b'<' => {
15 | // Inner loop for garbage.
16 | while let Some(b) = iter.next() {
17 | match b {
18 | b'!' => {
19 | iter.next();
20 | }
21 | b'>' => break,
22 | _ => characters += 1,
23 | }
24 | }
25 | }
26 | b'{' => {
27 | groups += depth;
28 | depth += 1;
29 | }
30 | b'}' => {
31 | depth -= 1;
32 | }
33 | _ => (),
34 | }
35 | }
36 |
37 | (groups, characters)
38 | }
39 |
40 | pub fn part1(input: &Input) -> u32 {
41 | input.0
42 | }
43 |
44 | pub fn part2(input: &Input) -> u32 {
45 | input.1
46 | }
47 |
--------------------------------------------------------------------------------
/tests/year2024/day24.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day24::*;
2 |
3 | const EXAMPLE: &str = "\
4 | x00: 1
5 | x01: 0
6 | x02: 1
7 | x03: 1
8 | x04: 0
9 | y00: 1
10 | y01: 1
11 | y02: 1
12 | y03: 1
13 | y04: 1
14 |
15 | ntg XOR fgs -> mjb
16 | y02 OR x01 -> tnw
17 | kwq OR kpj -> z05
18 | x00 OR x03 -> fst
19 | tgd XOR rvg -> z01
20 | vdt OR tnw -> bfw
21 | bfw AND frj -> z10
22 | ffh OR nrd -> bqk
23 | y00 AND y03 -> djm
24 | y03 OR y00 -> psh
25 | bqk OR frj -> z08
26 | tnw OR fst -> frj
27 | gnj AND tgd -> z11
28 | bfw XOR mjb -> z00
29 | x03 OR x00 -> vdt
30 | gnj AND wpb -> z02
31 | x04 AND y00 -> kjc
32 | djm OR pbm -> qhw
33 | nrd AND vdt -> hwm
34 | kjc AND fst -> rvg
35 | y04 OR y02 -> fgs
36 | y01 AND x02 -> pbm
37 | ntg OR kjc -> kwq
38 | psh XOR fgs -> tgd
39 | qhw XOR tgd -> z09
40 | pbm OR djm -> kpj
41 | x03 XOR y03 -> ffh
42 | x00 XOR y04 -> ntg
43 | bfw OR bqk -> z06
44 | nrd XOR fgs -> wpb
45 | frj XOR qhw -> z04
46 | bqk OR frj -> z07
47 | y03 OR x01 -> nrd
48 | hwm AND bqk -> z03
49 | tgd XOR rvg -> z12
50 | tnw OR pbm -> gnj";
51 |
52 | #[test]
53 | fn part1_test() {
54 | let input = parse(EXAMPLE);
55 | assert_eq!(part1(&input), 2024);
56 | }
57 |
58 | #[test]
59 | fn part2_test() {
60 | // No test
61 | }
62 |
--------------------------------------------------------------------------------
/tests/year2024/day15.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2024::day15::*;
2 |
3 | const EXAMPLE: &str = "\
4 | ##########
5 | #..O..O.O#
6 | #......O.#
7 | #.OO..O.O#
8 | #..O@..O.#
9 | #O#..O...#
10 | #O..O..O.#
11 | #.OO.O.OO#
12 | #....O...#
13 | ##########
14 |
15 | ^v>^vv^v>v<>v^v<<><>>v^v^>^<<<><^
16 | vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<^<^^>>>^<>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^v^^<^^vv<
18 | <>^^^^>>>v^<>vvv^>^^^vv^^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
19 | ^><^><>>><>^^<<^^v>>><^^>v>>>^v><>^v><<<>vvvv>^<><<>^><
20 | ^>><>^v<><^vvv<^^<><^v<<<><<<^^<^>>^<<<^>>^v^>>^v>vv>^<<^v<>><<><<>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
22 | <><^^>^^^<>^vv<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
23 | ^^>vv<^v^v^<>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><
24 | v^^>>><<^^<>>^v^v^<<>^<^v^v><^<<<><<^vv>>v>v^<<^";
25 |
26 | #[test]
27 | fn part1_test() {
28 | let input = parse(EXAMPLE);
29 | assert_eq!(part1(&input), 10092);
30 | }
31 |
32 | #[test]
33 | fn part2_test() {
34 | let input = parse(EXAMPLE);
35 | assert_eq!(part2(&input), 9021);
36 | }
37 |
--------------------------------------------------------------------------------
/tests/year2021/day16.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2021::day16::*;
2 |
3 | #[test]
4 | fn part1_test() {
5 | let input = parse("8A004A801A8002F478");
6 | assert_eq!(part1(&input), 16);
7 |
8 | let input = parse("620080001611562C8802118E34");
9 | assert_eq!(part1(&input), 12);
10 |
11 | let input = parse("C0015000016115A2E0802F182340");
12 | assert_eq!(part1(&input), 23);
13 |
14 | let input = parse("A0016C880162017C3686B18A3D4780");
15 | assert_eq!(part1(&input), 31);
16 | }
17 |
18 | #[test]
19 | fn part2_test() {
20 | let input = parse("C200B40A82");
21 | assert_eq!(part2(&input), 3);
22 |
23 | let input = parse("04005AC33890");
24 | assert_eq!(part2(&input), 54);
25 |
26 | let input = parse("880086C3E88112");
27 | assert_eq!(part2(&input), 7);
28 |
29 | let input = parse("CE00C43D881120");
30 | assert_eq!(part2(&input), 9);
31 |
32 | let input = parse("D8005AC2A8F0");
33 | assert_eq!(part2(&input), 1);
34 |
35 | let input = parse("F600BC2D8F");
36 | assert_eq!(part2(&input), 0);
37 |
38 | let input = parse("9C005AC2F8F0");
39 | assert_eq!(part2(&input), 0);
40 |
41 | let input = parse("9C0141080250320F1802104A08");
42 | assert_eq!(part2(&input), 1);
43 | }
44 |
--------------------------------------------------------------------------------
/src/year2025/day05.rs:
--------------------------------------------------------------------------------
1 | //! # Cafeteria
2 | use crate::util::iter::*;
3 | use crate::util::parse::*;
4 | use std::ops::Range;
5 |
6 | type Input = (Vec>, Vec);
7 |
8 | pub fn parse(input: &str) -> Input {
9 | let (prefix, suffix) = input.split_once("\n\n").unwrap();
10 | let mut ranges: Vec<_> = prefix.iter_unsigned().chunk::<2>().collect();
11 | let mut ids: Vec<_> = suffix.iter_unsigned().collect();
12 | let mut range = 0..0;
13 | let mut merged = Vec::new();
14 |
15 | ranges.sort_unstable();
16 | ids.sort_unstable();
17 |
18 | for [from, to] in ranges {
19 | if from < range.end {
20 | range.end = range.end.max(to + 1);
21 | } else {
22 | merged.push(range);
23 | range = from..to + 1;
24 | }
25 | }
26 |
27 | merged.push(range);
28 | (merged, ids)
29 | }
30 |
31 | pub fn part1(input: &Input) -> usize {
32 | let (merged, ids) = input;
33 | let position = |id: u64| ids.binary_search(&id).unwrap_or_else(|e| e);
34 | merged.iter().map(|range| position(range.end) - position(range.start)).sum()
35 | }
36 |
37 | pub fn part2(input: &Input) -> u64 {
38 | let (merged, _) = input;
39 | merged.iter().map(|range| range.end - range.start).sum()
40 | }
41 |
--------------------------------------------------------------------------------
/src/year2017/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Corruption Checksum
2 | //!
3 | //! Part two is `O(n²)` complexity but at least we can reduce by a factor of two by sorting
4 | //! each line first, allowing us to only compare each number against those that are greater.
5 | //! As a minor benefit this makes part one faster too.
6 | use crate::util::parse::*;
7 |
8 | type Input = Vec>;
9 |
10 | pub fn parse(input: &str) -> Input {
11 | input
12 | .lines()
13 | .map(|line| {
14 | let mut values: Vec<_> = line.iter_unsigned().collect();
15 | values.sort_unstable();
16 | values
17 | })
18 | .collect()
19 | }
20 |
21 | pub fn part1(input: &Input) -> u32 {
22 | input.iter().map(|values| values.last().unwrap() - values.first().unwrap()).sum()
23 | }
24 |
25 | pub fn part2(input: &Input) -> u32 {
26 | input
27 | .iter()
28 | .map(|values| {
29 | for (i, &smaller) in values.iter().enumerate() {
30 | for &larger in &values[i + 1..] {
31 | if larger.is_multiple_of(smaller) {
32 | return larger / smaller;
33 | }
34 | }
35 | }
36 | unreachable!()
37 | })
38 | .sum()
39 | }
40 |
--------------------------------------------------------------------------------
/src/year2025/day06.rs:
--------------------------------------------------------------------------------
1 | //! # Trash Compactor
2 | use crate::util::grid::*;
3 | use crate::util::point::*;
4 |
5 | type Input = (u64, u64);
6 |
7 | pub fn parse(input: &str) -> Input {
8 | let grid = Grid::parse(input);
9 | let bottom = grid.height - 1;
10 | let mut right = grid.width;
11 |
12 | let block = |(part_one, part_two), left| {
13 | let rows = (0..bottom).map(|y| (left..right).fold(0, |num, x| acc(&grid, num, x, y)));
14 | let cols = (left..right).map(|x| (0..bottom).fold(0, |num, y| acc(&grid, num, x, y)));
15 |
16 | let plus = grid[Point::new(left, bottom)] == b'+';
17 | let first: u64 = if plus { rows.sum() } else { rows.product() };
18 | let second: u64 = if plus { cols.sum() } else { cols.product() };
19 |
20 | right = left - 1;
21 | (part_one + first, part_two + second)
22 | };
23 |
24 | (0..grid.width).rev().filter(|&x| grid[Point::new(x, bottom)] != b' ').fold((0, 0), block)
25 | }
26 |
27 | pub fn part1(input: &Input) -> u64 {
28 | input.0
29 | }
30 |
31 | pub fn part2(input: &Input) -> u64 {
32 | input.1
33 | }
34 |
35 | fn acc(grid: &Grid, number: u64, x: i32, y: i32) -> u64 {
36 | let digit = grid[Point::new(x, y)];
37 | if digit == b' ' { number } else { 10 * number + u64::from(digit - b'0') }
38 | }
39 |
--------------------------------------------------------------------------------
/src/year2015/day03.rs:
--------------------------------------------------------------------------------
1 | //! # Perfectly Spherical Houses in a Vacuum
2 | //!
3 | //! We store Santa's path in a [`FastSet`] of [`Point`] objects that deduplicates visited points.
4 | //! For part two we alternate between Santa and the robot, tracking two points simultaneously and
5 | //! reusing the same deduplicating logic as part one.
6 | //!
7 | //! [`FastSet`]: crate::util::hash
8 | //! [`Point`]: crate::util::point
9 | use crate::util::hash::*;
10 | use crate::util::point::*;
11 |
12 | pub fn parse(input: &str) -> Vec {
13 | input.trim().bytes().map(Point::from).collect()
14 | }
15 |
16 | pub fn part1(input: &[Point]) -> usize {
17 | deliver(input, |_| true)
18 | }
19 |
20 | pub fn part2(input: &[Point]) -> usize {
21 | deliver(input, |i| i.is_multiple_of(2))
22 | }
23 |
24 | fn deliver(input: &[Point], predicate: fn(usize) -> bool) -> usize {
25 | let mut santa = ORIGIN;
26 | let mut robot = ORIGIN;
27 |
28 | let mut set = FastSet::with_capacity(input.len());
29 | set.insert(ORIGIN);
30 |
31 | for (index, &point) in input.iter().enumerate() {
32 | if predicate(index) {
33 | santa += point;
34 | set.insert(santa);
35 | } else {
36 | robot += point;
37 | set.insert(robot);
38 | }
39 | }
40 |
41 | set.len()
42 | }
43 |
--------------------------------------------------------------------------------
/src/year2017/day19.rs:
--------------------------------------------------------------------------------
1 | //! # A Series of Tubes
2 | //!
3 | //! Uses the utility [`Grid`] to parse the input, then the [`Point`] class to follow the path.
4 | //!
5 | //! [`Grid`]: crate::util::grid
6 | //! [`Point`]: crate::util::point
7 | use crate::util::grid::*;
8 | use crate::util::point::*;
9 |
10 | type Input = (String, u32);
11 |
12 | pub fn parse(input: &str) -> Input {
13 | let grid = Grid::parse(input);
14 |
15 | let mut position = grid.find(b'|').unwrap();
16 | let mut direction = DOWN;
17 |
18 | let mut part_one = String::new();
19 | let mut part_two = 0;
20 |
21 | loop {
22 | let next = grid[position];
23 |
24 | match next {
25 | b'+' => {
26 | let left = direction.counter_clockwise();
27 | let right = direction.clockwise();
28 | direction = if grid[position + right] == b' ' { left } else { right };
29 | }
30 | b' ' => break,
31 | _ if next.is_ascii_alphabetic() => part_one.push(next as char),
32 | _ => (),
33 | }
34 |
35 | position += direction;
36 | part_two += 1;
37 | }
38 |
39 | (part_one, part_two)
40 | }
41 |
42 | pub fn part1(input: &Input) -> &str {
43 | input.0.as_str()
44 | }
45 |
46 | pub fn part2(input: &Input) -> u32 {
47 | input.1
48 | }
49 |
--------------------------------------------------------------------------------
/src/year2022/day10.rs:
--------------------------------------------------------------------------------
1 | //! # Cathode-Ray Tube
2 | use crate::util::parse::*;
3 |
4 | /// Tokenizes the input treating both "noop" and "addx" as no-ops to obtain the correct
5 | /// instruction timing. Produces a `vec` of the absolute values of `x` from cycle 0 to 241.
6 | pub fn parse(input: &str) -> Vec {
7 | let mut x = 1;
8 | let mut xs = vec![1];
9 |
10 | for token in input.split_ascii_whitespace() {
11 | match token {
12 | "noop" | "addx" => (),
13 | delta => x += delta.signed::(),
14 | }
15 | xs.push(x);
16 | }
17 |
18 | xs
19 | }
20 |
21 | /// Converts between the 0-based indexing produced by the `parse` function and the 1-based indexing
22 | /// used by the problem statement.
23 | pub fn part1(input: &[i32]) -> i32 {
24 | input.iter().enumerate().skip(19).step_by(40).map(|(i, &x)| ((i + 1) as i32) * x).sum()
25 | }
26 |
27 | /// Returns pixels as a multi-line [`String`] so that the entire function can be integration tested.
28 | pub fn part2(input: &[i32]) -> String {
29 | let mut result = String::new();
30 |
31 | for row in input.chunks_exact(40) {
32 | result.push('\n');
33 | for (i, &c) in row.iter().enumerate() {
34 | result.push(if ((i as i32) - c).abs() <= 1 { '#' } else { '.' });
35 | }
36 | }
37 |
38 | result
39 | }
40 |
--------------------------------------------------------------------------------
/src/year2023/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Cube Conundrum
2 | use crate::util::iter::*;
3 | use crate::util::parse::*;
4 |
5 | type Game = (u32, u32, u32);
6 |
7 | /// Parse each game into the maximum red, green and blue values.
8 | pub fn parse(input: &str) -> Vec {
9 | input
10 | .lines()
11 | .map(|line| {
12 | line.split_ascii_whitespace().chunk::<2>().skip(1).fold(
13 | (0, 0, 0),
14 | |(r, g, b), [amount, color]| {
15 | let amount = amount.unsigned();
16 | match color.as_bytes()[0] {
17 | b'r' => (r.max(amount), g, b),
18 | b'g' => (r, g.max(amount), b),
19 | b'b' => (r, g, b.max(amount)),
20 | _ => unreachable!(),
21 | }
22 | },
23 | )
24 | })
25 | .collect()
26 | }
27 |
28 | /// Sum the ids for all valid games.
29 | pub fn part1(input: &[Game]) -> usize {
30 | input
31 | .iter()
32 | .enumerate()
33 | .filter_map(|(id, &(r, g, b))| (r <= 12 && g <= 13 && b <= 14).then_some(id + 1))
34 | .sum()
35 | }
36 |
37 | /// Sum the product of maximum red, green and blue values.
38 | pub fn part2(input: &[Game]) -> u32 {
39 | input.iter().map(|(r, g, b)| r * g * b).sum()
40 | }
41 |
--------------------------------------------------------------------------------
/tests/year2020/day19.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day19::*;
2 |
3 | const EXAMPLE: &str = "\
4 | 42: 9 14 | 10 1
5 | 9: 14 27 | 1 26
6 | 10: 23 14 | 28 1
7 | 1: \"a\"
8 | 11: 42 31
9 | 5: 1 14 | 15 1
10 | 19: 14 1 | 14 14
11 | 12: 24 14 | 19 1
12 | 16: 15 1 | 14 14
13 | 31: 14 17 | 1 13
14 | 6: 14 14 | 1 14
15 | 2: 1 24 | 14 4
16 | 0: 8 11
17 | 13: 14 3 | 1 12
18 | 15: 1 | 14
19 | 17: 14 2 | 1 7
20 | 23: 25 1 | 22 14
21 | 28: 16 1
22 | 4: 1 1
23 | 20: 14 14 | 1 15
24 | 3: 5 14 | 16 1
25 | 27: 1 6 | 14 18
26 | 14: \"b\"
27 | 21: 14 1 | 1 14
28 | 25: 1 1 | 1 14
29 | 22: 14 14
30 | 8: 42
31 | 26: 14 22 | 1 20
32 | 18: 15 15
33 | 7: 14 5 | 1 21
34 | 24: 14 1
35 |
36 | abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
37 | bbabbbbaabaabba
38 | babbbbaabbbbbabbbbbbaabaaabaaa
39 | aaabbbbbbaaaabaababaabababbabaaabbababababaaa
40 | bbbbbbbaaaabbbbaaabbabaaa
41 | bbbababbbbaaaaaaaabbababaaababaabab
42 | ababaaaaaabaaab
43 | ababaaaaabbbaba
44 | baabbaaaabbaaaababbaababb
45 | abbbbabbbbaaaababbbbbbaaaababb
46 | aaaaabbaabaaaaababaa
47 | aaaabbaaaabbaaa
48 | aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
49 | babaaabbbaaabaababbaabababaaab
50 | aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba";
51 |
52 | #[test]
53 | fn part1_test() {
54 | let input = parse(EXAMPLE);
55 | assert_eq!(part1(&input), 3);
56 | }
57 |
58 | #[test]
59 | fn part2_test() {
60 | let input = parse(EXAMPLE);
61 | assert_eq!(part2(&input), 12);
62 | }
63 |
--------------------------------------------------------------------------------
/src/year2018/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Inventory Management System
2 | use crate::util::hash::*;
3 |
4 | pub fn parse(input: &str) -> Vec<&[u8]> {
5 | input.lines().map(str::as_bytes).collect()
6 | }
7 |
8 | pub fn part1(input: &[&[u8]]) -> u32 {
9 | let mut twos = 0;
10 | let mut threes = 0;
11 |
12 | for &id in input {
13 | // Ids are lowercase ASCII only with cardinality of 26.
14 | let mut freq = [0_u8; 26];
15 |
16 | for &b in id {
17 | freq[(b - b'a') as usize] += 1;
18 | }
19 |
20 | twos += freq.contains(&2) as u32;
21 | threes += freq.contains(&3) as u32;
22 | }
23 |
24 | twos * threes
25 | }
26 |
27 | pub fn part2(input: &[&[u8]]) -> String {
28 | let width = input[0].len();
29 | let mut seen = FastSet::with_capacity(input.len());
30 |
31 | // Use a set to check for duplicates by comparing the prefix and suffix of IDs excluding one
32 | // column at a time.
33 | for column in 0..width {
34 | for &id in input {
35 | let prefix = &id[..column];
36 | let suffix = &id[column + 1..];
37 |
38 | if !seen.insert([prefix, suffix]) {
39 | // Convert to String
40 | return prefix.iter().chain(suffix).copied().map(char::from).collect();
41 | }
42 | }
43 |
44 | seen.clear();
45 | }
46 |
47 | unreachable!()
48 | }
49 |
--------------------------------------------------------------------------------
/src/year2016/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Bathroom Security
2 | //!
3 | //! Relies heavily on the [`point`] and [`grid`] modules.
4 | //!
5 | //! [`grid`]: crate::util::grid
6 | //! [`point`]: crate::util::point
7 | use crate::util::grid::*;
8 | use crate::util::point::*;
9 |
10 | pub fn parse(input: &str) -> Vec<&str> {
11 | input.lines().collect()
12 | }
13 |
14 | pub fn part1(input: &[&str]) -> String {
15 | let digits = Grid::parse("123\n456\n789");
16 | let mut position = ORIGIN;
17 | let mut result = String::new();
18 |
19 | for line in input {
20 | for b in line.bytes() {
21 | let next = position + Point::from(b);
22 | if next.x.abs() <= 1 && next.y.abs() <= 1 {
23 | position = next;
24 | }
25 | }
26 | result.push(digits[position + Point::new(1, 1)] as char);
27 | }
28 |
29 | result
30 | }
31 |
32 | pub fn part2(input: &[&str]) -> String {
33 | let digits = Grid::parse("##1##\n#234#\n56789\n#ABC#\n##D##");
34 | let mut position = Point::new(-2, 0);
35 | let mut result = String::new();
36 |
37 | for line in input {
38 | for b in line.bytes() {
39 | let next = position + Point::from(b);
40 | if next.manhattan(ORIGIN) <= 2 {
41 | position = next;
42 | }
43 | }
44 | result.push(digits[position + Point::new(2, 2)] as char);
45 | }
46 |
47 | result
48 | }
49 |
--------------------------------------------------------------------------------
/tests/year2020/day04.rs:
--------------------------------------------------------------------------------
1 | use aoc::year2020::day04::*;
2 |
3 | const FIRST_EXAMPLE: &str = "\
4 | ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
5 | byr:1937 iyr:2017 cid:147 hgt:183cm
6 |
7 | iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
8 | hcl:#cfa07d byr:1929
9 |
10 | hcl:#ae17e1 iyr:2013
11 | eyr:2024
12 | ecl:brn pid:760753108 byr:1931
13 | hgt:179cm
14 |
15 | hcl:#cfa07d eyr:2025 pid:166559648
16 | iyr:2011 ecl:brn hgt:59in";
17 |
18 | const SECOND_EXAMPLE: &str = "\
19 | eyr:1972 cid:100
20 | hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926
21 |
22 | iyr:2019
23 | hcl:#602927 eyr:1967 hgt:170cm
24 | ecl:grn pid:012533040 byr:1946
25 |
26 | hcl:dab227 iyr:2012
27 | ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277
28 |
29 | hgt:59cm ecl:zzz
30 | eyr:2038 hcl:74454a iyr:2023
31 | pid:3556412378 byr:2007
32 |
33 | pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
34 | hcl:#623a2f
35 |
36 | eyr:2029 ecl:blu cid:129 byr:1989
37 | iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm
38 |
39 | hcl:#888785
40 | hgt:164cm byr:2001 iyr:2015 cid:88
41 | pid:545766238 ecl:hzl
42 | eyr:2022
43 |
44 | iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719";
45 |
46 | #[test]
47 | fn part1_test() {
48 | let input = parse(FIRST_EXAMPLE);
49 | assert_eq!(part1(&input), 2);
50 | }
51 |
52 | #[test]
53 | fn part2_test() {
54 | let input = parse(SECOND_EXAMPLE);
55 | assert_eq!(part2(&input), 4);
56 | }
57 |
--------------------------------------------------------------------------------
/src/year2020/day10.rs:
--------------------------------------------------------------------------------
1 | //! # Adapter Array
2 | //!
3 | //! Part one uses the [`windows`] function to iterate over all pairs counting the differences.
4 | //!
5 | //! Part two is a classic [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming)
6 | //! problem. The charging outlet can be arranged in exactly one way. Each subsequent adapter can be
7 | //! arranged in the sum of the number of ways that the adapters at -1, -2 and -3 jolts can be
8 | //! arranged.
9 | //!
10 | //! [`windows`]: slice::windows
11 | use crate::util::parse::*;
12 |
13 | pub fn parse(input: &str) -> Vec {
14 | let mut adapters: Vec<_> = input.iter_unsigned().collect();
15 | adapters.sort_unstable();
16 | adapters
17 | }
18 |
19 | pub fn part1(input: &[usize]) -> usize {
20 | let mut total = [0, 0, 0, 1];
21 | total[input[0]] += 1;
22 |
23 | for w in input.windows(2) {
24 | let diff = w[0].abs_diff(w[1]);
25 | total[diff] += 1;
26 | }
27 |
28 | total[1] * total[3]
29 | }
30 |
31 | pub fn part2(input: &[usize]) -> usize {
32 | let last = input.last().unwrap();
33 | let mut sum = vec![0; last + 1];
34 | sum[0] = 1;
35 |
36 | for &i in input {
37 | match i {
38 | 1 => sum[i] = sum[i - 1],
39 | 2 => sum[i] = sum[i - 1] + sum[i - 2],
40 | _ => sum[i] = sum[i - 1] + sum[i - 2] + sum[i - 3],
41 | }
42 | }
43 |
44 | *sum.last().unwrap()
45 | }
46 |
--------------------------------------------------------------------------------
/src/year2025/day11.rs:
--------------------------------------------------------------------------------
1 | //! # Reactor
2 | type Input = Vec>;
3 |
4 | pub fn parse(input: &str) -> Input {
5 | let mut graph = vec![vec![]; 26 * 26 * 26];
6 |
7 | for line in input.lines() {
8 | let mut edges = line.split_ascii_whitespace();
9 | let from = edges.next().unwrap();
10 | graph[to_index(from)].extend(edges.map(to_index));
11 | }
12 |
13 | graph
14 | }
15 |
16 | pub fn part1(input: &Input) -> u64 {
17 | paths(input, "you", "out")
18 | }
19 |
20 | pub fn part2(input: &Input) -> u64 {
21 | let one = paths(input, "svr", "fft") * paths(input, "fft", "dac") * paths(input, "dac", "out");
22 | let two = paths(input, "svr", "dac") * paths(input, "dac", "fft") * paths(input, "fft", "out");
23 | one + two
24 | }
25 |
26 | fn paths(input: &Input, from: &str, to: &str) -> u64 {
27 | let mut cache = vec![u64::MAX; input.len()];
28 | dfs(input, &mut cache, to_index(from), to_index(to))
29 | }
30 |
31 | fn dfs(input: &Input, cache: &mut [u64], node: usize, end: usize) -> u64 {
32 | if node == end {
33 | 1
34 | } else if cache[node] == u64::MAX {
35 | let result = input[node].iter().map(|&next| dfs(input, cache, next, end)).sum();
36 | cache[node] = result;
37 | result
38 | } else {
39 | cache[node]
40 | }
41 | }
42 |
43 | fn to_index(s: &str) -> usize {
44 | s.bytes().take(3).fold(0, |acc, b| 26 * acc + usize::from(b - b'a'))
45 | }
46 |
--------------------------------------------------------------------------------
/src/year2024/day25.rs:
--------------------------------------------------------------------------------
1 | //! # Code Chronicle
2 | //!
3 | //! Efficiently checks if locks and keys overlap using bitwise logic. The ASCII character
4 | //! `#` (35) is odd and `.` (46) is even so bitwise AND with 1 results in either 1 or 0.
5 | //! The newline character `\n` (10) is even so will result in 0 and not contribute to matches.
6 | //! There are 25 bits plus 4 newline bits so each lock or key can be stored in an `u32`.
7 | //! For example:
8 | //!
9 | //! ```none
10 | //! #####
11 | //! ##.## 11011
12 | //! .#.## 01011
13 | //! ...## => 00011 => 110110_010110_000110_000100_00010
14 | //! ...#. 00010
15 | //! ...#. 00010
16 | //! .....
17 | //! ```
18 | pub fn parse(input: &str) -> &str {
19 | input
20 | }
21 |
22 | pub fn part1(input: &str) -> u32 {
23 | let mut locks = Vec::with_capacity(250);
24 | let mut keys = Vec::with_capacity(250);
25 | let mut result = 0;
26 |
27 | for slice in input.as_bytes().chunks(43) {
28 | let bits = slice[6..35].iter().fold(0, |bits, &n| (bits << 1) | (n & 1) as u32);
29 |
30 | if slice[0] == b'#' {
31 | locks.push(bits);
32 | } else {
33 | keys.push(bits);
34 | }
35 | }
36 |
37 | for lock in &locks {
38 | for key in &keys {
39 | result += (lock & key == 0) as u32;
40 | }
41 | }
42 |
43 | result
44 | }
45 |
46 | pub fn part2(_input: &str) -> &'static str {
47 | "n/a"
48 | }
49 |
--------------------------------------------------------------------------------
/src/year2021/day07.rs:
--------------------------------------------------------------------------------
1 | //! # The Treachery of Whales
2 | //!
3 | //! Part 1 is a disguised definition of the mathematical [median](https://en.wikipedia.org/wiki/Median).
4 | //! We can calculate the result immediately using the standard algorithm.
5 | //!
6 | //! Part 2 is found by using the [mean](https://en.wikipedia.org/wiki/Mean).
7 | //! However since this could a floating point value and we are using integers we need to check
8 | //! 3 values total, the rounded result and one value on either side to ensure the correct answer.
9 | use crate::util::parse::*;
10 |
11 | pub fn parse(input: &str) -> Vec {
12 | input.iter_signed().collect()
13 | }
14 |
15 | pub fn part1(input: &[i32]) -> i32 {
16 | let median = median(input);
17 | input.iter().map(|n| (n - median).abs()).sum()
18 | }
19 |
20 | pub fn part2(input: &[i32]) -> i32 {
21 | let mean = mean(input);
22 | let triangle = |x: i32, mean: i32| {
23 | let n = (x - mean).abs();
24 | (n * (n + 1)) / 2
25 | };
26 |
27 | (-1..=1).map(|delta| input.iter().map(|&x| triangle(x, mean + delta)).sum()).min().unwrap()
28 | }
29 |
30 | fn median(input: &[i32]) -> i32 {
31 | let mut crabs = input.to_vec();
32 | crabs.sort_unstable();
33 |
34 | let half = input.len() / 2;
35 | if crabs.len().is_multiple_of(2) { crabs[half - 1].midpoint(crabs[half]) } else { crabs[half] }
36 | }
37 |
38 | fn mean(input: &[i32]) -> i32 {
39 | let sum: i32 = input.iter().sum();
40 | sum / (input.len() as i32)
41 | }
42 |
--------------------------------------------------------------------------------
/src/year2016/day09.rs:
--------------------------------------------------------------------------------
1 | //! # Explosives in Cyberspace
2 | //!
3 | //! The only difference between part one and two is that we recursively decompress inner sequences.
4 | use crate::util::parse::*;
5 |
6 | pub fn parse(input: &str) -> &[u8] {
7 | input.trim().as_bytes()
8 | }
9 |
10 | pub fn part1(input: &[u8]) -> usize {
11 | decompress(input, false)
12 | }
13 |
14 | pub fn part2(input: &[u8]) -> usize {
15 | decompress(input, true)
16 | }
17 |
18 | fn decompress(mut slice: &[u8], part_two: bool) -> usize {
19 | let mut length = 0;
20 |
21 | // Find the next marker.
22 | while let Some(start) = slice.iter().position(|&b| b == b'(') {
23 | let (next, amount) = number(&slice[start + 1..]);
24 | let (next, repeat) = number(next);
25 |
26 | // For part two, recursively decompress data.
27 | let result = if part_two { decompress(&next[..amount], true) } else { amount };
28 |
29 | slice = &next[amount..];
30 | length += start + result * repeat;
31 | }
32 |
33 | // Add remaining plain data that doesn't contain any marker.
34 | length + slice.len()
35 | }
36 |
37 | fn number(slice: &[u8]) -> (&[u8], usize) {
38 | // Parse number digit by digit.
39 | let mut index = 0;
40 | let mut acc = 0;
41 |
42 | while slice[index].is_ascii_digit() {
43 | acc = 10 * acc + slice[index].to_decimal() as usize;
44 | index += 1;
45 | }
46 |
47 | // Skip over trailing delimeter.
48 | (&slice[index + 1..], acc)
49 | }
50 |
--------------------------------------------------------------------------------
/src/year2025/day02.rs:
--------------------------------------------------------------------------------
1 | //! # Gift Shop
2 | use crate::util::iter::*;
3 | use crate::util::parse::*;
4 |
5 | type Range = [u32; 2];
6 | type Pair = [u64; 2];
7 |
8 | const FIRST: [Range; 5] = [[2, 1], [4, 2], [6, 3], [8, 4], [10, 5]];
9 | const SECOND: [Range; 6] = [[3, 1], [5, 1], [6, 2], [7, 1], [9, 3], [10, 2]];
10 | const THIRD: [Range; 2] = [[6, 1], [10, 1]];
11 |
12 | pub fn parse(input: &str) -> Vec {
13 | input.iter_unsigned::().chunk::<2>().collect()
14 | }
15 |
16 | pub fn part1(input: &[Pair]) -> u64 {
17 | sum(&FIRST, input)
18 | }
19 |
20 | pub fn part2(input: &[Pair]) -> u64 {
21 | sum(&FIRST, input) + sum(&SECOND, input) - sum(&THIRD, input)
22 | }
23 |
24 | fn sum(ranges: &[Range], input: &[Pair]) -> u64 {
25 | let mut result = 0;
26 |
27 | for &[digits, size] in ranges {
28 | let digits_power = 10_u64.pow(digits);
29 | let size_power = 10_u64.pow(size);
30 |
31 | let step = (digits_power - 1) / (size_power - 1);
32 | let start = step * (size_power / 10);
33 | let end = step * (size_power - 1);
34 |
35 | for &[from, to] in input {
36 | let lower = from.next_multiple_of(step).max(start);
37 | let upper = to.min(end);
38 |
39 | if lower <= upper {
40 | let n = (upper - lower) / step;
41 | let triangular = n * (n + 1) / 2;
42 | result += lower * (n + 1) + step * triangular;
43 | }
44 | }
45 | }
46 |
47 | result
48 | }
49 |
--------------------------------------------------------------------------------
/src/util/integer.rs:
--------------------------------------------------------------------------------
1 | //! Combines common [operators](https://doc.rust-lang.org/book/appendix-02-operators.html)
2 | //! and constants `0`, `1` and `10` to enable generic methods on integer types.
3 | use std::ops::*;
4 |
5 | pub trait Integer:
6 | Copy
7 | + From
8 | + PartialEq
9 | + PartialOrd
10 | + Add