mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Compare commits
42 Commits
09e012c082
...
2022/day-2
| Author | SHA1 | Date | |
|---|---|---|---|
| 561fd2f07c | |||
| 256d351f8e | |||
| 48594a75e6 | |||
| 85a51b13c1 | |||
| 2ae2d6baa8 | |||
| 4a55e53182 | |||
| af0897300d | |||
| cabae7b1fd | |||
| 0635141ac6 | |||
| d9d5947c3b | |||
| cc8b4ce353 | |||
| 0b91da04b3 | |||
| dba146b299 | |||
| 33111615be | |||
| 04e8a41d98 | |||
| 36d76018ba | |||
| 4172fd0463 | |||
| ad0b4a4659 | |||
| 2dab7342f8 | |||
| edd14a0e3d | |||
| 4d7188e1ff | |||
| 255edaca79 | |||
| 8ea716cba8 | |||
| 601de2c565 | |||
| 894524bc81 | |||
| f19bf28f34 | |||
| de3a24a87c | |||
| 09b590e927 | |||
| 9dacb4c1ae | |||
| 07e03c1630 | |||
| 3accf9845d | |||
| fd26f58e25 | |||
| b2f9898714 | |||
| d757c389f0 | |||
| fd561a3e9d | |||
| 2fcdc6b8d2 | |||
| 8a3f0f843c | |||
| 23b5c39838 | |||
| 452f6e5f14 | |||
| 61fb240622 | |||
| aee25057d6 | |||
| a98332894f |
@@ -1,7 +1,7 @@
|
||||
on:
|
||||
- push
|
||||
|
||||
name: Advent of Code 2021
|
||||
name: Advent of Code 2022
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -30,17 +30,23 @@ jobs:
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Set up caching
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: >
|
||||
2022 -> target
|
||||
|
||||
- name: Build binaries
|
||||
working-directory: 2021
|
||||
working-directory: 2022
|
||||
run: >
|
||||
cargo build --all-targets
|
||||
|
||||
- name: Run tests
|
||||
working-directory: 2021
|
||||
working-directory: 2022
|
||||
run: >
|
||||
cargo test
|
||||
|
||||
- name: Run clippy
|
||||
working-directory: 2021
|
||||
working-directory: 2022
|
||||
run: >
|
||||
cargo clippy -- --deny warnings
|
||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex = "0.1"
|
||||
regex = "1"
|
||||
|
||||
@@ -73,10 +73,10 @@ fn main() {
|
||||
let door_label = line.unwrap();
|
||||
let caps = room_pattern.captures(&door_label).unwrap();
|
||||
|
||||
let name = caps.at(1).unwrap();
|
||||
let checksum = caps.at(4).unwrap();
|
||||
let name = caps.get(1).unwrap().as_str();
|
||||
let checksum = caps.get(4).unwrap().as_str();
|
||||
if is_valid(name, checksum) {
|
||||
let sector_id = caps.at(3).unwrap().parse().unwrap();
|
||||
let sector_id = caps.get(3).unwrap().as_str().parse().unwrap();
|
||||
cur_sum += sector_id;
|
||||
|
||||
let decoded: String = name.chars()
|
||||
|
||||
@@ -4,5 +4,5 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex = "^0.1"
|
||||
lazy_static = "^0.2"
|
||||
regex = "1"
|
||||
lazy_static = "1"
|
||||
|
||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex="^0.1"
|
||||
regex="1"
|
||||
|
||||
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3.0.0-rc.0", features = ["derive"] }
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
itertools = "0.10"
|
||||
nom = "7"
|
||||
|
||||
|
||||
@@ -20,3 +20,15 @@ OPTIONS:
|
||||
-i, --input <INPUT> Read input from the given file instead of stdin
|
||||
-t, --time Print time taken
|
||||
```
|
||||
|
||||
## That goal was achieved
|
||||
|
||||
Runtime benchmarked with [Criterion], reading input directly from memory to avoid disk IO
|
||||
inconsistencies.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
[Criterion]: https://github.com/bheisler/criterion.rs
|
||||
|
||||
@@ -7,7 +7,7 @@ use criterion::criterion_main;
|
||||
use criterion::BenchmarkId;
|
||||
use criterion::Criterion;
|
||||
|
||||
const DAYS_IMPLEMENTED: usize = 18;
|
||||
const DAYS_IMPLEMENTED: usize = 25;
|
||||
|
||||
fn read_input(day: usize) -> Vec<u8> {
|
||||
let input_path = format!("inputs/{:02}.txt", day);
|
||||
@@ -26,15 +26,18 @@ pub fn benchmark_days(c: &mut Criterion) {
|
||||
let input = read_input(day);
|
||||
|
||||
let part1 = get_implementation(day, false);
|
||||
let part2 = get_implementation(day, true);
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
|
||||
b.iter(|| part1(&mut &i[..]));
|
||||
});
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
|
||||
b.iter(|| part2(&mut &i[..]));
|
||||
});
|
||||
if day < 25 {
|
||||
let part2 = get_implementation(day, true);
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
|
||||
b.iter(|| part2(&mut &i[..]));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
97
2021/create_timing_plots.py
Executable file
97
2021/create_timing_plots.py
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def read_timings() -> Dict[int, Dict]:
|
||||
timings = {}
|
||||
|
||||
for day in Path('target/criterion/part1').iterdir():
|
||||
with open(day / 'new' / 'estimates.json', mode='rb') as f:
|
||||
timings[int(day.parts[-1])] = {
|
||||
1: json.load(f)
|
||||
}
|
||||
|
||||
for day in Path('target/criterion/part2').iterdir():
|
||||
with open(day / 'new' / 'estimates.json', mode='rb') as f:
|
||||
timings[int(day.parts[-1])][2] = json.load(f)
|
||||
|
||||
return timings
|
||||
|
||||
|
||||
def plot_cumulative_time(timings: Dict[int, Dict]):
|
||||
plt.clf()
|
||||
|
||||
times = [0]
|
||||
|
||||
for day in range(min(timings.keys()), max(timings.keys()) + 1):
|
||||
times.append(timings[day][1]['mean']['point_estimate'])
|
||||
if day < 25:
|
||||
times.append(timings[day][2]['mean']['point_estimate'])
|
||||
else:
|
||||
times.append(0)
|
||||
|
||||
cumulative = np.cumsum(times)
|
||||
# Convert from nanoseconds to seconds
|
||||
cumulative /= 1e9
|
||||
|
||||
x = np.arange(0.0, 25.5, 0.5)
|
||||
|
||||
plt.plot(x, cumulative, label="Cumulative time", drawstyle='steps-post')
|
||||
plt.plot([0, 25], [0, 0.5], label="Target time")
|
||||
plt.ylabel('Cumulative time (s)')
|
||||
plt.xlabel('Days completed')
|
||||
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
|
||||
plt.xlim(0, 25)
|
||||
plt.ylim(0, 0.5)
|
||||
|
||||
plt.savefig('cumulative-time.svg')
|
||||
|
||||
|
||||
def plot_individual_times(timings: Dict[int, Dict]):
|
||||
plt.clf()
|
||||
|
||||
def plot(parts, **kwargs):
|
||||
x = np.arange(1, len(parts) + 1)
|
||||
|
||||
values = np.array(list(part['mean']['point_estimate'] for part in parts))
|
||||
upper = np.array(list(part['mean']['confidence_interval']['upper_bound'] for part in parts))
|
||||
lower = np.array(list(part['mean']['confidence_interval']['lower_bound'] for part in parts))
|
||||
|
||||
# Convert from ns to s
|
||||
yerr = np.array([upper - values, lower - values]) / 1e9
|
||||
values = values / 1e9
|
||||
|
||||
plt.bar(x, values, yerr=yerr, align='edge', log=True, **kwargs)
|
||||
pass
|
||||
|
||||
plot(list(timings[day][1] for day in range(1, 26)), label="Part 1", width=-0.4)
|
||||
plot(list(timings[day][2] for day in range(1, 25)), label="Part 2", width=0.4)
|
||||
|
||||
plt.ylabel('Runtime (s)')
|
||||
plt.xlabel('Day')
|
||||
|
||||
plt.xlim(0, 26)
|
||||
plt.xticks(np.arange(1, 26))
|
||||
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
|
||||
plt.savefig('individual-time.svg')
|
||||
|
||||
|
||||
def main():
|
||||
timings = read_timings()
|
||||
plot_cumulative_time(timings)
|
||||
plot_individual_times(timings)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
1
2021/cumulative-time.svg
Normal file
1
2021/cumulative-time.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 16 KiB |
1
2021/individual-time.svg
Normal file
1
2021/individual-time.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 32 KiB |
102
2021/inputs/20.txt
Normal file
102
2021/inputs/20.txt
Normal file
@@ -0,0 +1,102 @@
|
||||
#####..#.#######.##.#.#.#.#####..######...#.##.###...#.##..#####..###.#.####..#.##.#....#...##.###..#.#......####.#...#.####.#..#.###.#.#.#.###.###..########.##.#.#....#.#####.......###.#..#.#.###.###.###.#.......#.#....#.##.###.....##...#.#.#..#.#....##..#####...##...#.##..##.##.#...###...#.##...#...#.####.###...........#...#..##...##.###.##.###.....#.##...###.....#.#.###..##..#..##..#.....##..##....#....####...#.###.#######.#.##.####.....####.#.#.##.#####...#.##.##.#.##..####.#.#.######.#..###..#.##.##...
|
||||
|
||||
##.##....#..#....#.....#..##.#...######.##.##..#..##.###.##..##.#..#..####..##..#.#..###..##...##.##
|
||||
..##.###.##..##.###..#.###....##.#.#...##.#.#..####.#..#..##...##......###...###.#..##...##.##.##..#
|
||||
.#..####..##..###..#.....#....##....###..####.##.##.#.#.##..######..#####.#...##.#..##..##..##...##.
|
||||
..###.......##.#..#.##.##.#..#######..##.......###.###.###.#..###...#.#####..###....###.##..###..##.
|
||||
.#..####..###.#.#..#.#..##...#...#.##...##..##..##.#######.....#.#..#.#.#.#.#.#..#.##......####..##.
|
||||
##..#...###.##....####.###.###.#.#.#........##...#.#....#######.######...##.###...##.###.##.######..
|
||||
##..##...#....#....#####.#.....#....#.#..#.#.##...##.##...#.####...#####.#.#.##...#..##.##.##.##..##
|
||||
..#..##..#..#...####....#.....###....##.#..#...#..#.##.#....#.#.#...##.#..#..#..##....#.##..#..##.##
|
||||
..##....######.###.#.....##.##....###...#..#.....#...###.###....#...#.##.####..##.###....#####...##.
|
||||
.#..##.###.#......#.#####.####..####......###.....####..####..####..#.######.####..##.#...#.##.####.
|
||||
####..##.##.##..#.#...##.####..####.#...#.#.##..#.###.#.....#....###.####.###..#.#..#.#...#.#.##..##
|
||||
.##..#....###..#####.##.....###.##.###.######.#.###.#.##.#.#######....##..#.#.##..#.##...#######..##
|
||||
###.......###.....#.#.##....##..#.##...#....####.##.###.....#.####..#........#...####.##.#.##...##.#
|
||||
##.##....##..#####.#...####.....##..#..#...##.#...##.#..#..########...###.##...#.##...##.#..##.##...
|
||||
.#.###...#.###..##...####..#.###.##.#.#...#..###.#.####..#..##.##.####.###...##.##.###..#.#.####.##.
|
||||
#..#.#.#.#.#.#.#..#####.#....####.#.......#..#####..##..#..###....#...#..###.#..###.##..#.###.##.###
|
||||
....##..##.###..####.#.###.##.....#...#...##.##.#.###..##.#.#..#....#.####.##...#.#...#.#...###...#.
|
||||
##...#....##.#....###....#..##.##.####.#.#.##..##.####...#.#....####..#.##.....#....#...#..##...#...
|
||||
#.##...#.##..#.##.###..##...##.#.#..##..#.....###.#.####....#######.#.#.#####.#....##.#.....####....
|
||||
.....#####..###...#.#.#.#...#.#..#.###..##.##....##.###..###..###.#.#...#.#.##.###...#...##.#..#.##.
|
||||
...###.###.###.#..#.#.####.##...##.##..#####.......#.##.....#####..#.#######...#..#.###......#######
|
||||
#..##.....###..#.###..#..###.#.##...#...#......#.###..#...###...#..##......#.....##.####..##...#...#
|
||||
.....##..#.#.#..#.#.#.#####...#..#.......#..#..#....#..##..##.#.#..#.####..#...#..##...##...#..#####
|
||||
...##..#.#...#...#.####..#.##.###..##..###.......#..######.#.###.#..#.##.###.....########..#..#...#.
|
||||
#.#...##...#.##.##.#..#..#.#....##.#.#...#.#..####.#...#.#..######.#.##....#.#...##....#..#.#.##.###
|
||||
...#####.##.####.##...#..##.#..##...#..##..#.##...##..#.#.###......#.###.#.#..###...##..##.##..###..
|
||||
.##...###..#....#.#.....#..#.##..###.#..###..###.#..#.#.###..#...#..####..#.###.##.##.#.#.#..#..#..#
|
||||
.#..#.#.#..#####.##...#.#...###.####.##..###....######.##..##.#...#.###..###.###....##.#......#.##.#
|
||||
#..####.######....###..####.##.##.....#.##.####.##..##.#..##.#.#.#.##.##..#.###.##..####.##.#.##..##
|
||||
....#.#..........#.##....#.#..#.###.##.####.#.#..##.#..##.#..#.....###.#..###.######..##.#......####
|
||||
...#..#.##.###########...###.###..##......#..###.#.#...##.##...####.##..#.........##...##.###.###.#.
|
||||
.##.#####.#...#.###.#..#..#.#..#.##...#.#..##.#.####.##..######....##.####...#..###.####.#...##.#...
|
||||
...#.##..#..#.#..##..#.#..##.....#.##.#....#..#..#.#......##.####...####...##......##..##....####.#.
|
||||
####.##.#...#....#.#.#..###.##.###..#.###.#.#..#.##.##..##.##.#.#..#.####...###.####.##.....#.#...##
|
||||
#........#.###..#.#.#####...#.##.#.###...#..#...##.##..#.###....#.###..#.#.#.###.#.##.#....#......##
|
||||
...#.##..##.#..........#..#....###.#..#..#.#...###.##..#.#...###.####...####..#.####.######.#....#..
|
||||
##.#.####.##.#.##..#..##...###...###.##..##.#####..###..#..#.#..#.##...#.####...##.##..#.#.#..###...
|
||||
#.####..##..#.#..##..##.#..#..#...#.###.#.##.####.###.###...##.#####..##..####...##.##########.#.###
|
||||
####.##..###.####.#.######...#..#.##.#.....##.#....#...#.############..#.#.###.####.#.#..#.###....#.
|
||||
..###..#...##.#.##.##..######.###.###..#..#####....#.#....####.#..#.......##..#####.#...#.#.##....#.
|
||||
.#.##...#..#.##.####......#.#......######.#.#.##.#..##..#....##..##....#.##.###..#.##..#.#.....##...
|
||||
###..###.########..####.###.#...###.........##....##.##..#...#.##..##..#.#.####....######..#..#...##
|
||||
##.#..###..#.#..#...##.####.#..##..##...###.##.#......#........###...#.###..####..####..#####..###..
|
||||
#.##...##..##..#.#.###..###...###.....#.#.######.....##.....#.##..##.#...###.###.#.#..#.##.##.##.#..
|
||||
#..#.#####..#..#...#.#...#..##.#..#.###...#..###.###.#.#...#.###..#.###..#..##.##......##...#...###.
|
||||
#....#.##.....#.#...###....#..#.#.#..##.##..###.###..#..#.#..##.....###.#.#.#...#.##.#..##....####..
|
||||
#..#####...#...#####.###.#..#..#...####.##.#.#..#...#.####...##.##.....#.#.##.##.##.#....#.######..#
|
||||
###...##..##.##.##.#..##.##.#.##.##.#..#.#####..#.#..#.#..####....#.###..###...####.#....#...#.###.#
|
||||
##...####...##.######...#...#..##..###..###..#.##.#.#.#...##.#.###...#...########..#.#######...###..
|
||||
.###...#.#.####.#.#...##.#.###.#.###.#####.###..##.#..###..#.#...##...#####..##....#..#..##.#.#....#
|
||||
...#..#....#..#....#.#.##..#..#####....#..#.#..####..####.####.###......###..#..#..###.##.###...###.
|
||||
#.#...#.###.###....#..###..###...#..#####..#.##........###....###.###.##.###.#..##..#.....#.#.####.#
|
||||
#...#.#...#.#..#..#.##.##.#......#.#.#..###....#.#.#.#..#.#.###..#..#..##.#.#.#.##...#..###.####..#.
|
||||
#.#.##.####........#.##..#.#.#...##..#.#####.#..#.#..#.##.#..####.###.#####.#.##.#....##..#####.####
|
||||
#######.##..#.#..#...#..#..#.######..##.#.###.#...#..####..##.#.##.###.#.##.#.##..#...#.#..#.#.####.
|
||||
.##..#####.##.####.##.#....##.....###.......#.####.###....#...#.#####.###.#..#...##.#..##.#....###.#
|
||||
..####.#.#.....#...###.#...#.#...#.####..##..#..######......#...#.##.####..#.......#.##.......#.###.
|
||||
.##..#.#####..##..##.#..####.##.##.#.###.#.#.....#.....#.#...####....##.##...####......##.##.#######
|
||||
#.#.#..###..###..##.#..##...###..###..#..#.###.#..##.##...##..#..####....####.##.#.###...#..##.#.##.
|
||||
##.##.....######.#..##.#.#.###.##.###.##....######.##.#.##..#..##...#...#..#.#.#.######..#.###.##..#
|
||||
#..#.#.###.#.#.#.....###.######..##.##.#.#...#####.#...##.##.##.##....##....#..#.##.#.##..##...#...#
|
||||
..#.....#....#...#######..#.#.#.#.###.##.#.##.###..#..##..###..#.#####..###.......####.#..####..#...
|
||||
#..#.#...##.##..#.#.....###.##.#.#....###....#.##..#....#####.##.#####..###...####.#.#.#.###.#....##
|
||||
#....##..#..##..#.####..##.##....####..##..#..####.######.##..#.###.#.##....###.#....##....##.#.##.#
|
||||
.#.#.#.##.##...###.#.#...#...#..######.##.#.#.##.####.....#.#..#.######.......##.#####..#....#####.#
|
||||
.###.#.##...###.....##..#.#..##....#.###..##.##..####..##.#.###..##.#.#...##.#####.#.....#..#..#####
|
||||
#.#.###..#....####....#...#.###.#..#...###..###......##..##.#.#..#....#......###...##..#.##.##...#.#
|
||||
###.####.##.#.##.......##.....#.#.###......##..#.#....###..#.#.##.###.##.##.##.#..#.####.#......###.
|
||||
####...#...##...#.#.#..######.#####..##...#.##.##.####.##.#.##..#..#.#.##.#...#......#.##.#######...
|
||||
.##...#....#.##.#...#..#..#.####..#.#..........#.#.##......#.##.######.###.#####.#.#####.###.####...
|
||||
.##.##.##.###..###..##.#..#.###..#####.#..##.##.#.####....###.#..###...##..##..#.##..#...#..###.##.#
|
||||
#.....##..#...##.#...#.###.##..#.....##..#.##...#.##...#.#.##.#...#.#..###...#...#######...#.#.....#
|
||||
.######..#.####.#.##.##.#.#.#.#.###.#######...#..####.#.#..#####..#.....###.##...#.###.####.#.#.....
|
||||
#.####..##...####.##.#.##...####..##.#.#..####.##.#.###.##..##.##..###.##...##........###..#.#.##...
|
||||
#...#.##.....###.##.....####.####.##.##.##....##.#.#.#.##...#.#.##..#..##.....##.#...##..##...##..##
|
||||
#..#.###.#....#.##...##...#.#......##.###...#......##..#..##...##.#..###.#..#.#.#.##.........##.#.##
|
||||
.#.#..#..#.#..##...#.#...#..###.#...#.#.##.##....#.##.#...#.##.#..#.#..##..#.##...#.#.#..###.#.###..
|
||||
###...#.#..##.###...#..##.#..##.#.######..####..#.#.....##....##.####.###...#.#...#.#..#..#.###....#
|
||||
.####.###..##.##...#.....##.###.#..##..####.....#....##.....#....##..##...##....#..#..###.#...###.##
|
||||
..###..###.#.#....#.##........#...####...####...#.####.##.###.##...#.####.#.###..###.##...##...#.#.#
|
||||
###.#..#.#...#.#.#.....##.###...#..###.#....#.##.##.###..#######.###.#...###.####...#.#.###.#...####
|
||||
#.#....####..#.#.###..###.###.#.#.##...###.#..###.#.#.#...###..#...##...#..#..###..##.#..#.##...###.
|
||||
.###..##.#..#.#.#####.#..#.........##..##...#...#.#...##..#.##...###..#.#.#..####....#.####.##.#....
|
||||
##.....#######....#.###.##...##.##.#####.#....#########.##....##.###...#.###..##.###.#..##..#....#.#
|
||||
...#.##.#.......#.#....#..##..#..##...#.#.####...###.##..##...##.#.##.#.###.###.###..####..#######.#
|
||||
.#.###...##.##.#.......#.#...#..#####...##...#...#.#####.##.#......#.##...#.###.#.#..#.#..##..##.#.#
|
||||
...##...##.#.#...#...#.###..###....#.##...##.....#...##..##....#..##..#.#..#.#.#.........##.#####..#
|
||||
........#...#.......#.#..#..#......##..##...##......#.....#.#.......#.#####.#.#.#..#...#####.#..####
|
||||
#.#.###...###....#...######...#.#.#####.##..#..##.##..#..#..#..##...###..#.#.#..##...#.#.#.#.####..#
|
||||
.#..#...##...#....#.#.##.#.#....##.#....#...#.#.##.....#########.#....#.##..#..#.#.##..#.#..###....#
|
||||
##..#.#.#..###.....###.#..#.##..##....###.#..####.#.#.#..######..###..#.#.#...#...#...#.#..#.#..###.
|
||||
.#.##.#.####....#..#.#...#.##......#..#.....#...#....#.##########..#...#.#.###...####..###......##.#
|
||||
###...#....###.#.#..#...#..####.#...#.##..#.##.#...###.#.#..#.###.###...#......#..#.##.#..#####...##
|
||||
.###.##.#..###...#..####.###...#.##..##....######.#..##...#...#.##.....#.####.########.##....#.##.##
|
||||
.......######.#...#...#.###....##..#.###.#...##.##..###.#..##...#..########.#.#.#...#..#..##.##..#.#
|
||||
..###.##..#..#####.#.##.#..#...##..#.#..###.###....###...#..##......###..#....#.#.....#...#..##.#..#
|
||||
###..##..#.#....#####.#######..#..##...#..#...#.#........#...###.#.###..##.####..#.####.#..#..#...#.
|
||||
...#..###.#.#.#.###...#.......####..###.#.##.####.#..#.#..#########.#.....#...##..#.#.#..#.#.#.#...#
|
||||
####.#..##.##..#..###.######.#.#.###...#####.#.###.#####.#.#.#.#...#.#.#...#.#########.#..###.##.###
|
||||
.##...#.#.###....##..##..#.#.#.#.#..#..##.###...####..#..#.#.#.#####..##.#.#.##.##...#.....#...###.#
|
||||
2
2021/inputs/21.txt
Normal file
2
2021/inputs/21.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Player 1 starting position: 9
|
||||
Player 2 starting position: 4
|
||||
420
2021/inputs/22.txt
Normal file
420
2021/inputs/22.txt
Normal file
@@ -0,0 +1,420 @@
|
||||
on x=-33..18,y=-35..11,z=-49..2
|
||||
on x=-14..32,y=5..49,z=-42..5
|
||||
on x=-28..18,y=-38..10,z=-14..33
|
||||
on x=-40..6,y=-22..32,z=-32..13
|
||||
on x=-14..37,y=-37..12,z=-31..19
|
||||
on x=-24..30,y=-40..6,z=-19..27
|
||||
on x=-29..15,y=-44..7,z=-22..22
|
||||
on x=-49..2,y=-29..15,z=-1..48
|
||||
on x=-1..45,y=-6..39,z=-16..37
|
||||
on x=-15..30,y=-35..14,z=4..49
|
||||
off x=20..39,y=29..46,z=-30..-15
|
||||
on x=-36..9,y=-8..38,z=-38..10
|
||||
off x=-22..-4,y=10..19,z=-4..10
|
||||
on x=-43..9,y=-37..16,z=-24..23
|
||||
off x=10..29,y=1..10,z=-2..16
|
||||
on x=-18..34,y=-39..8,z=-31..23
|
||||
off x=-2..7,y=-41..-23,z=4..23
|
||||
on x=-18..31,y=-27..27,z=-23..25
|
||||
off x=17..33,y=5..14,z=-26..-7
|
||||
on x=-29..25,y=-1..44,z=-5..44
|
||||
on x=-2089..22263,y=63383..83317,z=1521..34560
|
||||
on x=16324..26707,y=-76181..-51644,z=27623..60727
|
||||
on x=-95252..-74929,y=-36262..-8635,z=-14014..-4726
|
||||
on x=26087..56689,y=13866..33100,z=-77678..-54222
|
||||
on x=-58261..-34558,y=-52429..-39076,z=-46433..-17880
|
||||
on x=38567..59604,y=66243..73633,z=-4724..7559
|
||||
on x=-76223..-52004,y=-4022..17420,z=-56813..-31010
|
||||
on x=-28531..-6777,y=52497..78911,z=39320..53754
|
||||
on x=-1705..20943,y=71494..92397,z=2586..17205
|
||||
on x=43970..50168,y=-44993..-18711,z=-68417..-46597
|
||||
on x=-2878..23564,y=41697..70518,z=42674..68678
|
||||
on x=22987..51001,y=-74194..-62557,z=-40942..-24407
|
||||
on x=10735..33969,y=26636..35170,z=62555..84961
|
||||
on x=-87260..-58460,y=-25011..9170,z=-40488..-16433
|
||||
on x=-41317..-19098,y=55028..74495,z=9284..32979
|
||||
on x=57730..86394,y=-5618..4073,z=8825..29287
|
||||
on x=70498..95095,y=-26060..-15204,z=-11673..3577
|
||||
on x=-12181..6283,y=-76734..-56136,z=-41358..-26351
|
||||
on x=55479..68566,y=-65998..-51191,z=-388..13824
|
||||
on x=-7142..9719,y=17804..41523,z=-73454..-51015
|
||||
on x=-6780..13903,y=64955..76512,z=-35477..-12220
|
||||
on x=8140..17232,y=-84619..-62523,z=-28417..-860
|
||||
on x=-59883..-49433,y=-65970..-42610,z=8348..17483
|
||||
on x=-46361..-34652,y=-77141..-58593,z=-32375..2092
|
||||
on x=18682..23347,y=-70715..-62353,z=15488..48836
|
||||
on x=13625..33572,y=-53090..-39232,z=38313..62732
|
||||
on x=-7845..8128,y=72275..83684,z=9204..44598
|
||||
on x=30099..52396,y=-37319..-13384,z=-65551..-51334
|
||||
on x=66812..86665,y=-12147..-8315,z=-14456..18299
|
||||
on x=-80768..-62714,y=12166..32801,z=9298..28465
|
||||
on x=32917..51529,y=-39942..-11579,z=-77830..-58654
|
||||
on x=6795..30180,y=-52748..-23421,z=-79235..-66193
|
||||
on x=41104..59365,y=-65904..-44389,z=-58998..-32127
|
||||
on x=46835..68448,y=-13278..-4034,z=47409..74764
|
||||
on x=61812..89996,y=-11979..17125,z=-42861..-30521
|
||||
on x=36211..58568,y=65204..73638,z=-2374..22331
|
||||
on x=24752..29245,y=68946..77065,z=21993..33524
|
||||
on x=64234..90251,y=15294..35642,z=26838..33725
|
||||
on x=-19948..6112,y=-38109..-27877,z=62697..87704
|
||||
on x=-45769..-27330,y=-76264..-42424,z=34120..46556
|
||||
on x=-64655..-37560,y=32027..51779,z=36246..55408
|
||||
on x=46729..77810,y=30499..52592,z=22011..48493
|
||||
on x=-59194..-47087,y=61036..63539,z=-9127..12439
|
||||
on x=31894..45260,y=56306..80190,z=-39056..-4346
|
||||
on x=-28505..-11114,y=76279..91855,z=-17517..2342
|
||||
on x=-29827..357,y=-55982..-33070,z=53295..78681
|
||||
on x=61904..90365,y=-45148..-26196,z=-31689..-11315
|
||||
on x=-63745..-30029,y=-60515..-23200,z=-53318..-41274
|
||||
on x=35857..48971,y=-18159..16867,z=-83848..-48218
|
||||
on x=-58426..-37407,y=47038..72640,z=2498..22588
|
||||
on x=40878..41799,y=-86884..-48581,z=2168..20716
|
||||
on x=-26137..-535,y=60867..81985,z=-60883..-30553
|
||||
on x=-49390..-18873,y=19679..41934,z=64209..74274
|
||||
on x=-13205..4850,y=-54788..-33129,z=-74136..-52452
|
||||
on x=34452..69258,y=-18117..-14331,z=53496..73956
|
||||
on x=-26084..-6353,y=-28975..-2494,z=57753..84222
|
||||
on x=-55087..-32324,y=-62117..-47889,z=-36986..-26405
|
||||
on x=-49256..-42251,y=-58341..-32455,z=35370..57488
|
||||
on x=-29709..1208,y=44395..60836,z=44943..75568
|
||||
on x=9674..39186,y=-85531..-68265,z=11474..22020
|
||||
on x=-54733..-30617,y=-57541..-41688,z=44653..71542
|
||||
on x=58013..78420,y=-31202..-19242,z=18818..28322
|
||||
on x=-68634..-53973,y=-58009..-31614,z=-5131..5865
|
||||
on x=-16576..3952,y=63366..90574,z=8992..37515
|
||||
on x=-7386..14817,y=-14155..5703,z=66136..88553
|
||||
on x=19106..54924,y=-12140..15434,z=68415..80932
|
||||
on x=7336..31425,y=65432..82588,z=8047..29593
|
||||
on x=22525..33599,y=-68372..-39358,z=-68143..-43500
|
||||
on x=5213..21274,y=-39249..-27045,z=-91831..-72038
|
||||
on x=-31642..-16632,y=-2869..8672,z=66852..81506
|
||||
on x=70305..84886,y=-41625..-15439,z=-29089..-2340
|
||||
on x=-60096..-54846,y=-46888..-14091,z=-57849..-36369
|
||||
on x=-44911..-23725,y=-22548..198,z=55411..76767
|
||||
on x=-57512..-33022,y=-64054..-54691,z=22591..39559
|
||||
on x=535..39401,y=56745..78405,z=23560..28326
|
||||
on x=-56374..-39060,y=-77520..-41804,z=-7273..13316
|
||||
on x=7013..28554,y=32070..54196,z=47529..70955
|
||||
on x=-76288..-56876,y=-56665..-25593,z=-16778..-6302
|
||||
on x=-37510..-11747,y=61094..74622,z=-2370..18659
|
||||
on x=-58709..-30616,y=-33464..-11638,z=50961..72748
|
||||
on x=-55454..-27679,y=-82741..-59621,z=-9194..15631
|
||||
on x=13172..40388,y=11138..40063,z=-82760..-65315
|
||||
on x=14388..27772,y=-67554..-46788,z=-70583..-43179
|
||||
on x=15748..48411,y=-58853..-46690,z=45719..67485
|
||||
on x=-64826..-42121,y=-69677..-41462,z=-19124..10506
|
||||
on x=-38968..-4505,y=21318..56103,z=53808..76243
|
||||
on x=52992..73842,y=-45007..-30798,z=-40845..-17070
|
||||
on x=-72448..-52368,y=-13003..12727,z=-51653..-39744
|
||||
on x=-89717..-56812,y=-11429..11004,z=-33713..-29320
|
||||
on x=-82797..-68105,y=-907..18442,z=-48479..-36446
|
||||
on x=-52400..-36160,y=-2729..11358,z=-73134..-48314
|
||||
on x=-25713..-1239,y=45923..57024,z=-64104..-48955
|
||||
on x=-24274..3585,y=-91301..-60004,z=-36996..-8396
|
||||
on x=-72952..-55266,y=-33277..-2819,z=-34959..-11204
|
||||
on x=-66793..-46197,y=50987..54931,z=-27353..-16284
|
||||
on x=43392..52101,y=-14627..12623,z=-71060..-48522
|
||||
on x=-77723..-72809,y=6362..11492,z=9252..30717
|
||||
on x=32463..54093,y=18767..32223,z=-79630..-54627
|
||||
on x=26726..36372,y=-18434..723,z=54237..77721
|
||||
on x=62209..80598,y=-43071..-26185,z=11647..20283
|
||||
on x=-12408..8805,y=-82322..-75005,z=-7927..12271
|
||||
on x=66471..72381,y=-1981..28059,z=27987..48109
|
||||
on x=-80370..-49201,y=-61716..-49683,z=-30867..-7453
|
||||
on x=37596..66737,y=-68892..-60777,z=-33858..-8114
|
||||
on x=17321..30730,y=-52278..-42302,z=54029..68729
|
||||
on x=-77142..-71446,y=7200..27046,z=-14711..12602
|
||||
on x=-22544..-1958,y=-33075..-2255,z=-86145..-70682
|
||||
on x=55145..79591,y=-11592..16417,z=-30690..-11963
|
||||
on x=-13258..8815,y=64606..98004,z=-8762..6548
|
||||
on x=11099..20143,y=57055..77284,z=-23767..-18751
|
||||
on x=52489..83696,y=15746..31820,z=8280..43534
|
||||
on x=-66484..-41050,y=-57811..-31218,z=24204..41390
|
||||
on x=60564..85343,y=-27885..-15572,z=-28159..7052
|
||||
on x=-317..14600,y=68181..76576,z=-39440..-13155
|
||||
on x=-75121..-51737,y=-40321..-29860,z=15647..37621
|
||||
on x=-54204..-41260,y=5051..35207,z=53197..81544
|
||||
on x=36998..51680,y=51159..76975,z=5399..12759
|
||||
on x=-16863..16337,y=-80953..-58351,z=-59967..-35458
|
||||
on x=31744..60271,y=-14750..10965,z=49476..82924
|
||||
on x=-2256..18179,y=-73825..-67358,z=-34072..-25314
|
||||
on x=17732..43807,y=62479..77780,z=13938..28034
|
||||
on x=1622..28357,y=-82169..-57048,z=-25837..88
|
||||
on x=-40461..-9223,y=62104..86603,z=14710..22383
|
||||
on x=-81227..-61564,y=-42653..-23629,z=29983..44317
|
||||
on x=20880..48206,y=41863..67134,z=32598..46063
|
||||
on x=-96416..-62247,y=-18355..6029,z=-5981..7217
|
||||
on x=-57869..-30585,y=56288..73456,z=16646..22837
|
||||
on x=75450..92466,y=-20645..12847,z=-25402..-14103
|
||||
on x=-5465..14054,y=-35719..-4050,z=71849..89372
|
||||
on x=-61081..-25279,y=-66905..-48434,z=23859..40935
|
||||
on x=-7800..10807,y=71020..85725,z=-15915..7901
|
||||
on x=53985..76201,y=20582..53668,z=-1323..23345
|
||||
on x=-85787..-63425,y=27676..42137,z=-9285..-3133
|
||||
on x=48336..68487,y=-38490..98,z=41624..59831
|
||||
on x=-78012..-53039,y=30299..67166,z=19090..40584
|
||||
on x=5113..13878,y=-78897..-73837,z=11134..18475
|
||||
on x=41756..68743,y=-155..35498,z=50442..64705
|
||||
on x=-81270..-68840,y=-17576..-3690,z=-32135..-14787
|
||||
on x=8219..40862,y=8918..25218,z=-77252..-54208
|
||||
on x=39105..44578,y=66714..83921,z=15354..22292
|
||||
on x=46189..61321,y=43841..68088,z=19301..53413
|
||||
on x=-62770..-57542,y=-20733..14047,z=-67275..-32150
|
||||
on x=65480..84873,y=3073..19647,z=6345..23441
|
||||
on x=46867..47491,y=46506..52780,z=26672..40094
|
||||
on x=17013..41829,y=-11136..13219,z=-82179..-70797
|
||||
on x=-34036..-23731,y=33357..53053,z=51260..72738
|
||||
on x=31113..47177,y=-66933..-39151,z=-61354..-38916
|
||||
on x=34145..51166,y=-3683..10926,z=52987..77874
|
||||
on x=41954..65645,y=-56607..-45672,z=-4255..10356
|
||||
on x=-68089..-55495,y=46167..65284,z=-2384..10704
|
||||
on x=7890..33438,y=37201..73446,z=-61118..-42873
|
||||
on x=-7504..12073,y=-76259..-56952,z=29469..62400
|
||||
on x=13684..21664,y=-31197..-1820,z=68848..89615
|
||||
on x=-85435..-60015,y=-25411..-2834,z=-13167..8182
|
||||
on x=-76535..-58434,y=-29534..475,z=-33953..-16134
|
||||
on x=-59255..-45581,y=42904..53487,z=-44277..-36999
|
||||
on x=24422..52934,y=-69287..-47156,z=27348..40808
|
||||
on x=-77855..-49832,y=-40133..-15312,z=-44484..-35346
|
||||
on x=-41154..-18246,y=4608..24334,z=73408..80625
|
||||
on x=-49987..-14202,y=25483..46341,z=-72668..-53755
|
||||
on x=13538..18051,y=23397..42374,z=64790..80510
|
||||
on x=54955..79143,y=-54794..-41945,z=10831..26883
|
||||
on x=-18711..-1344,y=-66328..-31191,z=59213..66700
|
||||
on x=-42306..-25865,y=-84072..-59112,z=-10635..13499
|
||||
on x=-78607..-56882,y=28422..42754,z=-42069..-4658
|
||||
on x=70330..93330,y=3485..16587,z=-2226..11978
|
||||
on x=42999..75014,y=-73237..-35809,z=-16684..5008
|
||||
on x=14380..47360,y=-7768..2171,z=-75135..-69101
|
||||
on x=56578..76847,y=-38598..-29395,z=-32815..-15926
|
||||
on x=-12748..8540,y=15488..35223,z=54552..86464
|
||||
on x=3158..16552,y=-24454..1647,z=-80496..-74467
|
||||
on x=56473..73209,y=-3433..12083,z=-54506..-38799
|
||||
on x=51012..77530,y=30088..48866,z=8772..24396
|
||||
on x=17665..25364,y=39750..62592,z=46640..74482
|
||||
on x=-28714..-6773,y=9347..31266,z=73840..78208
|
||||
on x=8925..38027,y=59998..85715,z=-24137..-10466
|
||||
on x=53001..66549,y=-4287..21472,z=-73164..-44211
|
||||
on x=-54149..-45881,y=-28052..-10796,z=49458..62599
|
||||
on x=-21963..6658,y=66148..91598,z=-21298..6962
|
||||
on x=-11782..161,y=-91012..-60861,z=21515..30530
|
||||
on x=-76804..-69730,y=13746..32487,z=-23642..-13658
|
||||
on x=963..15271,y=-71045..-39328,z=-71381..-47851
|
||||
on x=67896..74688,y=-32914..-22017,z=12647..33400
|
||||
on x=12634..39919,y=-66590..-50495,z=50004..68679
|
||||
on x=8442..27410,y=9042..25167,z=68135..95195
|
||||
on x=-25776..-14278,y=-29280..-10089,z=69100..90070
|
||||
on x=64423..65336,y=3388..18317,z=-63336..-39916
|
||||
on x=35919..66955,y=14633..25424,z=55317..61335
|
||||
on x=-73286..-65915,y=-44128..-28250,z=22971..40421
|
||||
on x=15859..26558,y=-56047..-29767,z=42976..66388
|
||||
on x=-6917..5955,y=65260..87252,z=-24846..4318
|
||||
on x=-65972..-29473,y=32115..66783,z=35787..53459
|
||||
on x=-67248..-44667,y=33707..64039,z=-31788..-18880
|
||||
on x=45484..66247,y=38595..43467,z=4589..29393
|
||||
on x=13889..18349,y=66828..91044,z=14198..32527
|
||||
on x=54724..85550,y=-30589..-5424,z=35166..56213
|
||||
on x=-42965..-21638,y=-60889..-33965,z=43998..65167
|
||||
on x=-35930..-32769,y=-78331..-56047,z=-14735..9050
|
||||
on x=-24860..-8877,y=-80975..-43953,z=44660..63576
|
||||
on x=-14165..8370,y=-22173..-12379,z=57378..77093
|
||||
on x=71416..77554,y=-27428..6152,z=-49013..-27924
|
||||
on x=-93105..-68413,y=-35230..-13620,z=-20316..293
|
||||
on x=18417..29118,y=-86664..-54984,z=-36954..-22621
|
||||
on x=55918..67650,y=-41116..-22359,z=-41830..-26146
|
||||
off x=46522..78165,y=-65457..-45507,z=6815..36492
|
||||
off x=47885..74001,y=-31398..-10975,z=28012..47043
|
||||
on x=-91510..-71175,y=-16528..11618,z=-12499..8654
|
||||
off x=-84874..-61512,y=8619..38028,z=-54298..-34830
|
||||
on x=-83118..-51007,y=-45381..-31920,z=-23725..3021
|
||||
on x=10327..15960,y=-81856..-71010,z=-33630..-17410
|
||||
on x=23031..50754,y=-44713..-23633,z=-63299..-46320
|
||||
on x=-46257..-28480,y=-49238..-30841,z=47755..73142
|
||||
off x=20153..42123,y=-1222..5657,z=-77756..-63549
|
||||
off x=-61474..-57812,y=21117..35860,z=35705..60812
|
||||
off x=-79310..-66078,y=30244..44852,z=-9818..11212
|
||||
on x=71346..88869,y=-31928..-3884,z=-24256..-2336
|
||||
on x=-14150..11801,y=-57201..-51842,z=40079..61755
|
||||
on x=-40978..-28089,y=-42914..-23485,z=55939..67185
|
||||
off x=-23863..-13907,y=-536..10465,z=-90190..-61663
|
||||
on x=-5454..24659,y=-79999..-64557,z=27835..52330
|
||||
on x=72970..84571,y=10891..31328,z=-6227..5365
|
||||
off x=-29582..-11617,y=15192..35976,z=-79544..-70922
|
||||
off x=31030..48464,y=53376..61684,z=23041..44016
|
||||
off x=-10069..14806,y=35482..66322,z=-63854..-56881
|
||||
on x=53051..84557,y=-15724..16551,z=42287..54722
|
||||
on x=14308..26815,y=-13886..-3319,z=-79479..-57838
|
||||
off x=-59590..-50887,y=24924..38221,z=-57585..-33212
|
||||
on x=-63473..-31750,y=-64527..-52962,z=3041..21881
|
||||
off x=-31812..-7489,y=-22611..5463,z=-94027..-61918
|
||||
off x=-82927..-54190,y=-9326..-491,z=20413..40734
|
||||
on x=17422..42553,y=8312..32307,z=-71649..-69485
|
||||
off x=-78294..-58360,y=35412..45701,z=11726..40925
|
||||
on x=-21097..-3642,y=-8835..14381,z=-99475..-68222
|
||||
off x=-84402..-69432,y=-14573..10548,z=14300..22158
|
||||
on x=48734..68681,y=-34310..-26273,z=-52329..-23613
|
||||
off x=-35075..-15047,y=-46105..-25811,z=63394..85781
|
||||
on x=-86314..-54848,y=-46805..-24845,z=3445..37489
|
||||
on x=-63351..-50251,y=1886..23129,z=49969..56775
|
||||
off x=9515..27274,y=50806..72697,z=-49477..-25800
|
||||
on x=-35588..-13052,y=15904..42770,z=-81932..-66144
|
||||
off x=-46532..-36208,y=52000..73477,z=1265..25986
|
||||
off x=-87317..-63208,y=-17777..9520,z=-23859..-3922
|
||||
on x=-6728..4683,y=-95124..-75630,z=-29826..-12203
|
||||
on x=18636..43049,y=-80651..-64046,z=-24566..10269
|
||||
on x=34590..45757,y=-60461..-41469,z=-61769..-39386
|
||||
off x=69352..98422,y=4474..7247,z=-13318..-2831
|
||||
off x=-8443..8104,y=-47359..-17553,z=61091..78345
|
||||
on x=36926..56794,y=-55435..-27634,z=31804..55162
|
||||
on x=-43184..-19362,y=-73702..-61346,z=-50469..-12904
|
||||
off x=-12667..10577,y=9915..24867,z=-88319..-68574
|
||||
off x=-41812..-19280,y=-50846..-20974,z=-73207..-56898
|
||||
on x=25317..48114,y=45115..64793,z=-34388..-8697
|
||||
on x=-7572..26486,y=45477..70127,z=50627..71118
|
||||
on x=-65568..-53227,y=46928..71092,z=-13475..-291
|
||||
off x=-79123..-55369,y=-24021..-16788,z=17459..45068
|
||||
on x=26906..52136,y=17854..35117,z=-79712..-60188
|
||||
off x=73240..87023,y=-12287..13613,z=10048..23682
|
||||
off x=-2039..1086,y=20152..33227,z=72963..88128
|
||||
off x=-16444..-292,y=35253..51124,z=49972..79032
|
||||
off x=-31142..73,y=52811..81568,z=35320..52590
|
||||
off x=-45280..-38826,y=32419..56574,z=34445..72131
|
||||
off x=-76025..-59111,y=14..8694,z=-60123..-35050
|
||||
off x=-15911..3734,y=-23253..-9645,z=-88648..-77200
|
||||
off x=47880..75437,y=28421..53226,z=33581..53756
|
||||
off x=16705..55995,y=-22513..-5765,z=-79544..-52799
|
||||
off x=43351..73267,y=-30268..-23880,z=-69607..-39884
|
||||
on x=-49229..-24544,y=40180..60627,z=49877..77312
|
||||
on x=-67421..-46871,y=30102..60244,z=16607..38923
|
||||
on x=52711..81149,y=-10627..-8351,z=-48619..-22583
|
||||
on x=29102..45238,y=-70802..-50027,z=16042..39140
|
||||
off x=-87363..-61250,y=-1811..4566,z=-48295..-31466
|
||||
off x=52765..72819,y=-38051..-27751,z=22516..53729
|
||||
off x=-95898..-76590,y=-4285..-1522,z=-7096..27186
|
||||
off x=39546..65197,y=59713..74511,z=-14000..15914
|
||||
on x=27920..58905,y=-11677..424,z=-79346..-62053
|
||||
on x=-28804..-11775,y=72541..86610,z=-12598..7458
|
||||
on x=11013..13476,y=62070..76490,z=-39383..-17081
|
||||
off x=39439..48894,y=-72648..-38252,z=-48344..-12634
|
||||
on x=-70559..-52651,y=27489..46016,z=9134..42011
|
||||
on x=-20036..2910,y=-22525..-6028,z=-87710..-68411
|
||||
on x=-57816..-32833,y=51432..68426,z=-20978..2045
|
||||
off x=-79019..-59736,y=15304..30243,z=-45210..-32477
|
||||
off x=-90119..-75160,y=-24706..8541,z=-26255..-2577
|
||||
off x=-6777..14477,y=-71771..-33912,z=46706..60930
|
||||
off x=61137..75324,y=31584..49892,z=-26327..-14848
|
||||
on x=1100..22606,y=28697..54124,z=-81504..-52509
|
||||
off x=-71074..-58799,y=27675..44853,z=-58966..-20807
|
||||
off x=-71600..-42287,y=8542..25589,z=56065..61233
|
||||
on x=-45251..-35045,y=38191..54768,z=44757..67534
|
||||
off x=54620..79108,y=-56141..-42099,z=12070..29484
|
||||
on x=-13747..5593,y=-70633..-59152,z=35086..48154
|
||||
off x=-6784..14050,y=-65722..-55419,z=44065..49503
|
||||
off x=-2302..33895,y=7082..27279,z=-77945..-63272
|
||||
off x=-19701..-7304,y=-76198..-72082,z=28958..48047
|
||||
on x=12815..40193,y=37433..74447,z=-56868..-48723
|
||||
on x=16409..41021,y=-5541..8042,z=-75386..-63309
|
||||
off x=17361..35839,y=6486..33733,z=71504..85138
|
||||
on x=9825..32255,y=-68518..-48749,z=-80039..-57545
|
||||
off x=-62298..-50656,y=-1852..19142,z=44967..61407
|
||||
off x=-65488..-40004,y=-59621..-37464,z=-48950..-23715
|
||||
off x=-21676..-990,y=-79126..-51600,z=-55573..-22384
|
||||
on x=16547..46077,y=59890..75234,z=-23757..-11399
|
||||
on x=-87743..-69823,y=-36681..-16284,z=-11987..20192
|
||||
on x=-41729..-18632,y=-35288..-5409,z=-69092..-63322
|
||||
on x=40240..53567,y=51071..76567,z=-32328..-14382
|
||||
off x=-62904..-45149,y=32738..63897,z=-19593..-15038
|
||||
on x=21216..24135,y=-75210..-50944,z=-44984..-16166
|
||||
on x=-69562..-35055,y=58744..70823,z=-15501..-9281
|
||||
off x=-68150..-52172,y=26975..39630,z=-53507..-17045
|
||||
on x=51169..78842,y=11583..29490,z=29644..52457
|
||||
on x=-15373..4253,y=-97690..-61806,z=1940..31386
|
||||
on x=73779..78637,y=5371..23397,z=-27149..-10358
|
||||
on x=19250..44620,y=-7232..11656,z=-82542..-70642
|
||||
on x=39149..61967,y=-16335..12372,z=52676..65415
|
||||
off x=-23056..-4050,y=-38844..-16159,z=64555..74496
|
||||
off x=45322..60654,y=-64033..-45875,z=-6345..6738
|
||||
off x=54100..90830,y=-34444..-21517,z=5118..19759
|
||||
off x=-231..8241,y=-54245..-31025,z=62160..90247
|
||||
on x=-10127..-4636,y=-83774..-49558,z=30741..56326
|
||||
on x=-61249..-36895,y=58338..75723,z=-15361..7006
|
||||
off x=18751..41594,y=49217..65051,z=35222..37374
|
||||
off x=-19037..-9828,y=-67561..-45441,z=24792..52641
|
||||
on x=40827..72676,y=-15481..-1454,z=37617..66011
|
||||
off x=-64739..-34793,y=-25699..-17432,z=-67453..-38858
|
||||
on x=-18058..5742,y=-23939..-5488,z=-94889..-71764
|
||||
on x=35519..41049,y=-27602..-9277,z=49488..82039
|
||||
on x=9331..32089,y=-17498..8315,z=-80543..-76033
|
||||
off x=-34327..-11605,y=11327..29037,z=-77519..-64466
|
||||
off x=-71841..-43926,y=16818..21609,z=-69739..-45874
|
||||
on x=-56990..-48349,y=-68324..-43481,z=3016..7811
|
||||
off x=9304..25782,y=30245..56041,z=51315..85795
|
||||
off x=32607..48888,y=3690..28091,z=52295..84881
|
||||
off x=-2404..31293,y=58151..81212,z=-31998..-25149
|
||||
on x=-63323..-36977,y=54027..77083,z=-26641..8719
|
||||
off x=60302..80800,y=35514..54303,z=12123..40785
|
||||
off x=47486..64483,y=7507..25137,z=-73417..-59938
|
||||
off x=2177..22958,y=73828..91348,z=20624..37806
|
||||
off x=-68778..-38496,y=-15625..6286,z=50357..61804
|
||||
on x=42481..65067,y=414..25425,z=52357..76953
|
||||
on x=21032..42183,y=-46797..-14635,z=-74998..-57422
|
||||
on x=-57819..-39759,y=37245..65409,z=-31057..-9476
|
||||
on x=29358..58776,y=8103..20134,z=-73101..-67091
|
||||
off x=-26017..-15663,y=-53499..-40680,z=-81777..-63642
|
||||
off x=-75822..-54570,y=-54832..-37673,z=-36225..-20978
|
||||
on x=-30274..-12377,y=62717..73698,z=-51083..-18953
|
||||
on x=25463..45515,y=-79814..-55158,z=15540..44754
|
||||
off x=-58176..-42144,y=-44091..-18834,z=49801..63998
|
||||
off x=40488..54727,y=-80750..-51881,z=-8037..3647
|
||||
on x=66133..82929,y=-13321..9855,z=-45192..-21257
|
||||
off x=3029..23415,y=-78534..-62743,z=-50610..-16058
|
||||
on x=63368..74974,y=104..20701,z=37152..63545
|
||||
on x=40949..74694,y=-62178..-38585,z=2610..19835
|
||||
on x=-472..15977,y=64084..84976,z=-24559..2476
|
||||
off x=49194..76848,y=-47174..-24042,z=-33508..-8663
|
||||
off x=67399..78692,y=-28620..-16523,z=-19377..4508
|
||||
off x=56630..74700,y=-14438..20792,z=36581..74432
|
||||
on x=21015..41464,y=-9104..15645,z=-88506..-73629
|
||||
off x=-43920..-26879,y=14492..28620,z=59594..70987
|
||||
on x=-35951..-21806,y=7254..24763,z=54493..72173
|
||||
on x=3336..22348,y=-15737..-3592,z=60764..78216
|
||||
off x=56117..66807,y=20737..31533,z=-44715..-23712
|
||||
off x=13306..42710,y=68250..78199,z=-32910..-17468
|
||||
off x=-87878..-53833,y=18415..53070,z=-16577..2999
|
||||
on x=33630..50999,y=-67779..-48804,z=30503..55076
|
||||
off x=57002..86011,y=-10279..10607,z=19904..42650
|
||||
off x=18927..33193,y=-16636..-1801,z=-88904..-63937
|
||||
off x=21167..45110,y=-67846..-46840,z=-67041..-43159
|
||||
off x=15448..29805,y=-69142..-47763,z=-56592..-41006
|
||||
on x=-31981..-15095,y=-20248..3871,z=63022..87403
|
||||
off x=-50574..-43927,y=-45935..-22203,z=-54205..-39534
|
||||
off x=23509..30725,y=-59187..-39824,z=-55008..-29804
|
||||
on x=-6893..10692,y=-4433..17662,z=-79958..-63043
|
||||
off x=52839..82867,y=-54135..-43532,z=5074..22443
|
||||
off x=-19801..2279,y=-45316..-18060,z=-73077..-53175
|
||||
off x=-34124..-23489,y=-77318..-57778,z=-10644..21309
|
||||
on x=-62168..-39417,y=46644..71553,z=-12633..-2688
|
||||
on x=-50071..-22810,y=-45081..-19082,z=-71537..-54243
|
||||
on x=-3347..16680,y=71919..95169,z=-26699..-14243
|
||||
off x=-57262..-44366,y=32309..66254,z=-33394..-21315
|
||||
off x=71646..96656,y=-8202..21856,z=-6535..-796
|
||||
on x=-27944..-5589,y=47496..68996,z=51465..59779
|
||||
on x=8322..20036,y=-71459..-51821,z=28654..53172
|
||||
off x=-1130..11235,y=-72111..-54015,z=38692..55881
|
||||
on x=-69102..-39230,y=21462..55716,z=-47827..-41441
|
||||
on x=51340..80906,y=-52377..-19741,z=-34853..-23124
|
||||
off x=-37865..-22986,y=-62050..-50913,z=-69238..-43924
|
||||
on x=28721..62342,y=-8593..21244,z=52533..83625
|
||||
on x=52746..80495,y=22003..40732,z=-40093..-20844
|
||||
off x=35892..47834,y=-67866..-46589,z=34299..53539
|
||||
off x=18277..20309,y=-15322..3925,z=-94574..-68257
|
||||
off x=23509..40977,y=-81126..-48154,z=-21..33400
|
||||
on x=13627..46617,y=-2537..25688,z=-74686..-56092
|
||||
off x=4445..25422,y=1276..13484,z=-78843..-67185
|
||||
off x=-12411..9686,y=-80652..-50914,z=-61600..-42810
|
||||
on x=-18060..-1885,y=16610..43651,z=67414..76707
|
||||
on x=30774..44990,y=-6499..11812,z=-87416..-59474
|
||||
off x=-59552..-40954,y=48890..63902,z=-39700..-21599
|
||||
off x=12390..31538,y=65013..80718,z=-15195..9149
|
||||
off x=-82717..-58814,y=9792..34867,z=31729..41188
|
||||
off x=-62226..-36572,y=-17931..-2307,z=64240..74646
|
||||
5
2021/inputs/23.txt
Normal file
5
2021/inputs/23.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
#############
|
||||
#...........#
|
||||
###D#B#A#C###
|
||||
#B#D#A#C#
|
||||
#########
|
||||
252
2021/inputs/24.txt
Normal file
252
2021/inputs/24.txt
Normal file
@@ -0,0 +1,252 @@
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 14
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 1
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 15
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 7
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 15
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 13
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -6
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 10
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 14
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 0
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -4
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 13
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 15
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 11
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 15
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 6
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 11
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 1
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x 0
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 7
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x 0
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 11
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -3
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 14
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -9
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 4
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -9
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 10
|
||||
mul y x
|
||||
add z y
|
||||
137
2021/inputs/25.txt
Normal file
137
2021/inputs/25.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
>.v>>....v...v...v>...>>>...>v.v>.>.v>...>.>.v.>>>>.>.>.v>>v.v.>.>>vvv....>v.>v....v>vv.v.vvvv>>...>v>v...vvv>>>>..>v>...v>v..vv.>.>..v.v>.
|
||||
v.v.>.vv..v.v.>.......>.v.>>......>.v..>..v..>.vvvvv>v.>>vv>...vvvv.>>v>v>>v...v...v>.vv.v>.>.>..>>....v..>..vvv>.>vv>v....>>>v....>.vv...v
|
||||
..v...>vvv>>......>>..v.v..>.v.v>....v...>v>v..>>v>......>..v.>.>.>.v.>v>v..>.vv>.>...v.vv....>>>..>.v.v>..v...v.>v.>..>v>.v..>>v>v..>>>.v.
|
||||
.>vvv.>.>>>.v..v.>.v..vv>>>..v...v...v>v.>........>>>.>.v..vv>...v.v.vv>v>>>..>>>.v.vvv..>v.vv.v>..v>vv..>.>....>v>vv....v>...>v>v.>>>v>.>>
|
||||
v...v.v.v>.vv>>...vv.v.>v>.>..>>>>...>>vv>.v.>.>>vv.v.>>.>v.>vvvv>v.vv>>.>>.v>v..v.>.>...>>>>v.v>..>.>..v..>vv...v>vv...vvv>>.vv.v.v>.v...v
|
||||
>>v...v.v.>v>.>>>....>.>>v.>....>>>>v.....v>..>v.vv>.....>..>..v..v...>v..>v>..vvv>.>..v.vvv...>vvv>.vv>..>.v...v....v.v.v>.v.>>.v.v..>v.>>
|
||||
>v....v>>>........>....>..>.v>>....v..>...vv>v...v>.>>..v...v>>.......v>..>>.v......vv>>v>>>v.>v>.....>..vv..>v.>>..v.v..v..v>.vv>>>v>>v>vv
|
||||
v.>v.......>...vv..v.v>>v.v>....vv.v>..v..>..>v..>v..v..vv.vv.....>>>....>>v>.>....v>.>.v>...v.>v..v.v..>..>.vv...>.>v.....v.vvvvv..>.>v.>>
|
||||
>.>>..>.vvvv.>.vvv.vv.v>v>>vvv.vv......>...v.>.>vv>>..vv>v>..v>v>>..>.v..v.>>...>.v>>v.v.>.v.v>v>....>>...vv.v>..>v>.>>.>........>.....v>>.
|
||||
>.>v.>v..vv..v>v.vv.>v....>>.v>.>.vv...v>v.>.v>>vv.v>>..>>vvvv..vv>>.vv>.>>...>.>>..vvvv>.>>>.v.v.>>>v..>>..>.>>....vvvv.>..v>v.>...v>...vv
|
||||
>..v.>.>...>v>..>.......>vv.v.>>>.v>..>>>.>.>v...v.v>>>>>v>...>v>..>..>.v.>.>.vv>>v..>v>>.vv......vvv....>>>>v>v.....v.>v>.....>>>..>...>..
|
||||
.v..>>v>.>.>...vv.v.>vv...>.v...>>>.>..v...v...>>v>.>...>.>.v>v.v.>..>.>...v.>>.v...v..>.....vv..vvv.v.>..>v..>v....v>v...v.....vv..>..v.v.
|
||||
..>.>v..v.....>.>>v.>.v>.v>>>.>..>vvv.>.>....>v..v.....v>..>..>>..>v>v.>.v..>.vv.>...>.....v.....vv>......>..vv.>.vvv.v.v>v>v.>>.>>>>...v.>
|
||||
v..vv.v>v>>>..>...>...>vv.>.v.>vv.....>v.>>.>...v.>>...>vvv>v.v>v>v.v.>.......vv>.v>>.vv>.>.v...>..vv>v>..v>>>.....>>...vvv..>vv........v>.
|
||||
..v....v.>>>vv>.>.>>...>.>.v.v..vv......v.....>>.....vv>.vv.v>v..>....v.vv...>....v............>>.>>v...v.>.>>v>..>>>.....v.v..>vv>..v>>...
|
||||
.>v.vv.v.vv.>.>..v>.v...v....>>v...>v.....v.....>>.vv>v.vvv.v..vvv.vv>v.>..>>>v..>.vv...v..v>.v>>>..>>vv..>.v>.vv...v.>>......>..>...vvv.vv
|
||||
..v....>v.>>>v..vv>v..>....v.>.>v..>v..v.v>v.v>...>>>.v...vv>v>>>.v....>.vv.>v...v.v.>v.>vv.v.vvv.>v...v...>.v.>..v.v>>.....vv>>.v>v.......
|
||||
....>>vvv........>v.>.v..>.vv.....>..v..>..vv.>>...>.v...>v.>..>.>....>>>>.....v.v.....>v>.vvvv>.>v..>.vv..>vv>...v..v>>...v..>..v.>.v.....
|
||||
>v>v>>.v....>.v>.v>>..>..v>>v...>.>>>v...>>>vv....>..>.v.v.v..v.>...>.v.v.v.v>.>v...v>.v..vv....v.>...>v.v..>v.v..>...........>>>..>.v.vv..
|
||||
..v...>.>>.v>>.v.v>>.>..>>.>.......v>.v>vv..v.>.v...>v>..v...vv.>...v.>.vv.>..>.v>v.v.>..v>..>..vv>v.v.v>...v>v..>v.v.v.vvv..>v>vv>...vv.>>
|
||||
>.v>.v.>.vvv....v.v....v..vv.v.>>...v...>.v.>.v>v.>v.>.>>>..>v.vvv.v>.>v..>>...>v>..vv.....v.v..>..v.v>.v>v.....v.>vvvv.vv.v.>vv.v..v.>.>.v
|
||||
.>v>v>.v>>v..v>>v.v>..>v..>>.v.v..>..>v.vv>..>v>v.>.vv.>>.v....vvv>...v..v>.v.>.v.v..v>.v>v..>.>..v.v..>...vvv.>.vvv...v>v.....>....vv>....
|
||||
.v>.v>.v.vv>..>....>v......vv..>.>v.....>v>>.v>.......>.v.vvvv..>v....>.v..vv.>v.v..>.>.v>v.>...>.>..vv>.>>.....v.>>v....>...>>>v..v>v>.>..
|
||||
v>.v>>vv>>vv........>v.>..>>v..v.........v.v.vvv.>v>vvv>.......>>>....>>>v..>>..>>>.>......>.v>v..v.vv.>...v>>v..>>>..>.>vv...v>.>...vv>.v.
|
||||
.>...v....>.v>..v.>.vv>.>>v...vv.>..>>v...v.>..>>>vv..>.v.>.v.>.vv>.>>>>.vv>.>v..v>...>..v.v.v.v...v...v>>..v>.....v.>..v.v>.v.vv..vv.v...>
|
||||
.>..v>>...>v>.v>.>>..>>.vvvvv.v>v....v>v>....>v..v.>>>..>>vv..v>.v..>v>..>.>.v.>>>v...v...v>.v..v.v.....v>v..>.........>.>vvvvv>>vvvv..>...
|
||||
>v>......v..v..>v.>>.....>>.v.>..>.>>v.v.>..>.>.>.>v.>..>...v>>.....v.>>......>.>.vvv.>..vvvv..>.>....v..>>..v.>.>>..>.v...>..v>v>>.>....>>
|
||||
>v..>>.>v.>>.v>.>.>.>v.vvvv.v...>.....v....>>v.>vv>.>.>..v...>v>v.v.vv.>>.....>>...v.v>>v.v>.v..>..v>v..>..>.v.v.v.>.vv.>>>.v.v..v.>vv.v.>.
|
||||
v.....v....>>v.v.>..>..>>v>vv>.>v>>.>.vv..v..v>.>.v>.>..v>...>.>v>...v..>>vv...>.>..>v.v>...vvv.v>.>...v>v.vvv>v.>...v....>>>v>vvv>>>.v>...
|
||||
>.>>.vv>.v.v>>>.v>>.v....>v>......v...>>..>.v.>..v.>>.v>..v....>.>.>.v....>>>..>..v>.vv>..>v...v..vv.v...vv>.>..v>..>..vvv.....>>....v.>.vv
|
||||
...>.>.v>....>>v....v.v.>>v>v.v..>v.>>>v..>..>..>v.>.....v.v.v.>>...>.vv..>..v.>vvv...v>....>.v>v>>v>v..v..>.v..vv>..>>>.vv>vv.v>>.v.>>...v
|
||||
.>vv.v...>.>.>..>v.v.v>v...v....v>vv>>.>>.....v>>..v.v>.vv>.v>>vv..>v...v..>v>..>.v..>vv>..>>.v.>.vv>vv.........v>.v........v>>v..v>vv>v.>>
|
||||
.....>...vv.>.v.v..>vv.>.>.>>>..v>...>v...>.>>>.v..>>.>...v>>.v.v.v>>v..>.>>v.>vvv.vv>.>v..vv.>>....v...>v.......v.v.>.>.v.>>.....>v.....>.
|
||||
v>.>v.v>>.v.>vv.vv..v.>v.v........>vv.v>.....>v.>.v....v>.>>..v>.vvv...>.vv.>......>v.>.>..>v>.>..v..>..>..>.>..>>>v.>v.v.>..v.v>>>vv.>>>v>
|
||||
v>v....>...>..>v..v>.vv..vvv>>v.>.>>..>..v....vv..>v>v...>>>.......v.......v.v>....v>>>..>v.vv..v>.>>.vv...vvv.>.>>>>.>.>.>.>>....>>.>>..>.
|
||||
.v.>..vv..>.....>v.>v.>>>v..v>.v>....v>>...>..>>>v>.>>>.........>.>.v.>..v>..v>..vv>.>>v.vv....v>>.v>..v.>.v.>>...>...vv.v.v..vv.>>..v>v..v
|
||||
v>v>.>.v..>v>>.>>.>.>.v>>....v>vv>vv>..v.........>.>.>....v>vv>vv>..v.vv.......vv.vv>>v.v.v..v........v...>v>.>.v.vv..>.>>>>>....v.v...>>>.
|
||||
....vv..>..v>>..v.....v.v>v.>...v>>..>.>.v..v>.>>vv...>>..v.v>.>...>..v.....v>>vv>v..>.>..>.>....vv>..>.v...>.v....>...>.>..>.....vv>v.>v.v
|
||||
.>.v>v..>>...v.v...>...v>.v...v>>.>>....v..v.>.....>>...v.vvvv...vvv.>.>v>v.>>vv..>..>>..v>v.v>.>.v.>>..vv.>.>vv>vv.>.>.>..v..>..v.vv......
|
||||
vv.v.>v.v.>v>>.>....>v>>>vvvv..v.>........>vvv..>..v.....>...>.vv>..v.>v>..v.vv.>>>.>v...>.v>.....>.>v..>...>>>.>v.v..>.v>..vv..v>..vvv>..v
|
||||
.vv>>v>......>.>....vv>..>>.>.>v>..v...>v.>vv..>.>>v>...v>..>..>>>..v>v.v>.v..>v..vv>.>.>..>>...vv>..>v>v.>...vv..v...vvvv..vv>.v..>>.vv...
|
||||
.v.v>.vv....>...>..>>..>v>.>...>.>>..>.v..v..v>.>v...>>>.vv.>....v.v.v.vv>>v>v...>..>.v.v.v....vv.>>.>vvv>..>...vv....v>v>..>>>.v.....v.>>.
|
||||
v.>..vv>v>v>>>....>>....>>v..>..v.>.v.>vv.v.>.v>..>.>>>.v..v>>>.....>vv.v.>>vv....>>>.v>...>v.v.v>v.vv.>....v>>v>...>.v>...>v.v.>>>.vv>.>v>
|
||||
v.>...>>.>v.>>.>..v.v>..vvv.v....>>>vv.....v.v.>>v..v..>..vv..v>...>>.v>v>.>..v.>..>v..>.....>>..v>>v>>>v..>v.v>.>...v..>vv>v>....v..>>>>>v
|
||||
....>.>v>.v.v.>.>.vv>v.v>>>.>...v>v.....vv....v..v.v..vv>>>.v.vvv.v.>..v.vv.v...vvv>..v.>.>.v...vv>.v>.v.>..>vv....v>.>..>v.>>>v.>.>....>.v
|
||||
>>.>>>.>.>vv>..v.>>...v.>....v...vv..v>v>v...v>>v...v.v.>.....>.>>>.>v.v.>vv...v.>......>..>v.>vv.v>v.>...v>>..v.>v>.>.v>v..v.v>.vv.>....v>
|
||||
v..>...v.v....>.>.vvv>.......v>.>v.....v>.>>vvvvvv.v..v..>vv..v.>v..v...>.vv.>>.v...v.vv>..v>..>...>vv>>>...>>.v>..vv..>.....v>v>...>vv.v>.
|
||||
.vv.>v.vv.v.>.>...>v>..>>..>v.v.>>...>v.>>vv>vv..v..>>..>>.v.>>vv>v.>.vvvvv.v..>>>.vv..>>>>>..vv>...vvv....v>vv.>v..vv.....v..>>...>>>>..>.
|
||||
...v>.v..v.>.>.>.v>>.....v.v>.v.>v.v.>.>>>.v>.v>>.vv.>..v.v...vv.>...>.>v..>v....v.v>.>.v..vvv.v.....v.vv..>..v.>..>..v..v>.vvv>>.>..>.>>>.
|
||||
...v.>v.....>vv>v.v>...>vv>>..>.v.>..v>.v.v....v.>.v>.vv>.>..>..>>.v>..>v..>.v>vv.vvv>......>...>.>v>>>....>.v.v.v.v..>.v.>>v>.>v>.>..>v..v
|
||||
v>.v.vvv.v..>.....vv.v>..>>.....v..>.>...>>..v.v>>.>..v....>v>.>v..>.>....>>...>...vv>v.>>vv..>....>v>>v..v>...v.....>>.....v..vv.v.>>...>v
|
||||
v.vvv.>>.vv....>..>v...>>.v>....>v...>.vvv.v......vvv.>vv..vvv...>..v.>.v..vv.v>....v....>.v.v..v>.>...v>v>>>.vvvv..v.vv..>vv>.>v...v.v>..>
|
||||
vv.>....v...vv>.v...vvv.>>v.v>.....>...v>>.>>vv..v.....>vv.vvv>>.v.>>.v..v>>..v>.v.>v>.>.v.v.v..v>>>vv.......>>...v>vvvv>v>.>>v.v>.>>v.>..v
|
||||
v...>.vv..>v..>...>....vv....>.v.>>v>.......v...>>.....v....vv..>v.>.>..>...>>...v.v>v.>.>.....>..>.>.v......>.v.v.vv.>.vv.vv..vvv>vvvvvv>v
|
||||
vv.v>.>v>v..v.v...v.vvv..>v>.v>.v..v>v>>v>...>v.vv..v....v..>..v...vv>>.v..>>.>>v>..>..v.v..>v.v...>>.v>>.v>..v.....v.v.>>>.vvv.>...v.v...>
|
||||
v...v.>v.....>..>v>..>.>>>.v..>.>..>>>>>>v>vvv.>>vv.>>.>..>>v.>.v......v.>.v.v>v...vvvvv>...>.>.vvvv.....v>.>.>.>vv...>..vv....>v>>..>.v>..
|
||||
vv>..v...>.>...v..v.v....>..v>>...>.v>v.>...vv....vv.>...>.>..>>...v>..v>...>...>v..>>...vv.vv.>v...v.>>......>.>.>v>v...v.>...>.v.>.v.>>>.
|
||||
>...>.>.>>..v.....vv.v...>.>>..vvv.v.>>vv>...v.>...>.>.>v...v>.....>v>v>v....v..>>....vv..>v>v...>>v.>vv.>v.>..>....>...v..>.v....v.v..>v>.
|
||||
vv...>v.v>v.v..>>.>>>vv....v.>...>v.v.>>>v...vv..v.v..v.....>v..>>.>..>.v>.>>v..>vv..vvv>v.vvv..vv.v>....>>>>>.v>....>>>..v.>.>.v>......>>v
|
||||
>>.vv>>.>>...vvv.>.>.>>.v>.vv>..>..v.v>.v........v.v>vv.....v.v>v.v.v.v..>>..>v.>.vvv..>>..vv..>...v.v>>.v>....>>>>v.>v>vvv........v.....>.
|
||||
..>..v..v>>vv.>.....v..v.v..vvv.vv..>vv>..vv.v.>v>.>>>v>.v...v.v.v.v..>.v...>.v.vv>.vvv.vv>.v....>....>..>.vv>>v..v.v.>>....v.v>.v..v..v>>.
|
||||
.v>.v>>.....v.>.>v>.>..>>.vvv....>..>>>..v.v.>.>...>v.v>.vvv.>>.vv>v.>.v.v.>...v>vvv.>.v..>v..v>.>>.>>....>v...>..v>.>..v>..v...>v..v.>v>>v
|
||||
v.>.vv.v>...>v..v.>.vvvvv.v..>...>...vv>>..>>>vv.>>v>>>.>.>....vvv.>vv>..vv..>.>>.>>v>.vv..>>.....>.>>..>..>v..>..>>.v>>...vv>>.>..vvv...v.
|
||||
>>..>.v......v....>>.>...>>.>>..>vv.v>>.>.vv.>v.>v.>v..v>..v.v>.v.>v.>>>...>.v.>v..v..>>.v.v.vv>..>>v.v.v>...v>>v>>..>...v.>.....v>v>.>v.>>
|
||||
.v.v>>>>>vv>>.>.>>>.vv..v.>...v.>..>>v.v.vvv...>.>..v.>>.>>.vv..>>>>.vv...>.v.vv.v..v>v>>>.v>vv.v>..vv..>v..>v.>>..>v..v>.>..>.>...v>.v..vv
|
||||
.>.v...vvvv..v...>..>....v.>...v>>v.>v..v>v>..>>>v>...>..>vvv.v.>.v...>v>.v>>>>v...v.>v>....v.v>vv>.vv>.>>v..>...>vv...>.>v.>.vv.>...>v...v
|
||||
>.v.>.>...v>.v..>.v>>.>...v.>>..v.v>.v>.>vvv......>..>.>v>....>>.>v.v...v...>>>>.>..>...>.>v>.v..>...v..>>.v..v>.v>v...>v>>..>..v.>.>.v.v..
|
||||
.v.>>..>.>.v.>v..vv>>..>.>.v.>.>.v..vv..>...v..v.v>...>v..vv>.>vv>.vv>>.>>...v....>..>vv>>>.>.v>..v..vv>v.....>..>>......>.>>v>>.>.>v...vv.
|
||||
....v.>.>>>v.>....>>>v..v.v..vvv>.>v.>v..v..v.>>.....v.v..vv...>v.v...>>.>.v..>.v....v.>v.......vv....>.>v>vv>>..>v.....v>...>..>>>..v....v
|
||||
..>>>.....v>.v>v.vv>>.vv...>>.....v.>..v>v.>v>>.v..vv......>v.v.v.vv>>..v>v.v>..v.>.vvv.>.>>>...>....vv.>v>.....>.v.>..v..vv.>.>...>v>v.>>>
|
||||
...vvv......v.....>>>.....>.>..>.v.>.......>.>.v>v...>.vv>.>...v>.>>.>.>.>>.>vvv...v.v>>>>..v>..>>v..v.v.v..>.vv..v>v..v.v.v......>..vv.v>.
|
||||
v.v.v.v..v..vvv......>vv>>v..>>>>>v>v>.>.......>.>.>..>>>...>vv>.>.>...>..v>>>>.>.>v.>vvv...>.>..v.>.v...>.v>>vvv>vvv....v>>.v>.v>.v>....>.
|
||||
>>vvv.>>..>v.v...v.>v....v...v>>.vv>.vv..vv.v.v>vv.v.........>..v.vv>v>>>v....>...>...>vv.>.>.v>v..>>..>v>.vv..>v.>>>>>...v>...>vv>.v>.v..>
|
||||
>....>.v..>.>.>..>..vv...>>v>vv.>>.v>>>.v....>>>.v.>.v>.>>.vvv..v>>v.....>..v.v..>.vv.>....>>>v..>.v.>>v.....v..>>...v>.>>...>.v...>.>.v>>.
|
||||
v>.v>..>v....v.>>>v.v.v.....v>....vv...>v..vvv..>..>vv>vvv...v>>.vvv..vv>>v>.v...>.v......v>>...v.v....>..v..v>.v>...v.>.>...v.v.vvv..>>..>
|
||||
>v.>.......v>....v.v.>vv>..v>>.v.v.vv.....v........>.v...>.>.>>>v>....>vv>...>v.vv..>.>>v.>.v.>..>..v..>......>>>v>vv....v....>.v>.v.vv.>v>
|
||||
.v>..>..>.>...v.>.v>v..>.>.>.v.>>vvv..>.....v>.vv>v.v.v..>.v..........>v...>.>>.v>>vv.>...>v>..v>v>.>>>.>v.>.>...v.v.>v..>..v.v>..v.>>.vv.>
|
||||
..>.>v.vvv..v.v......>>>>>...>>v>....>v.>vv.........>>vv.vv.>v>...v>.>...vv...>v.>.>vv>....v...>>v>>..v>.>v.>vvv.>>.>v>..v.v>>....vv.v>>v>>
|
||||
>..>>v...v..>v.>..vv.>...v.>>.v.vvv.v..>..>>.v.>....>.>...vv.v..>>.v.>v....v...>..>.v.v>vv...vvvv>>v..>......>..v...>..v..>>........v...v..
|
||||
>v..v.>>......v.vvv.........>>..vv>>vv.>..>v....v.....>..vv..>.v.vv..>>.vv..>>.v.v..>..vvv>>....>...v.v..>v.>>.v.>>>>......v..>....>.v>>v.v
|
||||
.v.>>..>v>>.>...>>..>v.v.v>>v.>..>v..v>>.....>.vvvv>.>....>>.vv..>.>v.>.>>.>>>>..>.>vv>.v>..>.>vv>vvv..v>...v>.v>>.>..>>..>vv>v>.....v>.>v.
|
||||
>v.v..vv.v......vv..v>>....>>>.v..v>v.v>...v..v.v>.>.>..>v>>v>>>..>>v.>...v>>...>.vv.v.v..>..>.v>...>..v.>v...>.v.v>.>>vv>.vv..>v..>>v.vv..
|
||||
...>v..v.vvvv>..>v..v>.vv....v..v..v>vv.>.>v>.v..>.vv>>vv.v.....v.....>.vvv.vv>.>...>v...v>>.vvvvvv.v>......vv.......v..v...>.vvv.vv..>>.vv
|
||||
.vv.>v...v>>.v...v>v.v.vvv.>>v.v.v.....v..v>>.vvv...>v....>vv..>..>.>vv..v..vv.>vvvv.>>>v.v.vv>..>...v>>.v.v>.>>...>...>v>>vv...>v.>.vv>...
|
||||
>>v..v>>>v>v>.v.....>...>v.>.v.v.v..>.>.>...>.vv..>..>>...>v>.v.v.>.....>>>v..v.v..>v.v.v>v...v.>...>v>>.>...v>...>.>.>...v.v.v.....vv.>>>v
|
||||
.v.......v.>v>>.>>v..v.v..v>..>.>>..v....>>.v>.>..vv>>v..>v..v...>...>.....vv.v>...>.>v..>.v.>...vv....v...v..v.vvv.....v...vv...>>>.>v>.>.
|
||||
>>v.....vv.v>.v>.v.>>.vv>.v...v>.v>>v..>>v.>.>>v....>..>v>>>.>..v.v>..>>v>>.....v>.>v....vv.v.v.v.vv.>>>...v.vv>.v>...v>vv>vv..v.>..v....v.
|
||||
..>>...>......>....>v.v.v>.>...>>vv.v>>>.v.v>.>>>vv.v.>..>...>...v.....v....>..vv>>...vv..v..v>.v>.v.v..v...vvv..........>.>v.>.v.>v>v.>v>>
|
||||
..v..>>>>...vvv.v....>..>>...v>.>v.>v...v.>.>.v.v>.v.......>.>v.>.v..vv.....v.v.>.v..v>>...vvvvvvv...v....v..vv..>>..>>>..v.>vv>..v.>>>vv.v
|
||||
vv>.>.vv.v.v.....vv>>v..>v..vv.>>.>.>.v..v>v...>...v.v>>..>.v......v.>>.v.....v......>......>v.>v.v>>>v..>.v>..>.>v.v>..>v.v..v.>.>.>vvv..>
|
||||
>.v.......v>..>.vv>v....>v..>v..vv.v>>v>..>.>>..>..>..v.>v.....>.>>v....v>..v>...>v..>vvv.....vv>v>.v>vv.>v>>.vv>>.v.>.>...vv.v>vv..>.v...>
|
||||
vvv.>.>.>...v.v.vvvvv>.vv>.>...v.>.v..>.>...>v..v...>>vvvv.v>.v.>.vvv...vv.vv.>>.>.>.....vv..vv..vv>>>>.v>>v.>v.v.>>.v..>>v.v>..>>..>v>....
|
||||
v..>...vv...v>......v>...>.....>.>.v>.>vv>v>......>>.v..>.v.>..>>..vv.>v>.v..vv.v..v.>..>v....>..>.>.v.>>vvv..>v.v>v>v..>>.v.>v.v.>>.>>>v..
|
||||
v.........>>v>vv..>.>..>>>.v>...>v...>>.vv.v>...vv...v>>..v..>>>>.>v...vv.>vv>..v.v>...>v.....>.v>>..v.>v>.vvv.>.>v..v.>.v....>>>>.v...v.v>
|
||||
>>.>.>>.vv.>v.v.v.v>v....vvvvv..v.v>>>..>>.>..v>vvv>v.>v>>v>>..>>>>.v.v>.>.>.>>v.v.>v..v.v>>..vv....>....>>.>.vvv>.vv.....v>v.>>vv>v.v.v..>
|
||||
....vv....>....v>v>>...vv>>>.>..>.vv>v>.>>.v>vv..v...>>v..vv..>.vv.v>>>.>.v.v>.>.v>>...v....>.........>.....v>...>.>....vv..v>.v.>v...v....
|
||||
.>v.>.v>>v...>...>.....>.v>..vv>v>.vv>..>.v>.>...v.v.v.v.>v..vv...>...>vv.....>...v>v.>.>..>..v..v.v>.v..v>v.>v..>>...v....v.v>..vv.v>...>v
|
||||
>vvv.v>..vvv>.v>..v>.vv.v>>>vv......vvvvv>>.>v>..>vvv.v.vv>vvv....vvvv.v.>>.v>>..v>..v>v>.>vv.>...v.>>>v.>.>..>..v>>..>..>.v>>.>..>..v.v...
|
||||
.>v>v....>.>.v.....>v.v>.v..v>vv.vvv>.>..>vv..>..>v.>>...>.v>.v..>v..>.>...>..>...vv...>.>>v.>.vv>>....v.>.>.>vv>...v..>.v>v>v>...>v>....>v
|
||||
.>.>...vv.>>>...vv>.v..>>>..>.vv>v..>v.v....>>v>.v.vvv...v>...v..v>.>.>>>>>vv..v.>..v>..>vv>.v>>...v>>.>v.>.vv>.v..v..v...v>>>.v.>.>..>v>.>
|
||||
.>>v.vv.>>>>.>vvvv>>.>vv.>.vvv..>....v.>..>.>.v............>>...>>>>>.>.>>>...v..v.>.>.>..v..>.v>>.>v.>..v.>v.>.....>..>>>>v.v..>v>.>.>..>.
|
||||
.>v>.v..vv.>..v.v.>vvvv..>vv.v.>.v>vv>....v.v...>>..v>.>.>..v..v>.>>>v.>>>v>>...v..vv.vv.vvv...>..>..v..>>...>v.....v>vv....vv....vvv..>>..
|
||||
>v.v.vvvv.v.v....v.>>v....>>.>..>...>.>v>.....>v>v...>>v>...>.>..v.>v>>>..v..>.vv.>>>vv.vv.>v>.....>v.>>.v>.v>vvv.v...v....v...v....>v...v.
|
||||
v>>>v>>>.vv>vvv...v>v..>v>.v>..>.v..v>v....>.>>.v.....v.>>....vv.....v>v.>.>v...>>..>>>.>v.v.vv.>>v..v>vv.vv..>..>v.....v>>v.>.>>...vv.v...
|
||||
>vv.>.v>.>>....>v.>.>v>.>..>.v.vv.>>>>..v>v>vv>>v....>v>>.vv..>..vv>>v....v.v.>>>>v.....vv.v>>.v>....v..>..>>>v..>.>.>>v>.vv....vv>v>.....v
|
||||
..v>.v..>>vv>......>>.>...>..vv..v.v>>.>..>>..v>.....v>..v>>v.v.v.>>v..>v.>>.>vv....v>v>...vv>>>.v>v.v>.>..>v..v>.....v.>>.>v..>v>vv>>>..vv
|
||||
...>>>>>.v.v>..v.....vvv..>.>...vv..v...>.....>v.v..v..v.>v.vvvvv>v..vv.....v>.v.>.....>...>..>...v.>>v>..>.>vv.>>v.v.vv.v.v>..>.....>v>>v.
|
||||
vvv.>...>v>>>v...v.v.v..v...v.>>..vv.....>vv.>..>...>>....>>....>vv.v.>v...vv.vv>.>v.>v.>.>>...v>.....vv..vv.v>vv..>v>>>.>..>>>.vvv...>....
|
||||
..v>.v..>..>....v...>....v>v>v.vv..>>>.v.>.v..>..>>>..vv>>>.v>v.v>...>.v.>>.>.>...>.......v.v>>>.>...vv.v.>>.vv>v>v>..v.>v..v.>..>v.>..>v.>
|
||||
..>v.v...v>...>..v>...>>v>>>>>>.v.>.>.....>.v..v>v...vv.....>v.v.vv..>.v>v.>.>>>>>v.>>.v.v...v>v>>.v>..>vv>.>.vvv>v..>.v.>v>v>>..v>........
|
||||
...v..v>..vvv>...v>...vv....>..>...>...>v.>>vv.>v.>v...>vv>>v.>v......>...>.>..v..v.>v>>.>v>>>...vvv.vv.>..>..v..>>>vv..>...vv.vv>>...>..>.
|
||||
>.v...>>>>>>vvv..vvvvvv.vv..>.v>.v.v..vvv>v..>v>.>vvvvv>>..>.vv...>.v....>>>...v.vv..>......v..>..v.v....v....v.....>.v...v.vv>>..>..v..v.v
|
||||
...v>v..>.>..v...>v>v....>vvv>>>.v>>...>....vv>v...>v..>.v.>....v..>v..>.>v>.v.>..vv..v.....v..v..>....>.>.>v.>vv.vv.vv.>>v...vv.....v.>>v>
|
||||
v..vv..>...>.vv..v.v.....vv..>v......>v...v>v..v>.v>...>v>vvv>...v>v...>v.>>v......v>.>.........vv>....>vv>>v..v.v>..>vvv..>vvv..>.v.vv...v
|
||||
v.>v.>..vv>..>.....>>>....v.vv.v...vv.v.vvv..>....>>v>v>.>.v>>>.>.>.>...v.v...v.>v..v.>v>.vv.>>>.v.vv..>v>.v>..>vv>>.v>.>v..v..v>v>.>.>vvvv
|
||||
..>..>>......>.v>>>>.>v>..>.v....>...>>.v.v.vv....>.v>.>v.>>.>>v>.>..>vvvvv.v.>.v.v>.v>v.v>..>v..v.v.>v>>.>v>>.>.v.v..>.v.v>..>v...>.v>>.>>
|
||||
v....>.v>..v.>..v...>...>>v>.....v.....>..vv>v...v..vvv>.v..vv>v>v..>.>....>....v..v>>......v.>.vv>..>v.>>..v.....>.v>>.v...v>..>.>.v.v.>>v
|
||||
..v>.v....>v.v.>..>v.>.v....>.>v..v>...>v.v.....>..vv...v>....v.v..v>v.>.v>>>v>..>v.>...>.>...v..>>>v>v>....v>>v..v..>>....v>>.vv>.vv.>.v..
|
||||
>v..>...>..>>.vv.>v.>.....v>v.vv>vvv.v>>.>..v.>>..v..>.....>>.>vv.v.>>>v.>vv...v.>v>..>..>..v.vv...v...v>>>vv>.v.v..>>>..>.>v>...vv>.v..v>.
|
||||
....>vv.>vv.v>.v....>>v..v>.v.>>v>vv>..v.>>.>v>v.v..vv.v.>.v..>.......>.>v>.v>vvv>v.>.>..>>v>..vv>.vvv>.>>..v>vv.>>..>v>v>.v.>>........>>v.
|
||||
>.>vvv.>>.>..vvv.v...vvv..>>v.>>.v>.v..>v.v>..v.>...>..vv>v........>v..v>.v...v.v..vv.v...v.v>..>v.....vv...v.vvvv.>.v...>>......>>.>>...>v
|
||||
...>>...>>>v..vv...v>.>.v....v>v...>.>>>v.>>.............vv.>..v>.>v.>v.>..>.vv..>>.v..>>>>....v..>>v...v.v.>.>v>>>..>......>vvv>vvv>>.>>vv
|
||||
...v...v.v>>.>.>>>..v.v.>..>>.>.>.v>....>v...>>.v>>vv.....>>.>...v......v...>v.vv>>vv>....>.>>vv>v.>>>.>>vv..>.v..v>v...v.v..v...v..>v...>>
|
||||
..v..v>vvvv..>>..v>>.>>....v>>v...>>>..v.....v....>.>v.>>v>v...vv.....>>.>v..v.>..>v...>>.>.>>...>>...>>.>>...v>..v...>v...>v>>>..v.v.vvv..
|
||||
...v..v>>>v..>>>v..v>.>vv>.v.>.v...>..>vv>.v>>v>..v>>......>.v>>...v>v..>v.>...>......v.vv..v.>v...vvv>.>..v..v..v>v..>..>........>>...v...
|
||||
.>.v>...vv..v.v>>>v..>v>..v..>>v....v..v>...>v..>.v.>....>v>v.>>v.>.v....v.>.v.>>v>>.v>>..v.v..>v.>..vv>.>>>>>v.>.v>v.>...v.vvv...v.>v..>>>
|
||||
.v>.>>..>v.v>>..>>...>v..v..>..v.>>>.>.vv...v....v...>vv>v>..v..vv>......v>v.>>>.v...v.>>.>.>v..>....vv.vvv..>v..vvv>>.v.v>....vvv>vv.v.v..
|
||||
>..>v.>.>..>v.v.vv.>>.>....v.>v..>v.>>.vv..>.>>.>.v.>>..vvv>>.v...v.>.v.v>...>>...>...vvv>>vvvv.>v.>v..v..v.v..v..v...>.>...>>v.....>v..>v.
|
||||
..>....>...>>.>....vv.v.v>.......>v...v..>..>>......>>.v...>.>.>...>>.v.v.v..v>.>>>v...>>>.v..>....v..>v.>.vv......v..v..>.>>.>..vv.>.v..>.
|
||||
v>..v.v>.>...vv.v.>>..v>.vv.>v.>.>..v>>vv>>.v.>.>>.vv.>.>..v....v>>v....>.>.v.>.>v>v.>.v>v.>..>....v...v.v>v.>.>v.....>>>>v.v.>..v......v>.
|
||||
..v...>v>.>...>.....vv.vv>>.>..>.v.v>...v....>..v.>v.....>......v>....vv.v.v.>...v..v.v..v.>v.v.>vvv..v....>..>..v.>v.v.vvv.v.>>>....>v....
|
||||
>>..vv...>>.vv>vv>.>>...>...>.>v>>..vv.>.>.v.v.>>...>..>>v>v>...>.v>....>.>.....v..>>vv..>.>...v>>v......v.>v......>>>..>>.>.>.v>>v...>v...
|
||||
>>>..vv>v....v>..>......v..>vv.>>v>..>.>..vv.vv.v.>>..v...>.v.v..>>.>..v..vv.v.>>..>>.......>.>>v.v>v..>v>v>>>...vv..>v>..vvvv.>v>v.v>.>>v.
|
||||
.>....v.>>.v.v..>vv.>v..>v...>.vv.v.>vv.v...v...>v..v..v..v...>...v.>>>.>>.....>.>....>v>vvv..>.vv.vv.v...>v.>.v.>.>...>v..vv>>>.>...vvv>.>
|
||||
v.....>...v.>....>v..>v.>.vv.v>>v..>....>vvv.>>.>v.v.v.v..v...>v.>v...v>v...v.v>v...v.>v..v.vv..v>v..>..v.>...>..>....>..v.vv>>.v...v>.vv.v
|
||||
....>>.>.vv>>..v>>vvv.......>v...>>.vv>..>.vv>v>.v>v..>v...vvv..>>v>.>.v.v..>...vv...v..>..vv..vv...>..v..>v>...>.v>.v....v..vvv.>v.>v>vv..
|
||||
>v..v.....vv>v>..>>..v...>v>..>...v>>>>....v..vvvv>.........>..v.v>.v...v.v....v.>v.v>.>v..v.vvv>.v>.>..>>..>>>..v.>>>v.>..>.>v..>vvv.>v>..
|
||||
@@ -90,7 +90,65 @@ where
|
||||
let mut buffer = Vec::new();
|
||||
input.read_to_end(&mut buffer).unwrap();
|
||||
|
||||
let (_, output) = parser(&buffer).finish().unwrap();
|
||||
|
||||
output
|
||||
match parser(&buffer).finish() {
|
||||
Ok((_, output)) => output,
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Failed to parse input with error {:?} at \"{}\"",
|
||||
err.code,
|
||||
String::from_utf8_lossy(err.input)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BitSet {
|
||||
buffer: Vec<u32>,
|
||||
}
|
||||
|
||||
impl BitSet {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
let buffer = vec![0; capacity / 32];
|
||||
|
||||
Self { buffer }
|
||||
}
|
||||
|
||||
fn convert_value(value: usize) -> (usize, u32) {
|
||||
let chunk = value / 32;
|
||||
let bit = 1 << (31 - (value % 32));
|
||||
|
||||
(chunk, bit)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, value: usize) -> bool {
|
||||
let (chunk, bit) = Self::convert_value(value);
|
||||
|
||||
if self.buffer.len() <= chunk + 1 {
|
||||
self.buffer.resize(chunk + 1, 0);
|
||||
}
|
||||
|
||||
let not_present = self.buffer[chunk] & bit;
|
||||
|
||||
self.buffer[chunk] |= bit;
|
||||
|
||||
not_present == 0
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.buffer.iter().map(|c| c.count_ones() as usize).sum()
|
||||
}
|
||||
|
||||
pub fn contains(&self, value: usize) -> bool {
|
||||
let (chunk, bit) = Self::convert_value(value);
|
||||
|
||||
self.buffer
|
||||
.get(chunk)
|
||||
.map(|&c| c & bit != 0)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,95 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io::Read;
|
||||
use std::iter::repeat;
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::sequence::tuple;
|
||||
use nom::Finish;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::ordered;
|
||||
use crate::common::LineIter;
|
||||
use crate::common::read_input;
|
||||
use crate::common::BitSet;
|
||||
|
||||
type Coord = (u16, u16);
|
||||
|
||||
fn coordinates(input: &str) -> IResult<&str, Coord> {
|
||||
use nom::character::complete;
|
||||
fn coordinates(input: &[u8]) -> IResult<&[u8], Coord> {
|
||||
use nom::character::complete::char;
|
||||
use nom::character::complete::u16;
|
||||
|
||||
let (input, (x, _, y)) = tuple((complete::u16, complete::char(','), complete::u16))(input)?;
|
||||
|
||||
Ok((input, (x, y)))
|
||||
separated_pair(u16, char(','), u16)(input)
|
||||
}
|
||||
|
||||
fn line_definition(input: &str) -> IResult<&str, (Coord, Coord)> {
|
||||
let (input, (begin, _, end)) = tuple((coordinates, tag(" -> "), coordinates))(input)?;
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<(Coord, Coord)>> {
|
||||
let read_line = map(
|
||||
separated_pair(coordinates, tag(" -> "), coordinates),
|
||||
|(begin, end)| ordered(begin, end),
|
||||
);
|
||||
|
||||
// Sorting the coordinates saves trouble later
|
||||
Ok((input, ordered(begin, end)))
|
||||
separated_list1(newline, read_line)(input)
|
||||
}
|
||||
|
||||
fn stripe(
|
||||
map: &mut HashMap<Coord, u16>,
|
||||
once: &mut BitSet,
|
||||
twice: &mut BitSet,
|
||||
width: usize,
|
||||
xs: impl Iterator<Item = u16>,
|
||||
ys: impl Iterator<Item = u16>,
|
||||
) {
|
||||
for (x, y) in xs.zip(ys) {
|
||||
*map.entry((x, y)).or_default() += 1;
|
||||
let index = x as usize + y as usize * width;
|
||||
if !once.insert(index) {
|
||||
twice.insert(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn part_common(input: &mut dyn Read, diagonals: bool) -> String {
|
||||
let mut reader = LineIter::new(input);
|
||||
let mut map = HashMap::new();
|
||||
let lines = read_input(input, parse_input);
|
||||
|
||||
while let Some(line) = reader.next() {
|
||||
let (begin, end) = line_definition(line).finish().unwrap().1;
|
||||
let width = lines
|
||||
.iter()
|
||||
.map(|&(_, (x, _))| x as usize + 1)
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
let mut once_map = BitSet::new();
|
||||
let mut twice_map = BitSet::new();
|
||||
|
||||
for (begin, end) in lines {
|
||||
if begin.0 == end.0 {
|
||||
let y_range = begin.1..=end.1;
|
||||
stripe(&mut map, repeat(begin.0), y_range);
|
||||
stripe(
|
||||
&mut once_map,
|
||||
&mut twice_map,
|
||||
width,
|
||||
repeat(begin.0),
|
||||
y_range,
|
||||
);
|
||||
} else if begin.1 == end.1 {
|
||||
let x_range = begin.0..=end.0;
|
||||
stripe(&mut map, x_range, repeat(begin.1));
|
||||
stripe(
|
||||
&mut once_map,
|
||||
&mut twice_map,
|
||||
width,
|
||||
x_range,
|
||||
repeat(begin.1),
|
||||
);
|
||||
} else if diagonals {
|
||||
let x_range = begin.0..=end.0;
|
||||
let y_range = (begin.1.min(end.1))..=(begin.1.max(end.1));
|
||||
|
||||
if begin.1 > end.1 {
|
||||
// For a downward slope we need to reverse Y
|
||||
stripe(&mut map, x_range, y_range.rev());
|
||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range.rev());
|
||||
} else {
|
||||
stripe(&mut map, x_range, y_range);
|
||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.values().filter(|&&v| v > 1).count().to_string()
|
||||
twice_map.len().to_string()
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
@@ -82,11 +108,6 @@ mod tests {
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/05.txt");
|
||||
|
||||
#[test]
|
||||
fn test_parser() {
|
||||
assert_eq!(line_definition("6,4 -> 2,0"), Ok(("", ((2, 0), (6, 4)))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 5)
|
||||
|
||||
@@ -79,7 +79,7 @@ pub fn part2(input: &mut dyn Read) -> String {
|
||||
let mut grid = read_grid(input, &mut buffer);
|
||||
let mut todo = Vec::new();
|
||||
|
||||
let target = grid.iter().map(|line| line.len()).sum();
|
||||
let target: usize = grid.iter().map(|line| line.len()).sum();
|
||||
|
||||
(1..)
|
||||
.find(|_| advance(&mut grid, &mut todo) == target)
|
||||
|
||||
@@ -48,7 +48,7 @@ fn parse_fold(input: &[u8]) -> IResult<&[u8], Fold> {
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn apply_fold(dots: &mut Vec<Coords>, fold: Fold) {
|
||||
fn apply_fold(dots: &mut [Coords], fold: Fold) {
|
||||
match fold {
|
||||
Fold::X(coord) => dots.iter_mut().for_each(|(x, _)| {
|
||||
if *x >= coord {
|
||||
|
||||
@@ -182,7 +182,7 @@ mod tests {
|
||||
fn sample_part1() {
|
||||
let answers = [16, 12, 23, 31];
|
||||
|
||||
for (&sample, answer) in SAMPLE.into_iter().zip(answers) {
|
||||
for (&sample, answer) in SAMPLE.iter().zip(answers) {
|
||||
test_implementation(part1, sample, answer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::io::Read;
|
||||
use std::ops::Add;
|
||||
use std::ops::Deref;
|
||||
use std::ops::Sub;
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
@@ -23,6 +25,10 @@ impl Point3 {
|
||||
pub fn manhattan(&self) -> i32 {
|
||||
self.0.into_iter().map(i32::abs).sum()
|
||||
}
|
||||
|
||||
pub fn euler_square(&self) -> i32 {
|
||||
self.0.into_iter().map(|c| c * c).sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Point3 {
|
||||
@@ -49,6 +55,44 @@ impl Add for Point3 {
|
||||
}
|
||||
}
|
||||
|
||||
struct Scanner {
|
||||
visible: Vec<Point3>,
|
||||
distances: HashMap<i32, (Point3, Point3)>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(visible: Vec<Point3>) -> Self {
|
||||
let distances = visible
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(skip, &a)| {
|
||||
visible[(skip + 1)..]
|
||||
.iter()
|
||||
.map(move |&b| ((a - b).euler_square(), (a, b)))
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self { visible, distances }
|
||||
}
|
||||
|
||||
pub fn can_overlap(&self, other: &Self) -> bool {
|
||||
other
|
||||
.distances
|
||||
.keys()
|
||||
.filter(|&k| self.distances.contains_key(k))
|
||||
.count()
|
||||
>= 11
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Scanner {
|
||||
type Target = [Point3];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.visible
|
||||
}
|
||||
}
|
||||
|
||||
struct Rotations<'a> {
|
||||
points: &'a [Point3],
|
||||
axes: [usize; 3],
|
||||
@@ -119,32 +163,56 @@ fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Vec<Point3>>> {
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
|
||||
use nom::character::complete::i32;
|
||||
let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));
|
||||
|
||||
let parse_scanner = preceded(parse_header, many1(terminated(parse_point, newline)));
|
||||
let parse_scanner = map(
|
||||
preceded(parse_header, many1(terminated(parse_point, newline))),
|
||||
Scanner::new,
|
||||
);
|
||||
separated_list1(newline, parse_scanner)(input)
|
||||
}
|
||||
|
||||
fn try_overlap(
|
||||
correct: &[(Point3, HashSet<Point3>)],
|
||||
candidate: &[Point3],
|
||||
) -> Option<(Point3, Vec<Point3>)> {
|
||||
let mut relative = HashSet::new();
|
||||
fn find_pivot(group: &Scanner, related: &Scanner) -> Option<Point3> {
|
||||
let mut counter = HashMap::new();
|
||||
|
||||
for (distance, &(a, b)) in &group.distances {
|
||||
if related.distances.contains_key(distance) {
|
||||
*counter.entry(a).or_insert(0) += 1;
|
||||
*counter.entry(b).or_insert(0) += 1;
|
||||
}
|
||||
}
|
||||
|
||||
counter
|
||||
.into_iter()
|
||||
.max_by_key(|(_, count)| *count)
|
||||
.map(|t| t.0)
|
||||
}
|
||||
|
||||
fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanner)> {
|
||||
if !matched.can_overlap(candidate) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let matched_pivot = find_pivot(matched, candidate)?;
|
||||
|
||||
let correct: HashSet<_> = matched.iter().map(|&base| base - matched_pivot).collect();
|
||||
|
||||
for rot in Rotations::new(candidate) {
|
||||
for &start in &rot {
|
||||
relative.clear();
|
||||
let translated_iter = rot.iter().map(|&other| other - start);
|
||||
|
||||
relative.extend(rot.iter().map(|&other| other - start));
|
||||
|
||||
if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
|
||||
correct_relative.intersection(&relative).count() >= 12
|
||||
}) {
|
||||
if translated_iter
|
||||
.clone()
|
||||
.filter(|p| correct.contains(p))
|
||||
.count()
|
||||
>= 12
|
||||
{
|
||||
// Found a solution, build the correct output
|
||||
let translated = relative.drain().map(|point| point + *base).collect();
|
||||
let translated = translated_iter.map(|point| point + matched_pivot).collect();
|
||||
|
||||
return Some((start - *base, translated));
|
||||
return Some((start - matched_pivot, Scanner::new(translated)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,33 +225,30 @@ fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
|
||||
|
||||
let mut points: HashSet<_> = scanners[0].iter().copied().collect();
|
||||
|
||||
let mut todo = vec![std::mem::take(&mut scanners[0])];
|
||||
let mut todo = vec![scanners.remove(0)];
|
||||
let mut scanners_found = vec![Point3::default()];
|
||||
|
||||
while let Some(matched) = todo.pop() {
|
||||
if scanners.iter().all(Vec::is_empty) {
|
||||
if scanners.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
let relative: Vec<(Point3, HashSet<Point3>)> = matched
|
||||
.iter()
|
||||
.map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
|
||||
.collect();
|
||||
let mut i = 0;
|
||||
|
||||
for candidate in &mut scanners {
|
||||
if candidate.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((scanner, result)) = try_overlap(&relative, candidate) {
|
||||
while i < scanners.len() {
|
||||
if let Some((scanner, result)) = try_overlap(&matched, &scanners[i]) {
|
||||
scanners.remove(i);
|
||||
scanners_found.push(scanner);
|
||||
points.extend(result.iter().copied());
|
||||
todo.push(result);
|
||||
candidate.clear();
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(scanners.is_empty());
|
||||
|
||||
(points, scanners_found)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,176 @@
|
||||
use std::fmt::Display;
|
||||
use std::io::Read;
|
||||
use std::ops::Index;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use crate::common::BitSet;
|
||||
|
||||
type Translation = [bool; 512];
|
||||
|
||||
struct Field {
|
||||
width: usize,
|
||||
height: usize,
|
||||
infinity: bool,
|
||||
finite: BitSet,
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
impl Field {
|
||||
pub fn from_input<'a>(input: impl Iterator<Item = &'a [u8]>) -> Self {
|
||||
let mut input = input.peekable();
|
||||
|
||||
let width = input.peek().unwrap().len();
|
||||
|
||||
let mut finite = BitSet::new();
|
||||
|
||||
let len = input
|
||||
.flatten()
|
||||
.enumerate()
|
||||
.map(|(index, &c)| {
|
||||
if c == b'#' {
|
||||
finite.insert(index);
|
||||
}
|
||||
})
|
||||
.count();
|
||||
|
||||
debug_assert_eq!(len % width, 0);
|
||||
let height = len / width;
|
||||
|
||||
Self {
|
||||
width,
|
||||
height,
|
||||
finite,
|
||||
infinity: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn advance(&mut self, translation: &[bool; 512]) {
|
||||
const INDEX_MASK: usize = (1 << 9) - 1;
|
||||
|
||||
let new_width = self.width + 2;
|
||||
let new_height = self.height + 2;
|
||||
|
||||
let mut new_finite = BitSet::with_capacity(new_width * new_height);
|
||||
|
||||
for y in 0..new_height {
|
||||
let mut mask = if self.infinity { INDEX_MASK } else { 0 };
|
||||
|
||||
for x in 0..new_width {
|
||||
const COLUMN_MASK: usize = 0b001001001;
|
||||
let mut submask = if self.infinity { COLUMN_MASK } else { 0 };
|
||||
|
||||
for y in y.saturating_sub(2)..=y {
|
||||
submask = (submask << 3) | (self[(x, y)] as usize);
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
mask &= !COLUMN_MASK;
|
||||
mask |= submask;
|
||||
mask &= INDEX_MASK;
|
||||
|
||||
if translation[mask] {
|
||||
let index = x + y * new_width;
|
||||
new_finite.insert(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.width += 2;
|
||||
self.height += 2;
|
||||
self.finite = new_finite;
|
||||
self.infinity = translation[if self.infinity { INDEX_MASK } else { 0 }];
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
assert!(!self.infinity);
|
||||
self.finite.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<(usize, usize)> for Field {
|
||||
type Output = bool;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
|
||||
if x >= self.width || y >= self.height {
|
||||
return &self.infinity;
|
||||
}
|
||||
|
||||
let index = x + y * self.width;
|
||||
|
||||
if self.finite.contains(index) {
|
||||
&true
|
||||
} else {
|
||||
&false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Field {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
if self[(x, y)] {
|
||||
write!(f, "#")?
|
||||
} else {
|
||||
write!(f, ".")?
|
||||
}
|
||||
}
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn read_input(input: &mut dyn Read) -> (Translation, Field) {
|
||||
let mut buffer = Vec::new();
|
||||
input.read_to_end(&mut buffer).unwrap();
|
||||
|
||||
let mut translation = [false; 512];
|
||||
|
||||
let mut it = buffer.split(|&b| b == b'\n');
|
||||
|
||||
translation
|
||||
.iter_mut()
|
||||
.zip(it.next().unwrap())
|
||||
.for_each(|(t, &c)| *t = c == b'#');
|
||||
|
||||
let field = Field::from_input(it.skip(1));
|
||||
|
||||
(translation, field)
|
||||
}
|
||||
|
||||
fn parts_common(input: &mut dyn Read, count: usize) -> String {
|
||||
let (translation, mut field) = read_input(input);
|
||||
|
||||
for _ in 0..count {
|
||||
field.advance(&translation);
|
||||
}
|
||||
|
||||
field.len().to_string()
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
parts_common(input, 2)
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
parts_common(input, 50)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_implementation;
|
||||
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/20.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 35);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE, 3351);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,171 @@
|
||||
use std::io::Read;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use crate::common::LineIter;
|
||||
|
||||
fn read_input(input: &mut dyn Read) -> (i32, i32) {
|
||||
let mut reader = LineIter::new(input);
|
||||
|
||||
let mut helper = || {
|
||||
reader
|
||||
.next()
|
||||
.unwrap()
|
||||
.split(' ')
|
||||
.last()
|
||||
.unwrap()
|
||||
.parse()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let a = helper();
|
||||
let b = helper();
|
||||
|
||||
(a, b)
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
#[inline]
|
||||
fn simulate(die: i32, pos: i32) -> i32 {
|
||||
(pos + 3 * die + 3 - 1) % 10 + 1
|
||||
}
|
||||
|
||||
fn find_repetition(mut pos: i32, mut die: i32) -> i32 {
|
||||
let mut advance = 0;
|
||||
|
||||
for _ in 0..10 {
|
||||
pos = simulate(die, pos);
|
||||
advance += pos;
|
||||
die = (die + 6) % 10;
|
||||
}
|
||||
|
||||
advance
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
const TARGET_SCORE: i32 = 1000;
|
||||
|
||||
let (mut a, mut b) = read_input(input);
|
||||
|
||||
let a10 = find_repetition(a, 1);
|
||||
let b10 = find_repetition(b, 4);
|
||||
|
||||
let a_win = TARGET_SCORE / a10;
|
||||
let b_win = TARGET_SCORE / b10;
|
||||
|
||||
let win = a_win.min(b_win);
|
||||
let mut a_score = win * a10;
|
||||
let mut b_score = win * b10;
|
||||
let mut die = 1;
|
||||
let mut rolls = 3 * 20 * win;
|
||||
|
||||
let (loser_score, rolls) = if a_win < b_win {
|
||||
while a_score < TARGET_SCORE {
|
||||
a = simulate(die, a);
|
||||
a_score += a;
|
||||
rolls += 3;
|
||||
|
||||
if a_score < TARGET_SCORE {
|
||||
b = simulate(die + 3, b);
|
||||
b_score += b;
|
||||
rolls += 3;
|
||||
}
|
||||
|
||||
die = (die + 6) % 10;
|
||||
}
|
||||
|
||||
(b_score, rolls)
|
||||
} else {
|
||||
while b_score < TARGET_SCORE {
|
||||
a = simulate(die, a);
|
||||
a_score += a;
|
||||
|
||||
b = simulate(die + 3, b);
|
||||
b_score += b;
|
||||
|
||||
rolls += 6;
|
||||
|
||||
die = (die + 6) % 10;
|
||||
}
|
||||
|
||||
(a_score, rolls)
|
||||
};
|
||||
|
||||
(loser_score * rolls).to_string()
|
||||
}
|
||||
|
||||
const MAX_TURNS: usize = 13;
|
||||
const ROLLS: [i32; 7] = [3, 4, 5, 6, 7, 8, 9];
|
||||
const FREQS: [u64; 7] = [1, 3, 6, 7, 6, 3, 1];
|
||||
|
||||
fn multiverse(pos: i32) -> ([u64; MAX_TURNS], [u64; MAX_TURNS]) {
|
||||
type State = [[u64; 10]; 21];
|
||||
|
||||
// Let's work with pos - 1 as pos for now, indexes nicer;
|
||||
let pos = pos as usize - 1;
|
||||
|
||||
let mut alive = [0; MAX_TURNS];
|
||||
let mut wins = [0; MAX_TURNS];
|
||||
|
||||
alive[0] = 1;
|
||||
|
||||
let mut current = [[0u64; 10]; 21];
|
||||
current[0][pos] = 1;
|
||||
let mut next = [[0u64; 10]; 21];
|
||||
|
||||
let mut helper = |turn, current: &State, next: &mut State| {
|
||||
next.iter_mut().flatten().for_each(|v| *v = 0);
|
||||
|
||||
for (score, score_row) in current.iter().enumerate() {
|
||||
for (pos, &pop) in score_row.iter().enumerate() {
|
||||
for (roll, freq) in ROLLS.into_iter().zip(FREQS) {
|
||||
let new_pos = (pos + (roll as usize)) % 10;
|
||||
let new_score = score + new_pos + 1; // +1 because above
|
||||
let new_pop = freq * pop;
|
||||
|
||||
if new_score >= next.len() {
|
||||
wins[turn] += new_pop;
|
||||
} else {
|
||||
alive[turn] += new_pop;
|
||||
next[new_score][new_pos] += new_pop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for turn in (1..MAX_TURNS).step_by(2) {
|
||||
helper(turn, ¤t, &mut next);
|
||||
helper(turn + 1, &next, &mut current);
|
||||
}
|
||||
|
||||
(wins, alive)
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let (a, b) = read_input(input);
|
||||
|
||||
let (a_wins, a_alive) = multiverse(a);
|
||||
let (b_wins, b_alive) = multiverse(b);
|
||||
|
||||
let a_winner: u64 = a_wins[1..].iter().zip(b_alive).map(|(&a, b)| a * b).sum();
|
||||
let b_winner: u64 = b_wins.into_iter().zip(a_alive).map(|(a, b)| a * b).sum();
|
||||
|
||||
a_winner.max(b_winner).to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_implementation;
|
||||
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/21.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 739785);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE, 444356092776315u64);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,199 @@
|
||||
use std::io::Read;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::read_input;
|
||||
|
||||
type Point3 = [i32; 3];
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
struct Cuboid {
|
||||
lower: Point3,
|
||||
upper: Point3,
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
impl Cuboid {
|
||||
pub fn new(lower: Point3, upper: Point3) -> Self {
|
||||
// The input uses an inclusive range for representation, but an exclusive one simplifies a
|
||||
// lot of computations, so we convert here.
|
||||
Self::new_internal(lower, upper.map(|c| c + 1))
|
||||
}
|
||||
|
||||
fn new_internal(lower: Point3, upper: Point3) -> Self {
|
||||
debug_assert!(lower.iter().zip(&upper).all(|(a, b)| a < b));
|
||||
Self { lower, upper }
|
||||
}
|
||||
|
||||
pub fn is_small(&self) -> bool {
|
||||
self.lower
|
||||
.iter()
|
||||
.chain(&self.upper.map(|c| c - 1)) // begrudgingly convert back
|
||||
.all(|c| c.abs() <= 50)
|
||||
}
|
||||
|
||||
pub fn volume(&self) -> i64 {
|
||||
self.lower
|
||||
.iter()
|
||||
.zip(&self.upper)
|
||||
.map(|(&l, &h)| (h - l) as i64)
|
||||
.product()
|
||||
}
|
||||
|
||||
fn overlaps(&self, other: &Self) -> bool {
|
||||
self.lower
|
||||
.iter()
|
||||
.zip(&self.upper)
|
||||
.zip(other.lower.iter().zip(&other.upper))
|
||||
.all(|((&al, &ah), (&bl, &bh))| al < bh && bl < ah)
|
||||
}
|
||||
|
||||
pub fn retain_nonoverlapping(&self, other: &Self, new_cubes: &mut Vec<Self>) -> bool {
|
||||
if !self.overlaps(other) {
|
||||
// Cube can be kept as-is.
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut lower = self.lower;
|
||||
let mut upper = self.upper;
|
||||
|
||||
for axis in 0..3 {
|
||||
if other.lower[axis] > self.lower[axis] {
|
||||
let mut new_upper = upper;
|
||||
new_upper[axis] = other.lower[axis];
|
||||
|
||||
new_cubes.push(Cuboid {
|
||||
lower,
|
||||
upper: new_upper,
|
||||
});
|
||||
|
||||
lower[axis] = other.lower[axis];
|
||||
}
|
||||
|
||||
if other.upper[axis] < self.upper[axis] {
|
||||
let mut new_lower = lower;
|
||||
new_lower[axis] = other.upper[axis];
|
||||
|
||||
new_cubes.push(Cuboid {
|
||||
lower: new_lower,
|
||||
upper,
|
||||
});
|
||||
|
||||
upper[axis] = other.upper[axis];
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_tuple(input: &[u8]) -> IResult<&[u8], (i32, i32)> {
|
||||
use nom::character::complete::i32;
|
||||
separated_pair(i32, tag(".."), i32)(input)
|
||||
}
|
||||
|
||||
fn parse_cuboid(input: &[u8]) -> IResult<&[u8], Cuboid> {
|
||||
map(
|
||||
tuple((
|
||||
parse_tuple,
|
||||
preceded(tag(",y="), parse_tuple),
|
||||
preceded(tag(",z="), parse_tuple),
|
||||
)),
|
||||
|((xl, xh), (yl, yh), (zl, zh))| Cuboid::new([xl, yl, zl], [xh, yh, zh]),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<(bool, Cuboid)>> {
|
||||
let parse_state = alt((map(tag("on x="), |_| true), map(tag("off x="), |_| false)));
|
||||
let parse_line = tuple((parse_state, parse_cuboid));
|
||||
|
||||
separated_list1(newline, parse_line)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
let commands = read_input(input, parse_input);
|
||||
let mut cubes = Vec::new();
|
||||
let mut new_cubes = Vec::new();
|
||||
|
||||
for (state, cube) in commands.into_iter().filter(|(_, c)| c.is_small()) {
|
||||
cubes.retain(|existing: &Cuboid| existing.retain_nonoverlapping(&cube, &mut new_cubes));
|
||||
|
||||
// Add new cubes to the end
|
||||
cubes.append(&mut new_cubes);
|
||||
|
||||
if state {
|
||||
cubes.push(cube);
|
||||
}
|
||||
}
|
||||
|
||||
cubes.iter().map(Cuboid::volume).sum::<i64>().to_string()
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let commands = read_input(input, parse_input);
|
||||
let mut cubes = Vec::new();
|
||||
let mut new_cubes = Vec::new();
|
||||
|
||||
for (state, cube) in commands {
|
||||
cubes.retain(|existing: &Cuboid| existing.retain_nonoverlapping(&cube, &mut new_cubes));
|
||||
|
||||
// Add new cubes to the end
|
||||
cubes.append(&mut new_cubes);
|
||||
|
||||
if state {
|
||||
cubes.push(cube);
|
||||
}
|
||||
}
|
||||
|
||||
cubes.iter().map(Cuboid::volume).sum::<i64>().to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_implementation;
|
||||
|
||||
use super::*;
|
||||
|
||||
const SAMPLE1: &[u8] = include_bytes!("samples/22.1.txt");
|
||||
const SAMPLE2: &[u8] = include_bytes!("samples/22.2.txt");
|
||||
|
||||
#[test]
|
||||
fn test_overlap() {
|
||||
let cube_a = Cuboid {
|
||||
lower: [1, 1, 1],
|
||||
upper: [4, 4, 4],
|
||||
};
|
||||
|
||||
let cube_b = Cuboid {
|
||||
lower: [2, 2, 2],
|
||||
upper: [3, 3, 3],
|
||||
};
|
||||
|
||||
let mut new_cubes = Vec::new();
|
||||
|
||||
// B is fully inside A so it should overlap and the result should be empty
|
||||
assert!(!cube_b.retain_nonoverlapping(&cube_a, &mut new_cubes));
|
||||
assert_eq!(new_cubes, Vec::new());
|
||||
|
||||
// In the reverse case, we should have lots of new cubes
|
||||
assert!(!cube_a.retain_nonoverlapping(&cube_b, &mut new_cubes));
|
||||
assert_eq!(new_cubes.len(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE1, 590784);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE2, 2758514936282235u64);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,451 @@
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::io::Read;
|
||||
use std::mem::swap;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use crate::common::LineIter;
|
||||
|
||||
type Item<const S: usize> = (u32, State<S>);
|
||||
type Todo<const S: usize> = BinaryHeap<Reverse<Item<S>>>;
|
||||
type Visited<const S: usize> = HashMap<State<S>, u32>;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
|
||||
enum Pod {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
impl Pod {
|
||||
pub fn cost(self) -> u32 {
|
||||
match self {
|
||||
Pod::A => 1,
|
||||
Pod::B => 10,
|
||||
Pod::C => 100,
|
||||
Pod::D => 1000,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dest(self) -> usize {
|
||||
self as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<usize> for Pod {
|
||||
type Error = usize;
|
||||
|
||||
fn try_from(index: usize) -> Result<Self, Self::Error> {
|
||||
match index {
|
||||
0 => Ok(Pod::A),
|
||||
1 => Ok(Pod::B),
|
||||
2 => Ok(Pod::C),
|
||||
3 => Ok(Pod::D),
|
||||
_ => Err(index),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<char> for Pod {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(c: char) -> Result<Self, Self::Error> {
|
||||
match c {
|
||||
'A' => Ok(Pod::A),
|
||||
'B' => Ok(Pod::B),
|
||||
'C' => Ok(Pod::C),
|
||||
'D' => Ok(Pod::D),
|
||||
_ => Err("Invalid pod"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
||||
struct State<const S: usize> {
|
||||
hallway: [Option<Pod>; 11],
|
||||
rooms: [[Option<Pod>; S]; 4],
|
||||
}
|
||||
|
||||
fn room_hallway_pos(room: usize) -> usize {
|
||||
room * 2 + 2
|
||||
}
|
||||
|
||||
fn abs_delta(a: usize, b: usize) -> usize {
|
||||
if a < b {
|
||||
b - a
|
||||
} else {
|
||||
a - b
|
||||
}
|
||||
}
|
||||
|
||||
impl<const S: usize> State<S> {
|
||||
const VALID_HALLWAY_POS: [usize; 7] = [0, 1, 3, 5, 7, 9, 10];
|
||||
|
||||
pub fn is_done(&self) -> bool {
|
||||
self == &State {
|
||||
hallway: Default::default(),
|
||||
rooms: [
|
||||
[Some(Pod::A); S],
|
||||
[Some(Pod::B); S],
|
||||
[Some(Pod::C); S],
|
||||
[Some(Pod::D); S],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn add_to_queue(self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
||||
let entry = visited.entry(self.clone());
|
||||
|
||||
if matches!(&entry, Entry::Occupied(entry) if *entry.get() <= cost) {
|
||||
// Already got a better one
|
||||
return;
|
||||
}
|
||||
|
||||
// nightly only :'(
|
||||
// entry.insert(cost);
|
||||
*entry.or_default() = cost;
|
||||
|
||||
todo.push(Reverse((cost + self.estimate(), self)))
|
||||
}
|
||||
|
||||
fn estimate(&self) -> u32 {
|
||||
// A* estimate. For every entry that is not already "at rest", the cost is the cost
|
||||
// required to get it to the top of its intended room.
|
||||
|
||||
// Cost to enter the hole for all pods that still need to
|
||||
let enter_estimate: u32 = self
|
||||
.rooms
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, room)| {
|
||||
let pod = Pod::try_from(index).unwrap();
|
||||
|
||||
room.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.skip_while(|&(_, &entry)| entry == Some(pod))
|
||||
.map(|(index, _)| index as u32 + 1)
|
||||
.sum::<u32>()
|
||||
* pod.cost()
|
||||
})
|
||||
.sum();
|
||||
|
||||
// Cost for all of the hallway to move to above their intended rooms
|
||||
let hallway_estimate: u32 = self
|
||||
.hallway
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(pos, &pod)| {
|
||||
let pod = pod?;
|
||||
|
||||
let destination_pos = room_hallway_pos(pod.dest());
|
||||
|
||||
Some(abs_delta(pos, destination_pos) as u32 * pod.cost())
|
||||
})
|
||||
.sum();
|
||||
|
||||
// Cost to move out of the room and above the correct rooms
|
||||
let rooms_estimate: u32 = self
|
||||
.rooms
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(room_index, room)| {
|
||||
let hallway_pos = room_hallway_pos(room_index);
|
||||
|
||||
room.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.skip_while(|&(_, &entry)| {
|
||||
entry.map(|pod| pod.dest() == room_index).unwrap_or(false)
|
||||
})
|
||||
.filter_map(|(room_pos, &pod)| {
|
||||
let pod = pod?;
|
||||
|
||||
let destination_pos = room_hallway_pos(pod.dest());
|
||||
|
||||
let steps = 1 + room_pos + abs_delta(hallway_pos, destination_pos).max(2);
|
||||
|
||||
Some(steps as u32 * pod.cost())
|
||||
})
|
||||
.sum::<u32>()
|
||||
})
|
||||
.sum();
|
||||
|
||||
enter_estimate + hallway_estimate + rooms_estimate
|
||||
}
|
||||
|
||||
pub fn generate_next(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
||||
self.room_to_hallway(cost, todo, visited);
|
||||
self.hallway_to_room(cost, todo, visited);
|
||||
}
|
||||
|
||||
fn room_to_hallway(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
||||
for (index, room) in self.rooms.iter().enumerate() {
|
||||
// Check if we even want to move anything out of this room
|
||||
if room
|
||||
.iter()
|
||||
.all(|entry| entry.map(|pod| pod.dest() == index).unwrap_or(true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let (pos, pod) = room
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(pos, entry)| entry.map(|pod| (pos, pod)))
|
||||
.unwrap(); // Safe unwrap, we know it exists from above.
|
||||
|
||||
let base_cost = 1 + pos;
|
||||
let hallway_pos = room_hallway_pos(index);
|
||||
|
||||
let mut queue_new = |new_pos, new_cost| {
|
||||
let mut new_state = self.clone();
|
||||
swap(
|
||||
&mut new_state.hallway[new_pos],
|
||||
&mut new_state.rooms[index][pos],
|
||||
);
|
||||
|
||||
new_state.add_to_queue(new_cost + cost, todo, visited)
|
||||
};
|
||||
|
||||
// Check positions to the left
|
||||
for new_pos in (0..hallway_pos).rev() {
|
||||
if self.hallway[new_pos].is_some() {
|
||||
// Hit an occupied room
|
||||
break;
|
||||
}
|
||||
|
||||
if !Self::VALID_HALLWAY_POS.contains(&new_pos) {
|
||||
// Not allowed to stop here
|
||||
continue;
|
||||
}
|
||||
|
||||
let new_cost = (base_cost + hallway_pos - new_pos) as u32 * pod.cost();
|
||||
queue_new(new_pos, new_cost);
|
||||
}
|
||||
|
||||
// And to the right
|
||||
for new_pos in hallway_pos..self.hallway.len() {
|
||||
if self.hallway[new_pos].is_some() {
|
||||
// Hit an occupied room
|
||||
break;
|
||||
}
|
||||
|
||||
if !Self::VALID_HALLWAY_POS.contains(&new_pos) {
|
||||
// Not allowed to stop here
|
||||
continue;
|
||||
}
|
||||
|
||||
let new_cost = (base_cost + new_pos - hallway_pos) as u32 * pod.cost();
|
||||
queue_new(new_pos, new_cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hallway_to_room(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
||||
for (pos, pod) in self
|
||||
.hallway
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(pos, pod)| pod.map(|pod| (pos, pod)))
|
||||
{
|
||||
let room = pod.dest();
|
||||
let new_hallway_pos = room_hallway_pos(room);
|
||||
|
||||
// Check if the path is free
|
||||
let in_between = if new_hallway_pos < pos {
|
||||
&self.hallway[(new_hallway_pos + 1)..pos]
|
||||
} else {
|
||||
&self.hallway[(pos + 1)..new_hallway_pos]
|
||||
};
|
||||
|
||||
if in_between.iter().any(Option::is_some) {
|
||||
// Something's in the way
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if we can move into the room
|
||||
if self.rooms[room]
|
||||
.iter()
|
||||
.copied()
|
||||
.flatten()
|
||||
.any(|other| other != pod)
|
||||
{
|
||||
// Scared of other pods
|
||||
continue;
|
||||
}
|
||||
|
||||
let room_pos = if let Some(pos) = self.rooms[room].iter().rposition(Option::is_none) {
|
||||
pos
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let new_cost = (abs_delta(pos, new_hallway_pos) + room_pos + 1) as u32 * pod.cost();
|
||||
let mut new_state = self.clone();
|
||||
swap(
|
||||
&mut new_state.hallway[pos],
|
||||
&mut new_state.rooms[room][room_pos],
|
||||
);
|
||||
new_state.add_to_queue(cost + new_cost, todo, visited);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve(&self) -> u32 {
|
||||
let mut todo = Todo::new();
|
||||
|
||||
let mut visited = HashMap::new();
|
||||
visited.insert(self.clone(), 0);
|
||||
|
||||
todo.push(Reverse((self.estimate(), self.clone())));
|
||||
|
||||
while let Some(Reverse((_, state))) = todo.pop() {
|
||||
let cost = *visited.get(&state).unwrap_or(&0);
|
||||
|
||||
if state.is_done() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
state.generate_next(cost, &mut todo, &mut visited);
|
||||
}
|
||||
|
||||
panic!("No route found!")
|
||||
}
|
||||
}
|
||||
|
||||
impl<const S: usize> Display for State<S> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let helper = |opt_pod| match opt_pod {
|
||||
Some(Pod::A) => 'A',
|
||||
Some(Pod::B) => 'B',
|
||||
Some(Pod::C) => 'C',
|
||||
Some(Pod::D) => 'D',
|
||||
None => '.',
|
||||
};
|
||||
writeln!(f, "#############")?;
|
||||
write!(f, "#")?;
|
||||
|
||||
for entry in self.hallway {
|
||||
write!(f, "{}", helper(entry))?;
|
||||
}
|
||||
writeln!(f, "#")?;
|
||||
|
||||
for i in 0..S {
|
||||
writeln!(
|
||||
f,
|
||||
" #{}#{}#{}#{}#",
|
||||
helper(self.rooms[0][i]),
|
||||
helper(self.rooms[1][i]),
|
||||
helper(self.rooms[2][i]),
|
||||
helper(self.rooms[3][i])
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(f, " #########")
|
||||
}
|
||||
}
|
||||
|
||||
fn read_input(input: &mut dyn Read) -> State<2> {
|
||||
let mut reader = LineIter::new(input);
|
||||
let mut state = State {
|
||||
hallway: Default::default(),
|
||||
rooms: Default::default(),
|
||||
};
|
||||
|
||||
let _ = reader.next();
|
||||
let _ = reader.next();
|
||||
|
||||
let mut helper = |idx: usize| {
|
||||
reader
|
||||
.next()
|
||||
.unwrap()
|
||||
.chars()
|
||||
.filter_map(|c| Pod::try_from(c).ok())
|
||||
.zip(&mut state.rooms)
|
||||
.for_each(|(pod, room)| room[idx] = Some(pod))
|
||||
};
|
||||
|
||||
helper(0);
|
||||
helper(1);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
let state = read_input(input);
|
||||
|
||||
state.solve().to_string()
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let state2 = read_input(input);
|
||||
|
||||
let state4 = State {
|
||||
hallway: Default::default(),
|
||||
rooms: [
|
||||
[
|
||||
state2.rooms[0][0],
|
||||
Some(Pod::D),
|
||||
Some(Pod::D),
|
||||
state2.rooms[0][1],
|
||||
],
|
||||
[
|
||||
state2.rooms[1][0],
|
||||
Some(Pod::C),
|
||||
Some(Pod::B),
|
||||
state2.rooms[1][1],
|
||||
],
|
||||
[
|
||||
state2.rooms[2][0],
|
||||
Some(Pod::B),
|
||||
Some(Pod::A),
|
||||
state2.rooms[2][1],
|
||||
],
|
||||
[
|
||||
state2.rooms[3][0],
|
||||
Some(Pod::A),
|
||||
Some(Pod::C),
|
||||
state2.rooms[3][1],
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
state4.solve().to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::test_implementation;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/23.txt");
|
||||
|
||||
#[test]
|
||||
fn test_is_done() {
|
||||
let state = State {
|
||||
hallway: Default::default(),
|
||||
rooms: [
|
||||
[Some(Pod::A); 2],
|
||||
[Some(Pod::B); 2],
|
||||
[Some(Pod::C); 2],
|
||||
[Some(Pod::D); 2],
|
||||
],
|
||||
};
|
||||
|
||||
assert!(state.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 12521);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE, 44169);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,159 @@
|
||||
//! Very input-specific reverse-engineered solution
|
||||
//!
|
||||
//! # General implementation
|
||||
//!
|
||||
//! The code in the examples is a series of 14 times this:
|
||||
//!
|
||||
//! ```txt
|
||||
//! inp w -> read digit
|
||||
//! mul x 0
|
||||
//! add x z
|
||||
//! mod x 26 -> x = z % 26
|
||||
//! div z $A -> pop Z (see below)
|
||||
//! add x $B
|
||||
//! eql x w -> x = ((z + $B) == w)
|
||||
//! eql x 0 -> x = ((z + $B) != w)
|
||||
//! mul y 0
|
||||
//! add y 25
|
||||
//! mul y x
|
||||
//! add y 1 -> if x { 26 } else { 1 }
|
||||
//! mul z y -> if x { z *= 26 } (push z, see below)
|
||||
//! mul y 0
|
||||
//! add y w
|
||||
//! add y $C -> y = w + $C
|
||||
//! mul y x
|
||||
//! add z y -> if x { z += w + $C }
|
||||
//! ```
|
||||
//!
|
||||
//! `$A` is either `1` or `26` which we can translate to a bool `$A == 26` for convenience. This
|
||||
//! simplifies to the following rust.
|
||||
//!
|
||||
//! ```
|
||||
//! fn validate<const A: bool, const B: i32, const C: i32>(mut z: i32, digit: i32) -> i32 {
|
||||
//! let x = (z % 26 + B) != digit;
|
||||
//! if A {
|
||||
//! z /= 26;
|
||||
//! }
|
||||
//!
|
||||
//! if x {
|
||||
//! z = 26 * z + digit + C;
|
||||
//! }
|
||||
//!
|
||||
//! z
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! In human terms, `z` is used to hold a base 26 number. When `$A` is `true`, we pop off the least
|
||||
//! significant digit by dividing by 26. Then, depending on whether `(z + $B) % 26` is equal to our
|
||||
//! digit, we push `digit + $C`. Ideally, we should pop as often as we push in order to arrive at `z
|
||||
//! == 0` in the end. The input contains 7 pops, so we want each of those to not push.
|
||||
//!
|
||||
//! To solve this problem, we use a backtracking memoizing algorithm, where we cancel every sequence
|
||||
//! that fails to pop at some point. A pop is failed whenever we execute a validation pop where we
|
||||
//! can pop if `x` happened to be set to `0` at the time of the check. We can memoize this over the
|
||||
//! running value of `z`.
|
||||
//!
|
||||
//! This implementation probably doesn't work on other people's input; to fix it, you'll want to
|
||||
//! update the `parse_step` function. Good luck with that.
|
||||
use std::collections::HashMap;
|
||||
use std::io::Read;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::delimited;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::read_input;
|
||||
|
||||
type Cache = HashMap<(usize, i32), Option<i64>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Step(bool, i32, i32);
|
||||
|
||||
impl Step {
|
||||
fn evaluate(&self, digit: i32, z: i32) -> Option<i32> {
|
||||
if self.0 {
|
||||
(z % 26 + self.1 == digit).then(|| z / 26)
|
||||
} else {
|
||||
Some(z * 26 + digit + self.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
fn parse_step(input: &[u8]) -> IResult<&[u8], Step> {
|
||||
use nom::character::complete::i32;
|
||||
|
||||
let parse_pop = preceded(
|
||||
tag("inp w\nmul x 0\nadd x z\nmod x 26\ndiv z "),
|
||||
alt((map(tag("1"), |_| false), map(tag("26"), |_| true))),
|
||||
);
|
||||
|
||||
let parse_a = preceded(tag("\nadd x "), i32);
|
||||
|
||||
let parse_b = delimited(
|
||||
tag("\neql x w\neql x 0\nmul y 0\nadd y 25\nmul y x\nadd y 1\nmul z y\nmul y 0\nadd y w\nadd y "),
|
||||
i32,
|
||||
tag("\nmul y x\nadd z y"),
|
||||
);
|
||||
|
||||
map(tuple((parse_pop, parse_a, parse_b)), |(pop, a, b)| {
|
||||
Step(pop, a, b)
|
||||
})(input)
|
||||
}
|
||||
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Step>> {
|
||||
separated_list1(newline, parse_step)(input)
|
||||
}
|
||||
|
||||
fn optimize(
|
||||
current: usize,
|
||||
steps: &[Step],
|
||||
digits: &[i32],
|
||||
z: i32,
|
||||
cache: &mut Cache,
|
||||
) -> Option<i64> {
|
||||
if current >= steps.len() {
|
||||
return (z == 0).then(|| 0);
|
||||
}
|
||||
|
||||
if let Some(&memoized) = cache.get(&(current, z)) {
|
||||
return memoized;
|
||||
}
|
||||
|
||||
let result = digits.iter().find_map(|&digit| {
|
||||
let z = steps[current].evaluate(digit, z)?;
|
||||
let result = optimize(current + 1, steps, digits, z, cache)?;
|
||||
|
||||
Some(result + digit as i64 * 10i64.pow(13 - current as u32))
|
||||
});
|
||||
cache.insert((current, z), result);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn parts_common(input: &mut dyn Read, digits: &[i32]) -> String {
|
||||
let steps = read_input(input, parse_input);
|
||||
|
||||
let mut cache = Cache::new();
|
||||
|
||||
optimize(0, &steps, digits, 0, &mut cache)
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
let digits = [9, 8, 7, 6, 5, 4, 3, 2, 1];
|
||||
|
||||
parts_common(input, &digits)
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let digits = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
parts_common(input, &digits)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,85 @@
|
||||
use std::io::Read;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
fn read_input(input: &mut dyn Read) -> (usize, Vec<u8>) {
|
||||
let mut result = Vec::new();
|
||||
input.read_to_end(&mut result).unwrap();
|
||||
|
||||
let width = result.iter().position(|&c| c == b'\n').unwrap();
|
||||
result.retain(|c| !c.is_ascii_whitespace());
|
||||
|
||||
(width, result)
|
||||
}
|
||||
|
||||
fn advance(width: usize, state: &mut [u8]) -> bool {
|
||||
debug_assert_eq!(state.len() % width, 0);
|
||||
let mut changes = false;
|
||||
|
||||
// Move the eastbound herd
|
||||
for src in state.chunks_exact_mut(width) {
|
||||
let swap_last = src[0] == b'.' && src[width - 1] == b'>';
|
||||
let mut x = 0;
|
||||
|
||||
while x < src.len() - 1 {
|
||||
if src[x] == b'>' && src[x + 1] == b'.' {
|
||||
src.swap(x, x + 1);
|
||||
changes = true;
|
||||
x += 2;
|
||||
} else {
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if swap_last {
|
||||
src.swap(0, width - 1);
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Then move the southbound herd. Need to do by column because of the first entry special case
|
||||
for x in 0..width {
|
||||
let last_index = state.len() - width + x;
|
||||
let swap_last = state[x] == b'.' && state[last_index] == b'v';
|
||||
|
||||
let mut offset = x;
|
||||
|
||||
while offset < state.len() - width {
|
||||
if state[offset] == b'v' && state[offset + width] == b'.' {
|
||||
state.swap(offset, offset + width);
|
||||
changes = true;
|
||||
offset += 2 * width;
|
||||
} else {
|
||||
offset += width;
|
||||
}
|
||||
}
|
||||
|
||||
if swap_last {
|
||||
state.swap(x, last_index);
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
changes
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
let (width, mut state) = read_input(input);
|
||||
|
||||
(1..)
|
||||
.find(|_| !advance(width, &mut state))
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::test_implementation;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/25.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 58);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ pub fn get_implementation(day: usize, part2: bool) -> Solution {
|
||||
|
||||
#[cfg(test)]
|
||||
fn test_implementation(solution: Solution, data: &[u8], answer: impl ToString) {
|
||||
let result = solution(&mut data.as_ref());
|
||||
let result = solution(&mut &*data);
|
||||
|
||||
assert_eq!(answer.to_string(), result);
|
||||
}
|
||||
|
||||
7
2021/src/samples/20.txt
Normal file
7
2021/src/samples/20.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
|
||||
|
||||
#..#.
|
||||
#....
|
||||
##..#
|
||||
..#..
|
||||
..###
|
||||
2
2021/src/samples/21.txt
Normal file
2
2021/src/samples/21.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Player 1 starting position: 4
|
||||
Player 2 starting position: 8
|
||||
22
2021/src/samples/22.1.txt
Normal file
22
2021/src/samples/22.1.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
on x=-20..26,y=-36..17,z=-47..7
|
||||
on x=-20..33,y=-21..23,z=-26..28
|
||||
on x=-22..28,y=-29..23,z=-38..16
|
||||
on x=-46..7,y=-6..46,z=-50..-1
|
||||
on x=-49..1,y=-3..46,z=-24..28
|
||||
on x=2..47,y=-22..22,z=-23..27
|
||||
on x=-27..23,y=-28..26,z=-21..29
|
||||
on x=-39..5,y=-6..47,z=-3..44
|
||||
on x=-30..21,y=-8..43,z=-13..34
|
||||
on x=-22..26,y=-27..20,z=-29..19
|
||||
off x=-48..-32,y=26..41,z=-47..-37
|
||||
on x=-12..35,y=6..50,z=-50..-2
|
||||
off x=-48..-32,y=-32..-16,z=-15..-5
|
||||
on x=-18..26,y=-33..15,z=-7..46
|
||||
off x=-40..-22,y=-38..-28,z=23..41
|
||||
on x=-16..35,y=-41..10,z=-47..6
|
||||
off x=-32..-23,y=11..30,z=-14..3
|
||||
on x=-49..-5,y=-3..45,z=-29..18
|
||||
off x=18..30,y=-20..-8,z=-3..13
|
||||
on x=-41..9,y=-7..43,z=-33..15
|
||||
on x=-54112..-39298,y=-85059..-49293,z=-27449..7877
|
||||
on x=967..23432,y=45373..81175,z=27513..53682
|
||||
60
2021/src/samples/22.2.txt
Normal file
60
2021/src/samples/22.2.txt
Normal file
@@ -0,0 +1,60 @@
|
||||
on x=-5..47,y=-31..22,z=-19..33
|
||||
on x=-44..5,y=-27..21,z=-14..35
|
||||
on x=-49..-1,y=-11..42,z=-10..38
|
||||
on x=-20..34,y=-40..6,z=-44..1
|
||||
off x=26..39,y=40..50,z=-2..11
|
||||
on x=-41..5,y=-41..6,z=-36..8
|
||||
off x=-43..-33,y=-45..-28,z=7..25
|
||||
on x=-33..15,y=-32..19,z=-34..11
|
||||
off x=35..47,y=-46..-34,z=-11..5
|
||||
on x=-14..36,y=-6..44,z=-16..29
|
||||
on x=-57795..-6158,y=29564..72030,z=20435..90618
|
||||
on x=36731..105352,y=-21140..28532,z=16094..90401
|
||||
on x=30999..107136,y=-53464..15513,z=8553..71215
|
||||
on x=13528..83982,y=-99403..-27377,z=-24141..23996
|
||||
on x=-72682..-12347,y=18159..111354,z=7391..80950
|
||||
on x=-1060..80757,y=-65301..-20884,z=-103788..-16709
|
||||
on x=-83015..-9461,y=-72160..-8347,z=-81239..-26856
|
||||
on x=-52752..22273,y=-49450..9096,z=54442..119054
|
||||
on x=-29982..40483,y=-108474..-28371,z=-24328..38471
|
||||
on x=-4958..62750,y=40422..118853,z=-7672..65583
|
||||
on x=55694..108686,y=-43367..46958,z=-26781..48729
|
||||
on x=-98497..-18186,y=-63569..3412,z=1232..88485
|
||||
on x=-726..56291,y=-62629..13224,z=18033..85226
|
||||
on x=-110886..-34664,y=-81338..-8658,z=8914..63723
|
||||
on x=-55829..24974,y=-16897..54165,z=-121762..-28058
|
||||
on x=-65152..-11147,y=22489..91432,z=-58782..1780
|
||||
on x=-120100..-32970,y=-46592..27473,z=-11695..61039
|
||||
on x=-18631..37533,y=-124565..-50804,z=-35667..28308
|
||||
on x=-57817..18248,y=49321..117703,z=5745..55881
|
||||
on x=14781..98692,y=-1341..70827,z=15753..70151
|
||||
on x=-34419..55919,y=-19626..40991,z=39015..114138
|
||||
on x=-60785..11593,y=-56135..2999,z=-95368..-26915
|
||||
on x=-32178..58085,y=17647..101866,z=-91405..-8878
|
||||
on x=-53655..12091,y=50097..105568,z=-75335..-4862
|
||||
on x=-111166..-40997,y=-71714..2688,z=5609..50954
|
||||
on x=-16602..70118,y=-98693..-44401,z=5197..76897
|
||||
on x=16383..101554,y=4615..83635,z=-44907..18747
|
||||
off x=-95822..-15171,y=-19987..48940,z=10804..104439
|
||||
on x=-89813..-14614,y=16069..88491,z=-3297..45228
|
||||
on x=41075..99376,y=-20427..49978,z=-52012..13762
|
||||
on x=-21330..50085,y=-17944..62733,z=-112280..-30197
|
||||
on x=-16478..35915,y=36008..118594,z=-7885..47086
|
||||
off x=-98156..-27851,y=-49952..43171,z=-99005..-8456
|
||||
off x=2032..69770,y=-71013..4824,z=7471..94418
|
||||
on x=43670..120875,y=-42068..12382,z=-24787..38892
|
||||
off x=37514..111226,y=-45862..25743,z=-16714..54663
|
||||
off x=25699..97951,y=-30668..59918,z=-15349..69697
|
||||
off x=-44271..17935,y=-9516..60759,z=49131..112598
|
||||
on x=-61695..-5813,y=40978..94975,z=8655..80240
|
||||
off x=-101086..-9439,y=-7088..67543,z=33935..83858
|
||||
off x=18020..114017,y=-48931..32606,z=21474..89843
|
||||
off x=-77139..10506,y=-89994..-18797,z=-80..59318
|
||||
off x=8476..79288,y=-75520..11602,z=-96624..-24783
|
||||
on x=-47488..-1262,y=24338..100707,z=16292..72967
|
||||
off x=-84341..13987,y=2429..92914,z=-90671..-1318
|
||||
off x=-37810..49457,y=-71013..-7894,z=-105357..-13188
|
||||
off x=-27365..46395,y=31009..98017,z=15428..76570
|
||||
off x=-70369..-16548,y=22648..78696,z=-1892..86821
|
||||
on x=-53470..21291,y=-120233..-33476,z=-44150..38147
|
||||
off x=-93533..-4276,y=-16170..68771,z=-104985..-24507
|
||||
5
2021/src/samples/23.txt
Normal file
5
2021/src/samples/23.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
#############
|
||||
#...........#
|
||||
###B#C#B#D###
|
||||
#A#D#C#A#
|
||||
#########
|
||||
9
2021/src/samples/25.txt
Normal file
9
2021/src/samples/25.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
v...>>.vv>
|
||||
.vv>>.vv..
|
||||
>>.>v>...v
|
||||
>>v>>.>.v.
|
||||
v>v.vv.v..
|
||||
>.>>..v...
|
||||
.vv..>.>v.
|
||||
v.v..>>v.v
|
||||
....v..v.>
|
||||
26
2022/Cargo.toml
Normal file
26
2022/Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "aoc_2022"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.66"
|
||||
clap = { version = "4.0.19", features = ["derive"] }
|
||||
nom = "7.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.4.0"
|
||||
|
||||
[profile.release]
|
||||
# Keep debug information in release for better flamegraphs
|
||||
debug = true
|
||||
|
||||
[profile.bench]
|
||||
# And same for benchmarking
|
||||
debug = true
|
||||
|
||||
[[bench]]
|
||||
name = "days"
|
||||
harness = false
|
||||
20
2022/README.md
Normal file
20
2022/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Advent of Code 2022
|
||||
|
||||
Another year and another Advent of Code in Rust. Because last year went so well, this time we'll be
|
||||
aiming for a total time of under 250ms.
|
||||
|
||||
```console
|
||||
$ target/release/aoc_2022 --help
|
||||
Advent of Code 2022 runner
|
||||
|
||||
Usage: aoc_2022 [OPTIONS] <DAY>
|
||||
|
||||
Arguments:
|
||||
<DAY> Which day to run
|
||||
|
||||
Options:
|
||||
-t, --time Print time taken
|
||||
-2, --part2 Run part 2 instead of part 1
|
||||
-i, --input <INPUT> Read input from the given file instead of stdin
|
||||
-h, --help Print help information
|
||||
```
|
||||
46
2022/benches/days.rs
Normal file
46
2022/benches/days.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
use aoc_2022::get_implementation;
|
||||
use criterion::criterion_group;
|
||||
use criterion::criterion_main;
|
||||
use criterion::BenchmarkId;
|
||||
use criterion::Criterion;
|
||||
|
||||
/// Number of days we have an implementation to benchmark
|
||||
const DAYS_IMPLEMENTED: u8 = 2;
|
||||
|
||||
fn read_input(day: u8) -> Vec<u8> {
|
||||
let input_path = format!("inputs/{:02}.txt", day);
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
File::open(input_path)
|
||||
.expect("Failed to open input file")
|
||||
.read_to_end(&mut buffer)
|
||||
.expect("Failed to read input file");
|
||||
|
||||
buffer
|
||||
}
|
||||
|
||||
pub fn benchmark_days(c: &mut Criterion) {
|
||||
for day in 1..=DAYS_IMPLEMENTED {
|
||||
let input = read_input(day);
|
||||
|
||||
let part1 = get_implementation(day, false).unwrap();
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
|
||||
b.iter(|| part1(i));
|
||||
});
|
||||
|
||||
if day < 25 {
|
||||
let part2 = get_implementation(day, true).unwrap();
|
||||
|
||||
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
|
||||
b.iter(|| part2(i));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(benches, benchmark_days);
|
||||
criterion_main!(benches);
|
||||
0
2022/inputs/.gitkeep
Normal file
0
2022/inputs/.gitkeep
Normal file
2259
2022/inputs/01.txt
Normal file
2259
2022/inputs/01.txt
Normal file
File diff suppressed because it is too large
Load Diff
2500
2022/inputs/02.txt
Normal file
2500
2022/inputs/02.txt
Normal file
File diff suppressed because it is too large
Load Diff
94
2022/src/common.rs
Normal file
94
2022/src/common.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
//! Common helper utilities to all days
|
||||
|
||||
use anyhow::Result;
|
||||
use nom::error::ErrorKind;
|
||||
use nom::error::ParseError;
|
||||
use nom::Finish;
|
||||
use nom::IResult;
|
||||
use nom::InputLength;
|
||||
use nom::Parser;
|
||||
|
||||
/// Parse input from some nom parser and return as an anyhow result
|
||||
///
|
||||
/// This method exists as a convenience because nom's errors cannot otherwise be easily converted to
|
||||
/// an anyhow error, and I don't want to keep track of custom error implementations here.
|
||||
pub fn parse_input<'a, O>(
|
||||
input: &'a [u8],
|
||||
mut parser: impl Parser<&'a [u8], O, nom::error::Error<&'a [u8]>>,
|
||||
) -> Result<O> {
|
||||
let (unparsed, output) = parser.parse(input).finish().map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"Parser error {:?} to parse at {}",
|
||||
e.code,
|
||||
String::from_utf8_lossy(e.input)
|
||||
)
|
||||
})?;
|
||||
|
||||
if !unparsed.is_empty() {
|
||||
Err(anyhow::anyhow!(
|
||||
"Not all input consumed: {}",
|
||||
String::from_utf8_lossy(unparsed)
|
||||
))
|
||||
} else {
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a parser iteratively and reduces the results using the given function. Fails if the
|
||||
/// embedded parser doesn't return at least one result.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `f`: the function to apply
|
||||
/// - `g`: the function that combines the result o `f` with previous results
|
||||
///
|
||||
/// This implementation is based on [`nom::multi::fold_many1`] with minor differences. If
|
||||
/// successful, this should probably be upstreamed.
|
||||
pub fn reduce_many1<I, O, E, F>(
|
||||
mut f: F,
|
||||
mut g: impl FnMut(O, O) -> O,
|
||||
) -> impl FnMut(I) -> IResult<I, O, E>
|
||||
where
|
||||
I: Clone + InputLength,
|
||||
E: ParseError<I>,
|
||||
F: Parser<I, O, E>,
|
||||
{
|
||||
// Cannot delegate to fold_many0 because that would make the function FnOnce rather than FnMut,
|
||||
// since it would transfer ownership of the embedded parser to fold_many0.
|
||||
move |i: I| {
|
||||
let _i = i.clone();
|
||||
match f.parse(_i) {
|
||||
Err(nom::Err::Error(_)) => {
|
||||
Err(nom::Err::Error(E::from_error_kind(i, ErrorKind::Many1)))
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
Ok((i1, mut acc)) => {
|
||||
let mut input = i1;
|
||||
|
||||
loop {
|
||||
let _input = input.clone();
|
||||
let len = input.input_len();
|
||||
match f.parse(_input) {
|
||||
Err(nom::Err::Error(_)) => {
|
||||
break;
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
Ok((i, o)) => {
|
||||
// infinite loop check: the parser must always consume
|
||||
if i.input_len() == len {
|
||||
return Err(nom::Err::Failure(E::from_error_kind(
|
||||
i,
|
||||
ErrorKind::Many1,
|
||||
)));
|
||||
}
|
||||
|
||||
acc = g(acc, o);
|
||||
input = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((input, acc))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
2022/src/day01.rs
Normal file
55
2022/src/day01.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use std::ops::Add;
|
||||
|
||||
use anyhow::Result;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::opt;
|
||||
use nom::multi::separated_list0;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
use crate::common::reduce_many1;
|
||||
|
||||
fn parse_elf(input: &[u8]) -> IResult<&[u8], i32> {
|
||||
reduce_many1(terminated(nom::character::complete::i32, newline), Add::add)(input)
|
||||
}
|
||||
|
||||
fn parse_max(input: &[u8]) -> IResult<&[u8], i32> {
|
||||
reduce_many1(terminated(parse_elf, opt(newline)), Ord::max)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let result = parse_input(input, parse_max)?.to_string();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn parse_elf_list(input: &[u8]) -> IResult<&[u8], Vec<i32>> {
|
||||
separated_list0(newline, parse_elf)(input)
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let mut elves = parse_input(input, parse_elf_list)?;
|
||||
|
||||
let (first, third, _) = elves.select_nth_unstable_by(2, |a, b| Ord::cmp(b, a));
|
||||
|
||||
let result = first[1] + first[0] + *third;
|
||||
|
||||
Ok(result.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/01.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "24000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "45000");
|
||||
}
|
||||
}
|
||||
129
2022/src/day02.rs
Normal file
129
2022/src/day02.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use std::ops::Add;
|
||||
|
||||
use anyhow::Result;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::map_res;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
use crate::common::reduce_many1;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
enum Rps {
|
||||
Rock,
|
||||
Paper,
|
||||
Scissors,
|
||||
}
|
||||
|
||||
impl Rps {
|
||||
/// Score we get by playing this move
|
||||
fn score(self) -> u32 {
|
||||
match self {
|
||||
Rps::Rock => 1,
|
||||
Rps::Paper => 2,
|
||||
Rps::Scissors => 3,
|
||||
}
|
||||
}
|
||||
|
||||
/// Score we get from the result from playing given other
|
||||
fn score_against(self, other: Self) -> u32 {
|
||||
match (self, other) {
|
||||
(a, b) if a == b => 3,
|
||||
(Rps::Rock, Rps::Paper) | (Rps::Paper, Rps::Scissors) | (Rps::Scissors, Rps::Rock) => 0,
|
||||
_ => 6,
|
||||
}
|
||||
}
|
||||
|
||||
/// Score if the result is according to the instruction
|
||||
fn score_result(self) -> u32 {
|
||||
match self {
|
||||
Rps::Rock => 0, // Rock is lose
|
||||
Rps::Paper => 3, // Paper is draw
|
||||
Rps::Scissors => 6, // Scissors is win
|
||||
}
|
||||
}
|
||||
|
||||
/// Move we need to achieve the result indicated by self
|
||||
fn needed(self, other: Self) -> Self {
|
||||
match (self, other) {
|
||||
(Rps::Paper, other) => other,
|
||||
(Rps::Rock, Rps::Rock) => Rps::Scissors,
|
||||
(Rps::Rock, Rps::Paper) => Rps::Rock,
|
||||
(Rps::Rock, Rps::Scissors) => Rps::Paper,
|
||||
(Rps::Scissors, Rps::Rock) => Rps::Paper,
|
||||
(Rps::Scissors, Rps::Paper) => Rps::Scissors,
|
||||
(Rps::Scissors, Rps::Scissors) => Rps::Rock,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Rps {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
b'A' | b'X' => Ok(Rps::Rock),
|
||||
b'B' | b'Y' => Ok(Rps::Paper),
|
||||
b'C' | b'Z' => Ok(Rps::Scissors),
|
||||
_ => Err(anyhow::anyhow!("Invalid RPS: {value}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line(input: &[u8]) -> IResult<&[u8], (Rps, Rps)> {
|
||||
fn parse_rps(input: &[u8]) -> IResult<&[u8], Rps> {
|
||||
// Note: alpha1 also sort of works but is significantly slower
|
||||
map_res(nom::bytes::complete::take(1usize), |v: &[u8]| {
|
||||
Rps::try_from(v[0])
|
||||
})(input)
|
||||
}
|
||||
|
||||
terminated(
|
||||
separated_pair(parse_rps, nom::character::complete::char(' '), parse_rps),
|
||||
newline,
|
||||
)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
parse_input(
|
||||
input,
|
||||
reduce_many1(
|
||||
map(parse_line, |(them, us)| us.score() + us.score_against(them)),
|
||||
Add::add,
|
||||
),
|
||||
)
|
||||
.map(|sum| sum.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
parse_input(
|
||||
input,
|
||||
reduce_many1(
|
||||
map(parse_line, |(them, us)| {
|
||||
us.score_result() + us.needed(them).score()
|
||||
}),
|
||||
Add::add,
|
||||
),
|
||||
)
|
||||
.map(|sum| sum.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/02.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "15")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "12")
|
||||
}
|
||||
}
|
||||
9
2022/src/day03.rs
Normal file
9
2022/src/day03.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day04.rs
Normal file
9
2022/src/day04.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day05.rs
Normal file
9
2022/src/day05.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day06.rs
Normal file
9
2022/src/day06.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day07.rs
Normal file
9
2022/src/day07.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day08.rs
Normal file
9
2022/src/day08.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day09.rs
Normal file
9
2022/src/day09.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day10.rs
Normal file
9
2022/src/day10.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day11.rs
Normal file
9
2022/src/day11.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day12.rs
Normal file
9
2022/src/day12.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day13.rs
Normal file
9
2022/src/day13.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day14.rs
Normal file
9
2022/src/day14.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day15.rs
Normal file
9
2022/src/day15.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day16.rs
Normal file
9
2022/src/day16.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day17.rs
Normal file
9
2022/src/day17.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day18.rs
Normal file
9
2022/src/day18.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day19.rs
Normal file
9
2022/src/day19.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day20.rs
Normal file
9
2022/src/day20.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day21.rs
Normal file
9
2022/src/day21.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day22.rs
Normal file
9
2022/src/day22.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day23.rs
Normal file
9
2022/src/day23.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
9
2022/src/day24.rs
Normal file
9
2022/src/day24.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
5
2022/src/day25.rs
Normal file
5
2022/src/day25.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
use anyhow::Result;
|
||||
|
||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
91
2022/src/lib.rs
Normal file
91
2022/src/lib.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use anyhow::Result;
|
||||
|
||||
mod common;
|
||||
mod day01;
|
||||
mod day02;
|
||||
mod day03;
|
||||
mod day04;
|
||||
mod day05;
|
||||
mod day06;
|
||||
mod day07;
|
||||
mod day08;
|
||||
mod day09;
|
||||
mod day10;
|
||||
mod day11;
|
||||
mod day12;
|
||||
mod day13;
|
||||
mod day14;
|
||||
mod day15;
|
||||
mod day16;
|
||||
mod day17;
|
||||
mod day18;
|
||||
mod day19;
|
||||
mod day20;
|
||||
mod day21;
|
||||
mod day22;
|
||||
mod day23;
|
||||
mod day24;
|
||||
mod day25;
|
||||
|
||||
type Solution = fn(&[u8]) -> Result<String>;
|
||||
|
||||
pub fn get_implementation(day: u8, part2: bool) -> Result<Solution> {
|
||||
if !part2 {
|
||||
match day {
|
||||
1 => Ok(day01::part1),
|
||||
2 => Ok(day02::part1),
|
||||
3 => Ok(day03::part1),
|
||||
4 => Ok(day04::part1),
|
||||
5 => Ok(day05::part1),
|
||||
6 => Ok(day06::part1),
|
||||
7 => Ok(day07::part1),
|
||||
8 => Ok(day08::part1),
|
||||
9 => Ok(day09::part1),
|
||||
10 => Ok(day10::part1),
|
||||
11 => Ok(day11::part1),
|
||||
12 => Ok(day12::part1),
|
||||
13 => Ok(day13::part1),
|
||||
14 => Ok(day14::part1),
|
||||
15 => Ok(day15::part1),
|
||||
16 => Ok(day16::part1),
|
||||
17 => Ok(day17::part1),
|
||||
18 => Ok(day18::part1),
|
||||
19 => Ok(day19::part1),
|
||||
20 => Ok(day20::part1),
|
||||
21 => Ok(day21::part1),
|
||||
22 => Ok(day22::part1),
|
||||
23 => Ok(day23::part1),
|
||||
24 => Ok(day24::part1),
|
||||
25 => Ok(day25::part1),
|
||||
_ => anyhow::bail!("Invalid day for part 1: {day}"),
|
||||
}
|
||||
} else {
|
||||
match day {
|
||||
1 => Ok(day01::part2),
|
||||
2 => Ok(day02::part2),
|
||||
3 => Ok(day03::part2),
|
||||
4 => Ok(day04::part2),
|
||||
5 => Ok(day05::part2),
|
||||
6 => Ok(day06::part2),
|
||||
7 => Ok(day07::part2),
|
||||
8 => Ok(day08::part2),
|
||||
9 => Ok(day09::part2),
|
||||
10 => Ok(day10::part2),
|
||||
11 => Ok(day11::part2),
|
||||
12 => Ok(day12::part2),
|
||||
13 => Ok(day13::part2),
|
||||
14 => Ok(day14::part2),
|
||||
15 => Ok(day15::part2),
|
||||
16 => Ok(day16::part2),
|
||||
17 => Ok(day17::part2),
|
||||
18 => Ok(day18::part2),
|
||||
19 => Ok(day19::part2),
|
||||
20 => Ok(day20::part2),
|
||||
21 => Ok(day21::part2),
|
||||
22 => Ok(day22::part2),
|
||||
23 => Ok(day23::part2),
|
||||
24 => Ok(day24::part2),
|
||||
_ => anyhow::bail!("Invalid day for part 2: {day}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
61
2022/src/main.rs
Normal file
61
2022/src/main.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::num::NonZeroU8;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
|
||||
use aoc_2022::get_implementation;
|
||||
|
||||
/// Advent of Code 2022 runner
|
||||
#[derive(Parser)]
|
||||
struct Opts {
|
||||
/// Which day to run
|
||||
day: NonZeroU8,
|
||||
|
||||
/// Print time taken
|
||||
#[clap(short, long)]
|
||||
time: bool,
|
||||
|
||||
/// Run part 2 instead of part 1
|
||||
#[clap(short = '2', long)]
|
||||
part2: bool,
|
||||
|
||||
/// Read input from the given file instead of stdin
|
||||
#[clap(short, long)]
|
||||
input: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Opts {
|
||||
fn input_data(&self) -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
if let Some(input) = &self.input {
|
||||
File::open(input)?.read_to_end(&mut buffer)?;
|
||||
} else {
|
||||
std::io::stdin().read_to_end(&mut buffer)?;
|
||||
}
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let opts: Opts = Opts::parse();
|
||||
|
||||
let input = opts.input_data()?;
|
||||
|
||||
let implementation = get_implementation(opts.day.get(), opts.part2)?;
|
||||
|
||||
let begin = Instant::now();
|
||||
let result = implementation(&input)?;
|
||||
|
||||
if opts.time {
|
||||
eprintln!("Execution time: {:?}", Instant::now().duration_since(begin));
|
||||
}
|
||||
|
||||
println!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
0
2022/src/samples/.gitkeep
Normal file
0
2022/src/samples/.gitkeep
Normal file
14
2022/src/samples/01.txt
Normal file
14
2022/src/samples/01.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000
|
||||
3
2022/src/samples/02.txt
Normal file
3
2022/src/samples/02.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
A Y
|
||||
B X
|
||||
C Z
|
||||
@@ -1,6 +1,6 @@
|
||||
# Advent of Code
|
||||
|
||||
[](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml)
|
||||
[](https://github.com/bertptrs/adventofcode/actions/workflows/2022.yml)
|
||||
|
||||
This repository contains my solutions for Advent of Code. See:
|
||||
|
||||
@@ -11,3 +11,4 @@ This repository contains my solutions for Advent of Code. See:
|
||||
- [2019 edition](./2019)
|
||||
- [2020 edition](./2020)
|
||||
- [2021 edition](./2021)
|
||||
- [2022 edition](./2022)
|
||||
|
||||
Reference in New Issue
Block a user