56 Commits

Author SHA1 Message Date
f904d050cc Reimplement day 4 2022 with ranges instead of ints 2022-12-06 07:55:54 +01:00
6802a7bf33 Refactor common parts 2022-12-04 11:18:03 +01:00
9d23e80256 Implement 2022 day 4 2022-12-04 11:14:23 +01:00
e1b3b9d179 Implement 2022 day 3 2022-12-03 20:23:14 +01:00
30d1a16075 Collect into vec for nicer vectorization 2022-12-02 09:52:09 +01:00
256d351f8e Implement day 2 2022 2022-12-02 09:06:59 +01:00
48594a75e6 Make parsers more robust 2022-12-01 11:28:59 +01:00
85a51b13c1 Implement 2022 day 1 2022-12-01 09:40:00 +01:00
2ae2d6baa8 Merge pull request #4 from bertptrs/setup-2022 2022-11-30 18:08:54 +01:00
4a55e53182 Update README and references 2022-11-24 08:23:58 +01:00
af0897300d Add caching to CI pipeline for speed 2022-11-05 16:17:47 +01:00
cabae7b1fd Convert 2021 CI to 2022 2022-11-05 16:17:47 +01:00
0635141ac6 Add skeleton for 2022 2022-11-05 16:17:47 +01:00
d9d5947c3b Replace unnecessary Vec with slice 2022-06-07 08:32:59 +02:00
cc8b4ce353 Update vulnerable dependencies
Not that this will affect anyone, but it's nice anyway.
2022-06-07 08:25:30 +02:00
0b91da04b3 Add benchmarking plots 2022-01-09 18:41:02 +01:00
dba146b299 Avoid instantiating translated sets 2022-01-09 15:45:22 +01:00
33111615be Directly infer matched pivot 2022-01-09 14:22:41 +01:00
04e8a41d98 Use pre-matching strategy
Ensure that both scanners to be matched have a set of enough distances
in common to avoid matching between groups that cannot possibly be
related.
2022-01-08 19:50:16 +01:00
36d76018ba Correct width calculation
The original worked by accident
2022-01-06 23:35:38 +01:00
4172fd0463 Slightly more efficiently pre-allocate bitsets 2022-01-06 23:22:10 +01:00
ad0b4a4659 Use running masks instead of computing one by one 2022-01-06 23:05:41 +01:00
2dab7342f8 Replace sparse map with bitset 2022-01-06 22:52:57 +01:00
edd14a0e3d Update to Clap 3.0.0! 2022-01-02 23:06:32 +01:00
4d7188e1ff Replace hashset with bitset 2022-01-02 22:38:28 +01:00
255edaca79 Implement day 24 2022-01-02 21:47:07 +01:00
8ea716cba8 Properly use TryFrom 2022-01-02 18:49:25 +01:00
601de2c565 Readability 2022-01-02 18:30:13 +01:00
894524bc81 Implement part 2
Turns out you can incorrectly implement the problem and still get the
right answer for part 1. If you then correct it, it's a lot faster.
2022-01-02 18:28:04 +01:00
f19bf28f34 Properly implemented A* estimate 2022-01-02 16:17:01 +01:00
de3a24a87c Implementation day 23 2022-01-02 16:17:01 +01:00
09b590e927 Update southbound comment 2021-12-29 15:39:20 +01:00
9dacb4c1ae Perform updates in-place 2021-12-29 15:29:21 +01:00
07e03c1630 Implement day 25 2021-12-29 15:09:43 +01:00
3accf9845d Better code reuse, almost generic over dimensions 2021-12-29 14:19:58 +01:00
fd26f58e25 Implement day 22 part 2 (and 1 again) 2021-12-29 14:07:52 +01:00
b2f9898714 Reduce code duplication 2021-12-26 12:32:07 +01:00
d757c389f0 Replace inefficient recursion with iteration 2021-12-26 11:24:45 +01:00
fd561a3e9d Clippy suggestions 2021-12-22 21:16:27 +01:00
2fcdc6b8d2 Brute force day 22 part 1 2021-12-22 21:12:15 +01:00
8a3f0f843c Finally discovered that pos != new_pos 2021-12-22 20:36:58 +01:00
23b5c39838 Add inputs day 21 2021-12-22 20:04:29 +01:00
452f6e5f14 Implement fast day 21 part 1 2021-12-21 09:35:50 +01:00
61fb240622 Avoid 2/3 hashmap lookups 2021-12-20 18:24:37 +01:00
aee25057d6 Avoid allocations 2021-12-20 18:14:36 +01:00
a98332894f Brute force implementation day 20 2021-12-20 18:08:48 +01:00
09e012c082 Add input files day 18 2021-12-19 22:55:11 +01:00
944d3e644a Filter out the worst repetition 2021-12-19 18:38:30 +01:00
d56f4ae8f8 Implement part 2 with the same brute force 2021-12-19 18:33:24 +01:00
53ca8d0043 Implement day 19 part 1
By brute force and lots of it
2021-12-19 18:16:56 +01:00
6506af879a Simplify y-hit iterator 2021-12-18 18:15:11 +01:00
101ebee505 Use dedicated iterator instead of range 2021-12-18 18:15:11 +01:00
cc81a7012b Use math instead of binary search 2021-12-18 17:21:43 +01:00
9c299f140c Tighter bounds for the range of y 2021-12-18 15:01:47 +01:00
ba1b7b693e Use reusable parser wrapper more 2021-12-18 14:54:05 +01:00
7d331f9131 Implement day 18 2021 2021-12-18 14:46:27 +01:00
85 changed files with 11279 additions and 189 deletions

View File

@@ -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

View File

@@ -4,4 +4,4 @@ version = "0.1.0"
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
[dependencies]
regex = "0.1"
regex = "1"

View File

@@ -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()

View File

@@ -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"

View File

@@ -4,4 +4,4 @@ version = "0.1.0"
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
[dependencies]
regex="^0.1"
regex="1"

View File

@@ -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"

View File

@@ -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.
![Cumulative time](./cumulative-time.svg)
![Time by day](./individual-time.svg)
[Criterion]: https://github.com/bheisler/criterion.rs

View File

@@ -7,7 +7,7 @@ use criterion::criterion_main;
use criterion::BenchmarkId;
use criterion::Criterion;
const DAYS_IMPLEMENTED: usize = 16;
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
View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

1
2021/individual-time.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

100
2021/inputs/18.txt Normal file
View File

@@ -0,0 +1,100 @@
[[3,[[6,3],[9,6]]],[6,[[0,9],[9,7]]]]
[[[3,9],[[0,8],[7,6]]],[[[7,9],1],[1,3]]]
[8,[[[9,6],[8,4]],4]]
[5,[[1,2],[3,7]]]
[[[[7,7],5],[[3,5],8]],4]
[[[5,[0,7]],3],[[5,[5,3]],[1,[9,4]]]]
[[[[3,5],[7,1]],6],[[[3,6],[5,6]],[[3,2],5]]]
[[[[2,0],[3,0]],[5,7]],[[4,4],[[9,9],[9,3]]]]
[[[[8,0],7],[[7,1],9]],[[3,[8,6]],8]]
[[6,[7,5]],[[6,8],9]]
[[[9,[1,8]],2],[[[4,0],[9,3]],1]]
[[7,[1,[3,8]]],[[4,7],[8,1]]]
[[[5,5],[[4,5],[2,9]]],[[[7,7],0],8]]
[[[[4,7],3],5],[[[4,3],[3,8]],[[6,5],5]]]
[[[[3,8],2],[1,7]],[[[3,1],4],9]]
[[[[2,1],4],[[9,5],[1,4]]],[[3,5],[[9,1],9]]]
[[[6,[1,8]],[0,0]],[9,[0,3]]]
[[[[2,2],[3,3]],[[4,8],4]],[[[6,8],4],5]]
[4,[[[7,8],[3,4]],[[3,2],9]]]
[[[9,0],3],[[[7,1],4],7]]
[[[1,4],8],[[7,5],[[8,0],[0,7]]]]
[9,[[4,6],[[2,9],1]]]
[[[[1,8],8],6],[[[2,0],6],[0,5]]]
[[[5,5],[6,4]],[[3,8],[9,[7,6]]]]
[[0,[8,[1,4]]],2]
[[[[9,5],0],5],[9,[7,5]]]
[[9,[4,8]],[[8,1],[[8,6],[7,1]]]]
[4,[[[9,6],5],9]]
[[[[3,7],6],0],[[7,7],[[2,7],[9,3]]]]
[[[6,[3,7]],[[8,3],2]],[8,[6,[8,5]]]]
[[[5,[2,7]],[[6,7],3]],[5,[[4,4],1]]]
[[1,0],[[2,8],[[0,4],9]]]
[[[1,4],6],[[[9,8],[1,0]],1]]
[[3,4],[[1,[8,4]],8]]
[[[[9,4],[0,7]],[[5,4],[8,2]]],2]
[5,[[[8,7],[3,4]],[2,4]]]
[[[[1,3],[8,6]],[[3,4],6]],[[8,5],[[9,3],[5,7]]]]
[[0,[[0,9],[7,8]]],[3,9]]
[0,[[8,[2,3]],[[3,5],[4,9]]]]
[[[4,3],[[1,9],[1,5]]],[4,[[9,1],1]]]
[[[[3,6],[2,5]],3],[[8,[8,0]],[[6,9],[5,8]]]]
[7,[[3,[3,6]],[[6,9],[2,7]]]]
[[[[8,3],[6,5]],[[3,9],2]],[6,1]]
[[[2,0],[2,3]],8]
[[1,[[8,7],2]],[[[9,4],8],[4,[9,0]]]]
[[[6,7],[[5,2],3]],[[0,5],[[9,4],[2,6]]]]
[[[9,[5,8]],[[9,3],[6,9]]],5]
[[[5,[4,6]],[5,[3,2]]],[2,[9,[5,4]]]]
[8,6]
[[[4,8],[3,1]],[1,[[7,8],[7,5]]]]
[[4,[[8,8],4]],[5,[8,[3,9]]]]
[[[4,[9,0]],[[0,3],5]],[[5,[3,0]],[6,[2,3]]]]
[[[4,0],8],[[[4,0],7],[[9,6],3]]]
[[8,[[7,8],5]],[[[6,2],8],[1,[0,4]]]]
[[1,[[3,4],[0,8]]],[[6,5],3]]
[[5,2],[[8,6],[1,[9,7]]]]
[5,[6,[[1,3],[1,0]]]]
[[0,[[1,9],[5,6]]],[[[6,2],[5,1]],[[1,2],[1,0]]]]
[[[7,1],4],[[[0,3],3],[[4,8],1]]]
[[3,[9,[3,4]]],[1,[[0,0],[1,4]]]]
[1,[7,[1,[3,7]]]]
[[[0,[5,6]],[[7,4],[5,7]]],[[[6,8],[4,6]],9]]
[[[9,8],[7,[1,3]]],3]
[[[4,[0,3]],[[3,0],6]],[[2,[9,2]],1]]
[[[[1,9],[3,3]],[8,1]],5]
[[7,[5,2]],[[4,[0,1]],[3,3]]]
[[[6,6],[0,6]],[[3,[5,9]],[[4,2],[4,3]]]]
[[[7,[5,4]],[7,1]],9]
[[6,[5,2]],[[7,[0,5]],4]]
[[[8,1],[[7,6],[4,1]]],2]
[[[[4,3],[1,4]],[9,6]],[3,[[2,5],3]]]
[[[[9,3],[5,0]],1],[1,[[9,7],9]]]
[[[8,5],[5,9]],[2,[4,[0,0]]]]
[[[[7,9],2],[[8,8],[6,3]]],[7,[0,9]]]
[[[[6,6],[0,2]],[2,[9,0]]],[[0,9],[9,9]]]
[[[9,[1,3]],[6,5]],[[[1,1],8],[9,[7,2]]]]
[[8,[[8,4],6]],[[4,[5,9]],0]]
[[8,[5,[6,7]]],[[[1,9],9],[0,[0,9]]]]
[[9,[9,[7,3]]],[4,[4,7]]]
[[[[9,3],7],5],[[5,[8,5]],[0,[8,0]]]]
[[[5,[9,0]],[[7,4],[5,3]]],[3,[[1,1],[1,8]]]]
[[1,[[1,4],[5,9]]],[[[9,1],[6,5]],[9,[0,7]]]]
[[[[9,4],9],[5,3]],[[[4,2],[2,2]],[[1,0],0]]]
[[[6,[8,6]],9],[8,[[0,1],[9,7]]]]
[[2,0],[5,[[8,3],4]]]
[[[[0,2],0],8],[8,[[2,5],[8,2]]]]
[[[[7,4],8],[9,[7,5]]],[8,[7,[5,3]]]]
[[2,4],[3,[3,8]]]
[[5,4],[[0,[5,8]],[4,3]]]
[6,[[5,[4,7]],9]]
[[[2,[6,8]],[5,5]],[[[3,0],4],[[6,6],[0,1]]]]
[[[1,[4,2]],[[8,0],8]],[8,[[6,1],[0,0]]]]
[[9,[2,[3,3]]],[[2,6],[[5,2],[5,8]]]]
[[9,[4,4]],[[[8,6],1],2]]
[2,[[[0,7],7],[[7,8],5]]]
[[[4,0],[[1,1],[7,6]]],[[6,7],[[7,2],1]]]
[[[[2,5],0],[[9,5],9]],[6,[7,[6,1]]]]
[[[7,8],1],[[[6,2],0],[[9,7],[3,5]]]]
[[[9,1],0],[3,[[6,1],[6,9]]]]
[[[[9,0],0],[4,[7,0]]],[[6,[4,0]],[8,[4,2]]]]

921
2021/inputs/19.txt Normal file
View File

@@ -0,0 +1,921 @@
--- scanner 0 ---
-377,550,716
405,-463,594
-612,-603,479
-673,637,-463
536,-465,715
821,322,-697
-676,-693,500
643,432,654
366,-500,-472
708,409,-755
469,-498,555
738,371,759
600,282,729
362,-630,-324
-446,-778,-395
-679,-672,612
-450,654,697
353,-429,-389
-661,719,-393
118,-178,-1
702,313,-718
-540,-676,-341
-716,754,-469
-313,635,722
-546,-749,-540
-46,-64,45
--- scanner 1 ---
-393,569,-783
823,673,744
492,605,-667
568,-702,420
498,-690,338
-442,536,-928
-458,-493,-747
-617,-342,422
-654,709,686
539,-496,-476
540,570,-668
-416,521,-829
756,-480,-461
-387,-515,-848
-549,614,625
-611,-406,507
666,628,-671
-592,-479,403
632,-478,-385
802,792,735
860,679,648
27,17,-91
-624,571,775
-535,-422,-848
574,-745,303
--- scanner 2 ---
558,-741,-564
646,-807,485
464,437,812
-898,-528,468
616,-770,-508
-127,-22,17
351,393,-850
532,-629,-522
-680,-690,-789
600,353,768
-655,-827,-770
593,-678,448
675,-648,590
-808,525,-539
-765,-461,537
335,474,-887
-777,396,-580
241,407,-941
-787,793,667
-973,848,720
-661,-763,-685
-789,519,-676
449,424,815
-815,754,730
-42,81,-107
-877,-464,558
--- scanner 3 ---
-436,572,-578
746,-456,727
-475,513,-649
-451,-549,481
-562,-572,-515
774,-516,696
-704,791,507
768,-722,-551
812,-661,-568
-613,684,551
700,767,716
-303,592,-650
116,21,-89
-408,-507,547
753,-717,750
609,753,-601
-62,-9,37
553,672,-596
836,-673,-599
-467,-404,-483
-660,817,634
-609,-356,-546
602,796,-590
692,646,766
-565,-477,532
702,620,743
--- scanner 4 ---
538,-453,-833
-126,24,29
-352,-473,-587
-444,-449,-740
691,-464,520
626,828,344
-565,-317,406
775,942,-788
-369,-409,417
-708,823,-645
727,935,-697
-746,539,507
-806,434,481
-789,742,-763
-556,-362,404
-690,470,523
593,877,489
405,-436,-796
317,-447,-785
-404,-427,-788
-13,189,-5
-698,727,-823
600,898,-737
561,-551,518
641,854,443
733,-626,469
--- scanner 5 ---
46,10,147
758,-651,532
-527,-618,452
-823,464,-569
690,764,759
-564,-447,-551
764,-302,-267
684,881,802
456,449,-735
435,440,-616
107,94,-30
760,846,747
-677,-709,468
-647,455,-499
-408,-549,-539
398,536,-622
-293,614,774
829,-503,-276
-385,-416,-489
-272,801,808
-563,-622,372
-612,469,-575
613,-622,632
-278,753,780
681,-373,-280
812,-549,626
--- scanner 6 ---
579,574,-541
-505,493,-632
618,658,359
-341,743,774
-322,-636,574
716,580,-522
366,-369,516
-654,544,-722
401,-424,440
-413,-618,481
-785,-692,-593
-785,-599,-445
466,-635,-650
675,451,-553
89,132,-70
-427,825,855
-398,-634,698
570,-708,-669
-60,27,13
522,657,457
-376,606,841
-684,-621,-516
485,-772,-675
475,716,376
-647,496,-573
483,-412,510
--- scanner 7 ---
512,585,-747
807,772,880
733,795,840
-767,-876,-603
-719,662,750
-612,458,-552
570,-882,858
-589,-932,-661
623,-601,-378
-343,-464,739
-589,632,-556
746,-608,-532
494,492,-838
-652,610,660
-554,584,-555
111,-115,-49
589,-757,885
-618,631,899
496,368,-762
618,-644,-539
696,-814,921
-640,-913,-544
737,746,813
-310,-533,587
-23,-193,76
-85,0,-51
-447,-527,622
--- scanner 8 ---
-419,640,-664
-722,-533,531
705,861,595
577,-689,716
-842,-385,512
632,-792,-344
815,768,660
490,-691,586
-502,623,-798
-554,-811,-585
676,809,607
560,496,-785
-943,400,567
415,-740,758
679,-805,-531
732,438,-813
-792,347,621
724,-803,-540
-489,-738,-726
-746,-370,499
-2,59,-33
558,494,-753
-515,574,-768
-486,-634,-564
-122,-93,-71
-872,325,554
--- scanner 9 ---
506,-688,-561
571,721,622
503,-562,-503
-709,-714,-463
-835,437,457
-948,-735,-497
314,-589,962
495,809,-475
-788,360,-772
-612,-499,488
291,-602,907
-580,-584,424
-119,8,40
-636,429,-805
408,627,663
555,634,776
301,-483,836
-799,-766,-396
-671,423,-668
-725,535,411
10,-85,163
554,772,-348
-726,558,457
507,-736,-526
612,828,-526
-444,-607,500
--- scanner 10 ---
-643,-839,-726
-663,-800,-791
-17,49,1
-428,-762,319
-452,-869,434
806,-584,-592
-468,406,-817
118,-97,56
530,403,850
-433,399,-634
521,-484,654
881,-476,-533
954,-520,-545
781,439,-557
609,-463,682
-327,671,688
-542,-771,-726
-328,557,674
661,-458,693
510,298,863
-240,536,611
785,322,-393
-432,416,-779
-475,-744,471
518,305,832
823,411,-365
--- scanner 11 ---
-559,-302,-674
-766,553,760
-687,-322,850
-800,-238,758
370,-773,-566
-851,883,-504
-804,954,-655
-716,-388,-711
17,134,92
884,-743,798
905,900,-296
-681,-359,-759
-84,7,-30
851,833,-390
-756,459,918
479,-816,-448
-848,870,-519
707,-731,809
814,914,-406
503,782,753
544,911,722
767,-719,748
640,788,734
572,-776,-603
-781,-228,812
-703,514,732
--- scanner 12 ---
-593,845,571
-95,162,7
-509,-378,-516
504,-445,343
-400,708,-674
-554,-465,-583
431,-519,471
-473,-359,-516
-592,828,716
-931,-358,491
-906,-487,413
-628,838,754
-487,573,-751
370,841,-913
625,922,330
663,833,302
429,-748,-651
358,939,-895
244,-687,-680
-794,-417,415
621,805,494
350,946,-926
351,-656,-694
-488,687,-737
575,-504,385
--- scanner 13 ---
-540,634,673
764,-806,-384
489,306,-588
141,-5,-53
577,221,-522
-383,-685,663
-575,616,539
-558,-546,-541
-444,-533,-673
-356,-714,588
-603,633,440
791,-862,408
763,728,555
610,-722,-434
758,-918,432
693,-743,468
-611,661,-390
607,-706,-368
-1,-144,-29
-280,-701,796
-706,583,-501
-709,727,-493
764,719,476
763,692,397
643,299,-606
-566,-523,-601
--- scanner 14 ---
-636,680,-483
718,525,642
822,571,-429
534,-636,-655
-464,-684,-415
34,31,141
-600,748,862
-629,673,889
719,758,705
-438,-516,679
-448,-588,801
780,425,-363
-616,881,965
467,-723,-700
-462,-614,-303
806,549,-467
668,-416,539
746,-305,634
-461,-456,687
701,624,670
-795,747,-546
-726,811,-463
-540,-743,-278
-82,-24,3
812,-408,536
467,-742,-736
--- scanner 15 ---
570,716,-401
813,-522,-700
-565,-663,616
577,-384,448
71,-43,-130
-641,-610,619
-731,-539,-421
-448,392,521
563,363,512
-486,-548,601
792,-612,-764
638,513,555
-760,-644,-580
680,-591,-767
533,452,650
-701,454,-458
698,-382,317
-309,433,468
576,631,-465
-18,83,4
-617,468,-599
737,-417,381
-678,-502,-550
-643,510,-487
595,735,-538
-419,340,533
--- scanner 16 ---
-99,-26,105
-171,-173,17
-808,-569,-752
-430,-810,823
276,298,847
-545,545,909
406,-582,-466
797,-624,681
-592,481,-545
-566,579,670
483,-511,-365
283,346,756
390,447,-285
766,-707,633
341,480,-430
-591,-585,-737
814,-646,819
-404,-880,890
-381,-806,850
-544,516,-546
-514,646,760
320,473,796
-718,539,-542
364,432,-384
-684,-567,-828
335,-604,-365
--- scanner 17 ---
-814,515,-501
351,736,-672
-840,-376,629
-809,-483,615
420,355,558
452,-906,-323
-512,341,793
461,-873,-478
534,356,572
-618,422,726
-901,-561,658
-866,536,-417
346,616,-702
-798,-485,-246
-31,-18,-10
-785,-377,-340
786,-490,414
-885,-489,-394
278,697,-583
-163,40,154
-828,605,-546
-531,377,793
555,268,635
793,-482,383
688,-502,396
346,-856,-366
--- scanner 18 ---
-599,-418,-687
485,631,359
-642,-843,277
894,-574,-927
137,-133,-101
-513,528,790
-703,425,-406
623,-464,487
843,-793,-941
616,-512,636
-661,-584,-635
857,650,-567
765,-461,546
-612,-497,-702
-561,611,821
-770,355,-380
485,724,507
929,-711,-860
-699,589,838
948,668,-660
-730,429,-357
-605,-829,293
-24,-73,10
586,653,430
-757,-881,273
872,666,-784
--- scanner 19 ---
805,-688,638
106,-100,35
673,664,467
-736,-787,-834
-702,-600,-813
641,-450,-283
561,430,-721
-708,-739,-828
571,-441,-459
-562,-605,531
-610,479,771
590,617,600
-611,307,692
623,461,-542
-300,636,-543
755,-696,517
-551,-598,488
-557,-549,612
-380,632,-579
-77,14,78
611,563,-698
782,-698,664
-396,723,-429
546,708,493
-539,440,712
647,-455,-494
--- scanner 20 ---
-73,-55,-94
679,574,-740
412,-822,-515
-380,370,-593
587,593,879
-693,453,644
-818,416,667
722,670,792
450,-652,686
608,656,791
-288,297,-533
457,-835,651
-749,-809,456
691,374,-778
-793,-809,-818
421,-914,-678
113,-67,36
-695,-740,-793
467,-797,687
-788,-744,476
538,-900,-564
-579,-816,-811
662,430,-653
-720,-744,577
-333,306,-554
-711,301,691
--- scanner 21 ---
-720,-494,-326
-779,-506,-326
725,743,-671
643,-838,-672
735,624,-742
780,-444,760
635,-395,727
-773,-551,682
523,664,668
712,637,-797
4,104,146
-655,857,-500
-883,800,504
-152,-49,102
-923,-626,725
681,-418,775
-827,-424,-336
601,-802,-556
520,538,726
617,-733,-612
-698,874,-492
-834,-656,587
-892,821,623
519,490,691
-920,866,-491
-796,858,617
--- scanner 22 ---
80,-91,68
564,449,615
694,505,-425
820,-741,761
697,526,-537
-542,-761,600
-615,-889,674
630,595,-404
558,522,416
-23,-171,-90
635,-555,-793
552,-486,-729
-335,769,464
464,420,470
683,-817,702
-344,568,399
-75,6,7
-833,-862,-867
-686,-847,615
-836,-696,-870
615,-645,-662
-348,698,547
-518,733,-640
795,-819,632
-874,-749,-817
-387,735,-519
-451,700,-480
--- scanner 23 ---
-521,536,-591
405,-522,-611
598,-743,933
739,728,856
-767,828,470
553,913,-698
-311,-634,587
808,645,792
-303,-497,588
-36,32,-25
475,888,-569
447,-593,-552
-793,724,594
533,-449,-537
-589,-447,-308
-454,455,-697
649,708,725
477,776,-639
-632,-369,-400
-809,762,616
545,-781,880
105,114,172
-310,-582,457
432,-740,930
-618,-262,-369
-454,491,-678
--- scanner 24 ---
-574,-700,-914
645,309,-801
511,564,648
-735,664,363
464,628,796
703,-469,305
691,-453,440
-552,404,-633
710,348,-821
-763,685,451
496,-926,-724
702,-429,236
-885,-631,405
1,-36,-128
452,672,723
-672,-700,-757
-928,-818,431
-916,-845,434
-515,279,-610
515,-953,-752
645,377,-700
421,-973,-621
-625,-803,-884
-774,690,503
-400,386,-586
--- scanner 25 ---
-660,-612,759
44,-15,-25
-564,539,589
-501,550,610
817,513,-563
412,-387,533
-535,416,-425
-819,-717,730
743,582,558
666,604,559
-690,-754,677
790,542,-488
836,-482,-889
781,-535,-703
-473,-665,-681
-540,-734,-814
-665,512,540
-618,347,-489
742,-472,-731
341,-434,684
425,-390,548
593,616,664
-555,506,-556
-476,-644,-793
893,526,-355
--- scanner 26 ---
283,522,745
-873,247,471
628,-379,499
336,469,783
-605,567,-596
-904,279,268
-675,529,-760
-944,-764,-808
-898,-880,692
286,356,742
-18,5,-170
-93,-106,-29
360,663,-726
622,-869,-722
-946,250,385
759,-386,584
-742,-793,-828
629,-387,636
-776,-774,753
-830,-795,-768
746,-843,-826
600,-885,-760
-654,540,-697
424,732,-643
491,573,-706
-885,-685,732
--- scanner 27 ---
706,-520,-692
-101,126,35
771,564,-698
-480,528,-493
442,456,859
559,502,806
752,-472,-669
514,541,941
-584,455,-474
-875,-543,521
-499,391,-468
-747,589,719
771,471,-550
-763,-660,-431
726,-380,811
-823,-531,550
670,542,-627
-782,-478,411
677,-552,736
675,-422,649
851,-487,-643
-702,-565,-536
-852,-522,-461
-43,-34,179
-761,448,803
-705,477,745
--- scanner 28 ---
573,505,-684
8,-24,126
428,-551,785
857,610,665
-56,144,29
-507,671,603
-723,-628,-438
-717,-596,681
850,592,511
495,394,-589
464,-393,785
-586,488,-809
-697,-643,701
-698,573,-725
429,497,-687
523,-436,-581
-702,-787,657
-789,-593,-508
-533,539,692
935,526,599
540,-535,-553
-778,-650,-426
-354,610,678
116,29,-19
522,-669,-518
-553,559,-659
437,-472,786
--- scanner 29 ---
683,-540,-630
402,-538,-643
-329,-493,653
840,566,429
722,647,510
664,-649,866
28,-140,-104
878,620,-837
-765,-884,-623
732,696,-778
-28,13,9
-454,309,-532
-327,-538,662
948,661,-747
-340,-585,849
817,-625,774
434,-525,-638
865,-603,814
-430,363,472
900,551,520
-446,294,528
-808,-917,-481
-563,315,-597
-510,267,-682
-758,-915,-590
-404,258,412
--- scanner 30 ---
-299,482,-468
753,540,-526
737,658,-630
835,-810,469
-294,373,-321
-718,-593,401
-757,-504,474
-637,-474,469
-294,618,-363
356,-836,-662
-536,-675,-691
680,719,-521
505,718,872
-589,832,666
885,-853,575
-532,795,629
-626,-630,-705
-56,-7,92
385,591,857
-380,769,678
468,-782,-762
517,481,906
464,-930,-675
-557,-759,-743
852,-698,584
--- scanner 31 ---
-504,-722,764
-471,-655,604
620,778,-539
-579,438,-698
-750,-487,-538
-649,474,-531
-41,117,16
305,-582,-421
-635,-502,-459
-524,762,878
-469,-786,725
276,-591,590
365,-453,560
420,460,710
-635,417,-543
372,470,792
-182,-19,99
253,-570,-392
426,-548,665
618,810,-537
-697,-484,-614
346,-635,-282
479,460,722
-606,786,771
-653,734,906
676,838,-365
--- scanner 32 ---
-839,-599,715
351,-528,-912
377,598,754
-751,502,-745
498,820,-545
-631,-549,-889
566,-519,640
-706,-506,-739
-862,-551,669
-524,788,651
332,607,752
-149,64,-129
-455,732,635
-833,512,-793
496,852,-547
324,880,-489
-419,848,677
6,95,-6
-763,502,-686
479,-649,638
380,-540,-860
641,-691,689
424,411,741
241,-593,-819
-601,-411,-800
-813,-584,814

102
2021/inputs/20.txt Normal file
View File

@@ -0,0 +1,102 @@
#####..#.#######.##.#.#.#.#####..######...#.##.###...#.##..#####..###.#.####..#.##.#....#...##.###..#.#......####.#...#.####.#..#.###.#.#.#.###.###..########.##.#.#....#.#####.......###.#..#.#.###.###.###.#.......#.#....#.##.###.....##...#.#.#..#.#....##..#####...##...#.##..##.##.#...###...#.##...#...#.####.###...........#...#..##...##.###.##.###.....#.##...###.....#.#.###..##..#..##..#.....##..##....#....####...#.###.#######.#.##.####.....####.#.#.##.#####...#.##.##.#.##..####.#.#.######.#..###..#.##.##...
##.##....#..#....#.....#..##.#...######.##.##..#..##.###.##..##.#..#..####..##..#.#..###..##...##.##
..##.###.##..##.###..#.###....##.#.#...##.#.#..####.#..#..##...##......###...###.#..##...##.##.##..#
.#..####..##..###..#.....#....##....###..####.##.##.#.#.##..######..#####.#...##.#..##..##..##...##.
..###.......##.#..#.##.##.#..#######..##.......###.###.###.#..###...#.#####..###....###.##..###..##.
.#..####..###.#.#..#.#..##...#...#.##...##..##..##.#######.....#.#..#.#.#.#.#.#..#.##......####..##.
##..#...###.##....####.###.###.#.#.#........##...#.#....#######.######...##.###...##.###.##.######..
##..##...#....#....#####.#.....#....#.#..#.#.##...##.##...#.####...#####.#.#.##...#..##.##.##.##..##
..#..##..#..#...####....#.....###....##.#..#...#..#.##.#....#.#.#...##.#..#..#..##....#.##..#..##.##
..##....######.###.#.....##.##....###...#..#.....#...###.###....#...#.##.####..##.###....#####...##.
.#..##.###.#......#.#####.####..####......###.....####..####..####..#.######.####..##.#...#.##.####.
####..##.##.##..#.#...##.####..####.#...#.#.##..#.###.#.....#....###.####.###..#.#..#.#...#.#.##..##
.##..#....###..#####.##.....###.##.###.######.#.###.#.##.#.#######....##..#.#.##..#.##...#######..##
###.......###.....#.#.##....##..#.##...#....####.##.###.....#.####..#........#...####.##.#.##...##.#
##.##....##..#####.#...####.....##..#..#...##.#...##.#..#..########...###.##...#.##...##.#..##.##...
.#.###...#.###..##...####..#.###.##.#.#...#..###.#.####..#..##.##.####.###...##.##.###..#.#.####.##.
#..#.#.#.#.#.#.#..#####.#....####.#.......#..#####..##..#..###....#...#..###.#..###.##..#.###.##.###
....##..##.###..####.#.###.##.....#...#...##.##.#.###..##.#.#..#....#.####.##...#.#...#.#...###...#.
##...#....##.#....###....#..##.##.####.#.#.##..##.####...#.#....####..#.##.....#....#...#..##...#...
#.##...#.##..#.##.###..##...##.#.#..##..#.....###.#.####....#######.#.#.#####.#....##.#.....####....
.....#####..###...#.#.#.#...#.#..#.###..##.##....##.###..###..###.#.#...#.#.##.###...#...##.#..#.##.
...###.###.###.#..#.#.####.##...##.##..#####.......#.##.....#####..#.#######...#..#.###......#######
#..##.....###..#.###..#..###.#.##...#...#......#.###..#...###...#..##......#.....##.####..##...#...#
.....##..#.#.#..#.#.#.#####...#..#.......#..#..#....#..##..##.#.#..#.####..#...#..##...##...#..#####
...##..#.#...#...#.####..#.##.###..##..###.......#..######.#.###.#..#.##.###.....########..#..#...#.
#.#...##...#.##.##.#..#..#.#....##.#.#...#.#..####.#...#.#..######.#.##....#.#...##....#..#.#.##.###
...#####.##.####.##...#..##.#..##...#..##..#.##...##..#.#.###......#.###.#.#..###...##..##.##..###..
.##...###..#....#.#.....#..#.##..###.#..###..###.#..#.#.###..#...#..####..#.###.##.##.#.#.#..#..#..#
.#..#.#.#..#####.##...#.#...###.####.##..###....######.##..##.#...#.###..###.###....##.#......#.##.#
#..####.######....###..####.##.##.....#.##.####.##..##.#..##.#.#.#.##.##..#.###.##..####.##.#.##..##
....#.#..........#.##....#.#..#.###.##.####.#.#..##.#..##.#..#.....###.#..###.######..##.#......####
...#..#.##.###########...###.###..##......#..###.#.#...##.##...####.##..#.........##...##.###.###.#.
.##.#####.#...#.###.#..#..#.#..#.##...#.#..##.#.####.##..######....##.####...#..###.####.#...##.#...
...#.##..#..#.#..##..#.#..##.....#.##.#....#..#..#.#......##.####...####...##......##..##....####.#.
####.##.#...#....#.#.#..###.##.###..#.###.#.#..#.##.##..##.##.#.#..#.####...###.####.##.....#.#...##
#........#.###..#.#.#####...#.##.#.###...#..#...##.##..#.###....#.###..#.#.#.###.#.##.#....#......##
...#.##..##.#..........#..#....###.#..#..#.#...###.##..#.#...###.####...####..#.####.######.#....#..
##.#.####.##.#.##..#..##...###...###.##..##.#####..###..#..#.#..#.##...#.####...##.##..#.#.#..###...
#.####..##..#.#..##..##.#..#..#...#.###.#.##.####.###.###...##.#####..##..####...##.##########.#.###
####.##..###.####.#.######...#..#.##.#.....##.#....#...#.############..#.#.###.####.#.#..#.###....#.
..###..#...##.#.##.##..######.###.###..#..#####....#.#....####.#..#.......##..#####.#...#.#.##....#.
.#.##...#..#.##.####......#.#......######.#.#.##.#..##..#....##..##....#.##.###..#.##..#.#.....##...
###..###.########..####.###.#...###.........##....##.##..#...#.##..##..#.#.####....######..#..#...##
##.#..###..#.#..#...##.####.#..##..##...###.##.#......#........###...#.###..####..####..#####..###..
#.##...##..##..#.#.###..###...###.....#.#.######.....##.....#.##..##.#...###.###.#.#..#.##.##.##.#..
#..#.#####..#..#...#.#...#..##.#..#.###...#..###.###.#.#...#.###..#.###..#..##.##......##...#...###.
#....#.##.....#.#...###....#..#.#.#..##.##..###.###..#..#.#..##.....###.#.#.#...#.##.#..##....####..
#..#####...#...#####.###.#..#..#...####.##.#.#..#...#.####...##.##.....#.#.##.##.##.#....#.######..#
###...##..##.##.##.#..##.##.#.##.##.#..#.#####..#.#..#.#..####....#.###..###...####.#....#...#.###.#
##...####...##.######...#...#..##..###..###..#.##.#.#.#...##.#.###...#...########..#.#######...###..
.###...#.#.####.#.#...##.#.###.#.###.#####.###..##.#..###..#.#...##...#####..##....#..#..##.#.#....#
...#..#....#..#....#.#.##..#..#####....#..#.#..####..####.####.###......###..#..#..###.##.###...###.
#.#...#.###.###....#..###..###...#..#####..#.##........###....###.###.##.###.#..##..#.....#.#.####.#
#...#.#...#.#..#..#.##.##.#......#.#.#..###....#.#.#.#..#.#.###..#..#..##.#.#.#.##...#..###.####..#.
#.#.##.####........#.##..#.#.#...##..#.#####.#..#.#..#.##.#..####.###.#####.#.##.#....##..#####.####
#######.##..#.#..#...#..#..#.######..##.#.###.#...#..####..##.#.##.###.#.##.#.##..#...#.#..#.#.####.
.##..#####.##.####.##.#....##.....###.......#.####.###....#...#.#####.###.#..#...##.#..##.#....###.#
..####.#.#.....#...###.#...#.#...#.####..##..#..######......#...#.##.####..#.......#.##.......#.###.
.##..#.#####..##..##.#..####.##.##.#.###.#.#.....#.....#.#...####....##.##...####......##.##.#######
#.#.#..###..###..##.#..##...###..###..#..#.###.#..##.##...##..#..####....####.##.#.###...#..##.#.##.
##.##.....######.#..##.#.#.###.##.###.##....######.##.#.##..#..##...#...#..#.#.#.######..#.###.##..#
#..#.#.###.#.#.#.....###.######..##.##.#.#...#####.#...##.##.##.##....##....#..#.##.#.##..##...#...#
..#.....#....#...#######..#.#.#.#.###.##.#.##.###..#..##..###..#.#####..###.......####.#..####..#...
#..#.#...##.##..#.#.....###.##.#.#....###....#.##..#....#####.##.#####..###...####.#.#.#.###.#....##
#....##..#..##..#.####..##.##....####..##..#..####.######.##..#.###.#.##....###.#....##....##.#.##.#
.#.#.#.##.##...###.#.#...#...#..######.##.#.#.##.####.....#.#..#.######.......##.#####..#....#####.#
.###.#.##...###.....##..#.#..##....#.###..##.##..####..##.#.###..##.#.#...##.#####.#.....#..#..#####
#.#.###..#....####....#...#.###.#..#...###..###......##..##.#.#..#....#......###...##..#.##.##...#.#
###.####.##.#.##.......##.....#.#.###......##..#.#....###..#.#.##.###.##.##.##.#..#.####.#......###.
####...#...##...#.#.#..######.#####..##...#.##.##.####.##.#.##..#..#.#.##.#...#......#.##.#######...
.##...#....#.##.#...#..#..#.####..#.#..........#.#.##......#.##.######.###.#####.#.#####.###.####...
.##.##.##.###..###..##.#..#.###..#####.#..##.##.#.####....###.#..###...##..##..#.##..#...#..###.##.#
#.....##..#...##.#...#.###.##..#.....##..#.##...#.##...#.#.##.#...#.#..###...#...#######...#.#.....#
.######..#.####.#.##.##.#.#.#.#.###.#######...#..####.#.#..#####..#.....###.##...#.###.####.#.#.....
#.####..##...####.##.#.##...####..##.#.#..####.##.#.###.##..##.##..###.##...##........###..#.#.##...
#...#.##.....###.##.....####.####.##.##.##....##.#.#.#.##...#.#.##..#..##.....##.#...##..##...##..##
#..#.###.#....#.##...##...#.#......##.###...#......##..#..##...##.#..###.#..#.#.#.##.........##.#.##
.#.#..#..#.#..##...#.#...#..###.#...#.#.##.##....#.##.#...#.##.#..#.#..##..#.##...#.#.#..###.#.###..
###...#.#..##.###...#..##.#..##.#.######..####..#.#.....##....##.####.###...#.#...#.#..#..#.###....#
.####.###..##.##...#.....##.###.#..##..####.....#....##.....#....##..##...##....#..#..###.#...###.##
..###..###.#.#....#.##........#...####...####...#.####.##.###.##...#.####.#.###..###.##...##...#.#.#
###.#..#.#...#.#.#.....##.###...#..###.#....#.##.##.###..#######.###.#...###.####...#.#.###.#...####
#.#....####..#.#.###..###.###.#.#.##...###.#..###.#.#.#...###..#...##...#..#..###..##.#..#.##...###.
.###..##.#..#.#.#####.#..#.........##..##...#...#.#...##..#.##...###..#.#.#..####....#.####.##.#....
##.....#######....#.###.##...##.##.#####.#....#########.##....##.###...#.###..##.###.#..##..#....#.#
...#.##.#.......#.#....#..##..#..##...#.#.####...###.##..##...##.#.##.#.###.###.###..####..#######.#
.#.###...##.##.#.......#.#...#..#####...##...#...#.#####.##.#......#.##...#.###.#.#..#.#..##..##.#.#
...##...##.#.#...#...#.###..###....#.##...##.....#...##..##....#..##..#.#..#.#.#.........##.#####..#
........#...#.......#.#..#..#......##..##...##......#.....#.#.......#.#####.#.#.#..#...#####.#..####
#.#.###...###....#...######...#.#.#####.##..#..##.##..#..#..#..##...###..#.#.#..##...#.#.#.#.####..#
.#..#...##...#....#.#.##.#.#....##.#....#...#.#.##.....#########.#....#.##..#..#.#.##..#.#..###....#
##..#.#.#..###.....###.#..#.##..##....###.#..####.#.#.#..######..###..#.#.#...#...#...#.#..#.#..###.
.#.##.#.####....#..#.#...#.##......#..#.....#...#....#.##########..#...#.#.###...####..###......##.#
###...#....###.#.#..#...#..####.#...#.##..#.##.#...###.#.#..#.###.###...#......#..#.##.#..#####...##
.###.##.#..###...#..####.###...#.##..##....######.#..##...#...#.##.....#.####.########.##....#.##.##
.......######.#...#...#.###....##..#.###.#...##.##..###.#..##...#..########.#.#.#...#..#..##.##..#.#
..###.##..#..#####.#.##.#..#...##..#.#..###.###....###...#..##......###..#....#.#.....#...#..##.#..#
###..##..#.#....#####.#######..#..##...#..#...#.#........#...###.#.###..##.####..#.####.#..#..#...#.
...#..###.#.#.#.###...#.......####..###.#.##.####.#..#.#..#########.#.....#...##..#.#.#..#.#.#.#...#
####.#..##.##..#..###.######.#.#.###...#####.#.###.#####.#.#.#.#...#.#.#...#.#########.#..###.##.###
.##...#.#.###....##..##..#.#.#.#.#..#..##.###...####..#..#.#.#.#####..##.#.#.##.##...#.....#...###.#

2
2021/inputs/21.txt Normal file
View File

@@ -0,0 +1,2 @@
Player 1 starting position: 9
Player 2 starting position: 4

420
2021/inputs/22.txt Normal file
View 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
View File

@@ -0,0 +1,5 @@
#############
#...........#
###D#B#A#C###
#B#D#A#C#
#########

252
2021/inputs/24.txt Normal file
View 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
View 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>..

View File

@@ -4,6 +4,9 @@ use std::io::Read;
use std::marker::PhantomData;
use std::str::FromStr;
use nom::Finish;
use nom::IResult;
pub struct LineIter<'a> {
reader: BufReader<&'a mut dyn Read>,
buffer: String,
@@ -78,3 +81,74 @@ pub fn ordered<O: PartialOrd>(a: O, b: O) -> (O, O) {
(b, a)
}
}
pub fn read_input<I, P, O>(mut input: I, parser: P) -> O
where
I: Read,
P: for<'a> FnOnce(&'a [u8]) -> IResult<&'a [u8], O>,
{
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
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)
}
}

View File

@@ -6,9 +6,10 @@ use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::preceded;
use nom::sequence::tuple;
use nom::Finish;
use nom::IResult;
use crate::common::read_input;
#[derive(Debug)]
struct BingoCard([(bool, u8); 25]);
@@ -80,16 +81,8 @@ fn parse_input(input: &[u8]) -> IResult<&[u8], (Vec<u8>, Vec<BingoCard>)> {
tuple((parse_numbers, many1(parse_bingo)))(input)
}
fn read_input(input: &mut dyn Read) -> (Vec<u8>, Vec<BingoCard>) {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
parse_input(&buffer).finish().unwrap().1
}
pub fn part1(input: &mut dyn Read) -> String {
let (numbers, mut bingo_cards) = read_input(input);
let (numbers, mut bingo_cards) = read_input(input, parse_input);
for number in numbers {
for card in &mut bingo_cards {
@@ -103,7 +96,7 @@ pub fn part1(input: &mut dyn Read) -> String {
}
pub fn part2(input: &mut dyn Read) -> String {
let (numbers, mut bingo_cards) = read_input(input);
let (numbers, mut bingo_cards) = read_input(input, parse_input);
let mut bingo_won = vec![false; bingo_cards.len()];
let mut num_won = 0;
let to_win = bingo_cards.len();

View File

@@ -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)

View File

@@ -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)

View File

@@ -8,9 +8,10 @@ use nom::multi::many0;
use nom::sequence::preceded;
use nom::sequence::separated_pair;
use nom::sequence::terminated;
use nom::Finish;
use nom::IResult;
use crate::common::read_input;
type Coords = (u16, u16);
#[derive(Copy, Clone)]
@@ -47,14 +48,7 @@ fn parse_fold(input: &[u8]) -> IResult<&[u8], Fold> {
)(input)
}
fn read_input(input: &mut dyn Read) -> (Vec<Coords>, Vec<Fold>) {
let mut input_buffer = Vec::new();
input.read_to_end(&mut input_buffer).unwrap();
parse_input(&input_buffer).finish().unwrap().1
}
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 {
@@ -88,7 +82,7 @@ fn print_dots(dots: &[Coords]) -> String {
}
pub fn part1(input: &mut dyn Read) -> String {
let (mut dots, folds) = read_input(input);
let (mut dots, folds) = read_input(input, parse_input);
apply_fold(&mut dots, folds[0]);
@@ -98,7 +92,7 @@ pub fn part1(input: &mut dyn Read) -> String {
}
pub fn part2(input: &mut dyn Read) -> String {
let (mut dots, folds) = read_input(input);
let (mut dots, folds) = read_input(input, parse_input);
folds
.into_iter()

View File

@@ -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);
}
}

View File

@@ -1,15 +1,14 @@
use std::io::Read;
use std::ops::RangeInclusive;
use itertools::Itertools;
use itertools::MinMaxResult;
use nom::bytes::complete::tag;
use nom::combinator::map;
use nom::sequence::preceded;
use nom::sequence::separated_pair;
use nom::Finish;
use nom::IResult;
use crate::common::read_input;
#[inline]
fn solve_quadratic(a: f64, b: f64, c: f64) -> Option<f64> {
let d = b * b - 4. * a * c;
@@ -18,7 +17,11 @@ fn solve_quadratic(a: f64, b: f64, c: f64) -> Option<f64> {
None
} else {
// Don't care about the smaller solution due to problem statement
Some((-b - d.sqrt()) / 2. / a)
if a > 0. {
Some((-b + d.sqrt()) / 2. / a)
} else {
Some((-b - d.sqrt()) / 2. / a)
}
}
}
@@ -26,70 +29,49 @@ fn position(initial: i32, time: i32) -> i32 {
time * (2 * initial - time + 1) / 2
}
fn find_hit(initial: i32, range: &RangeInclusive<i32>) -> Option<RangeInclusive<i32>> {
fn find_hit(initial: i32, range: &RangeInclusive<i32>) -> impl Iterator<Item = i32> + '_ {
// y position at time x: f(x) = x * (1 + initial + initial - x) / 2
// = -1/2x^2 + (initial + 0.5)x
//
// to hit, find x := (max(box) + min(box)) / 2 = f(x)
// = -1/2x^2 + (initial + 0.5)x
// -1/2x^2 + (initial + 0.5)x - (max(box) + min(box)) / 2 = 0
let middle = (*range.start() + *range.end()) as f64 / 2.;
let middle = *range.start() as f64;
let b = initial as f64 + 0.5;
let hit = solve_quadratic(-0.5, b, -middle)? as i32;
if hit < 0 {
// Should not happen because of the shape but for correctness
None
let hit = if let Some(hit) = solve_quadratic(-0.5, b, -middle) {
hit as i32
} else {
let min_hit = (0..=hit)
.rev()
.take_while(|&n| range.contains(&position(initial, n)))
.min();
// Cause an empty range
-1
};
let max_hit = ((hit + 1)..)
.take_while(|&n| range.contains(&position(initial, n)))
.max();
match (min_hit, max_hit) {
(Some(min), Some(max)) => Some(min..=max),
(Some(val), None) | (None, Some(val)) => Some(val..=val),
_ => None,
}
}
(0..=hit)
.rev()
.take_while(move |&n| range.contains(&position(initial, n)))
}
fn find_speed(x: i32, range: &RangeInclusive<i32>) -> Option<RangeInclusive<i32>> {
let mut min = 0;
let mut max = *range.end();
fn find_speed(x: i32, range: &RangeInclusive<i32>) -> Option<(i32, i32)> {
if *range.end() <= position(x, x) {
// Can and should come to a full stop
let max = solve_quadratic(0.5, 0.5, -*range.end() as f64)? as i32;
// Need to tweak the formula as x slows down
let x_pos = |speed| position(speed, speed.min(x));
let min = (0..=max)
.rev()
.take_while(|&n| range.contains(&position(n, n)))
.last()?;
while max >= min {
let speed = (max + min) / 2;
Some((min, max))
} else {
// Might hit the target at speed
let max = (x * x + 2 * *range.end() - x) / (2 * x);
let pos = x_pos(speed);
let min = (0..=max)
.rev()
.take_while(|&n| range.contains(&position(n, n.min(x))))
.last()?;
if range.contains(&x_pos(speed)) {
let min_speed = (0..speed)
.rev()
.take_while(|&speed| range.contains(&x_pos(speed)))
.min()
.unwrap_or(speed);
let max_speed = ((speed + 1)..)
.take_while(|&speed| range.contains(&x_pos(speed)))
.max()
.unwrap_or(speed);
return Some(min_speed..=max_speed);
} else if pos < *range.start() {
min = speed + 1;
} else {
max = speed - 1;
}
Some((min, max))
}
None
}
fn parse_range(input: &[u8]) -> IResult<&[u8], RangeInclusive<i32>> {
@@ -108,48 +90,37 @@ fn parse_input(input: &[u8]) -> IResult<&[u8], (RangeInclusive<i32>, RangeInclus
}
pub fn part1(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
let (x_range, y_range) = read_input(input, parse_input);
let (x_range, y_range) = parse_input(&buffer).finish().unwrap().1;
let check_value =
|y_speed| find_hit(y_speed, &y_range).any(|time| find_speed(time, &x_range).is_some());
let check_value = |y_speed| {
let mut time = find_hit(y_speed, &y_range)?;
debug_assert!(*y_range.start() < 0);
let y_max = -*y_range.start();
if time.any(|time| find_speed(time, &x_range).is_some()) {
Some(position(y_speed, y_speed))
} else {
None
}
};
(0..1000).filter_map(check_value).max().unwrap().to_string()
(0..y_max)
.rev()
.find(|&speed| check_value(speed))
.map(|speed| position(speed, speed))
.unwrap()
.to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
let (x_range, y_range) = parse_input(&buffer).finish().unwrap().1;
let (x_range, y_range) = read_input(input, parse_input);
let num_options = |y_speed| {
let time = find_hit(y_speed, &y_range)?;
let range = time
find_hit(y_speed, &y_range)
.filter_map(|time| find_speed(time, &x_range))
.flat_map(|x| [*x.start(), *x.end()])
.minmax();
Some(match range {
MinMaxResult::NoElements => 0,
MinMaxResult::OneElement(_) => 1,
MinMaxResult::MinMax(min, max) => max - min + 1,
})
.reduce(|(a_min, a_max), (b_min, b_max)| (a_min.min(b_min), a_max.max(b_max)))
.map(|(min, max)| max - min + 1)
.unwrap_or(0)
};
(-1000..1000)
.filter_map(num_options)
.sum::<i32>()
.to_string()
debug_assert!(*y_range.start() < 0);
let y_max = -*y_range.start();
(-y_max..y_max).map(num_options).sum::<i32>().to_string()
}
#[cfg(test)]
@@ -162,9 +133,9 @@ mod tests {
#[test]
fn test_find_hit() {
assert_eq!(find_hit(2, &(-10..=-5)), Some(7..=7));
assert_eq!(find_hit(3, &(-10..=-5)), Some(9..=9));
assert_eq!(find_hit(0, &(-10..=-5)), Some(4..=5));
assert_eq!(find_hit(2, &(-10..=-5)).collect::<Vec<_>>(), vec![7]);
assert_eq!(find_hit(3, &(-10..=-5)).collect::<Vec<_>>(), vec![9]);
assert_eq!(find_hit(0, &(-10..=-5)).collect::<Vec<_>>(), vec![5, 4]);
}
#[test]

View File

@@ -1,9 +1,245 @@
use std::fmt::Debug;
use std::io::Read;
use std::mem::replace;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
use nom::branch::alt;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::multi::many0;
use nom::sequence::delimited;
use nom::sequence::separated_pair;
use nom::sequence::terminated;
use nom::IResult;
use crate::common::read_input;
#[derive(Clone, Eq, PartialEq)]
enum TurtleNumber {
Literal(u8),
Pair(Box<(TurtleNumber, TurtleNumber)>),
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
impl TurtleNumber {
pub fn add(self, other: Self) -> Self {
let mut new = TurtleNumber::Pair(Box::new((self, other)));
new.reduce();
new
}
pub fn magnitude(&self) -> u32 {
match self {
TurtleNumber::Literal(num) => *num as u32,
TurtleNumber::Pair(pair) => 3 * pair.0.magnitude() + 2 * pair.1.magnitude(),
}
}
fn reduce(&mut self) {
loop {
while self.try_explode(0).is_some() {}
if self.split() {
continue;
} else {
break;
}
}
}
fn leftmost_add(&mut self, value: u8) {
match self {
TurtleNumber::Literal(num) => *num += value,
TurtleNumber::Pair(pair) => pair.0.leftmost_add(value),
}
}
fn rightmost_add(&mut self, value: u8) {
match self {
TurtleNumber::Literal(num) => *num += value,
TurtleNumber::Pair(pair) => pair.1.rightmost_add(value),
}
}
fn try_explode(&mut self, depth: usize) -> Option<(Option<u8>, Option<u8>)> {
let pair = match self {
TurtleNumber::Literal(_) => return None,
TurtleNumber::Pair(pair) => pair,
};
if depth == 4 {
let original = replace(self, TurtleNumber::Literal(0));
let pair = match original {
TurtleNumber::Pair(pair) => *pair,
_ => unreachable!("Already checked for pair above"),
};
if let (TurtleNumber::Literal(first), TurtleNumber::Literal(second)) = pair {
Some((Some(first), Some(second)))
} else {
panic!("Too deeply nested turtle number: {:?}", pair);
}
} else {
match pair.0.try_explode(depth + 1) {
Some((left, Some(right))) => {
pair.1.leftmost_add(right);
Some((left, None))
}
Some((left, None)) => Some((left, None)),
None => match pair.1.try_explode(depth + 1) {
Some((Some(left), right)) => {
pair.0.rightmost_add(left);
Some((None, right))
}
other => other,
},
}
}
}
pub fn split(&mut self) -> bool {
match self {
TurtleNumber::Literal(num) if *num >= 10 => {
let half = *num / 2;
let other = *num - half;
*self = TurtleNumber::from((half, other));
true
}
TurtleNumber::Pair(pair) => pair.0.split() || pair.1.split(),
_ => false,
}
}
}
impl Debug for TurtleNumber {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Literal(num) => write!(f, "{}", num),
Self::Pair(pair) => write!(f, "[{:?},{:?}]", pair.0, pair.1),
}
}
}
// Helper traits to easily convert tuples to turtle numbers
impl From<u8> for TurtleNumber {
fn from(num: u8) -> Self {
TurtleNumber::Literal(num)
}
}
impl<T, U> From<(T, U)> for TurtleNumber
where
T: Into<TurtleNumber>,
U: Into<TurtleNumber>,
{
fn from((left, right): (T, U)) -> Self {
TurtleNumber::Pair(Box::new((left.into(), right.into())))
}
}
fn parse_turtle(input: &[u8]) -> IResult<&[u8], TurtleNumber> {
use nom::character::complete::char;
use nom::character::complete::u8;
alt((
map(u8, TurtleNumber::Literal),
map(
delimited(
char('['),
separated_pair(parse_turtle, char(','), parse_turtle),
char(']'),
),
|pair| TurtleNumber::Pair(Box::new(pair)),
),
))(input)
}
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<TurtleNumber>> {
many0(terminated(parse_turtle, newline))(input)
}
pub fn part1(input: &mut dyn Read) -> String {
let turtles = read_input(input, parse_input);
turtles
.into_iter()
.reduce(|a, b| a.add(b))
.map(|num| num.magnitude())
.unwrap()
.to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let turtles = read_input(input, parse_input);
turtles
.iter()
.flat_map(|a| turtles.iter().map(|b| a.clone().add(b.clone()).magnitude()))
.max()
.unwrap()
.to_string()
}
#[cfg(test)]
mod tests {
use crate::test_implementation;
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/18.txt");
#[test]
fn test_magnitude() {
let num: TurtleNumber = (
(((8, 7), (7, 7)), ((8, 6), (7, 7))),
(((0, 7), (6, 6)), (8, 7)),
)
.into();
assert_eq!(num.magnitude(), 3488);
}
#[test]
fn test_add() {
let input = TurtleNumber::from(((((4, 3), 4), 4), (7, ((8, 4), 9))));
let result = input.add((1, 1).into());
let expected = TurtleNumber::from(((((0, 7), 4), ((7, 8), (6, 0))), (8, 1)));
assert_eq!(result, expected);
}
#[test]
fn test_explode() {
let mut input1 = TurtleNumber::from((((((9, 8), 1), 2), 3), 4));
let output1 = TurtleNumber::from(((((0, 9), 2), 3), 4));
input1.reduce();
assert_eq!(input1, output1);
let mut input2 = TurtleNumber::from((7, (6, (5, (4, (3, 2))))));
let output2 = TurtleNumber::from((7, (6, (5, (7, 0)))));
input2.reduce();
assert_eq!(input2, output2);
let mut input3: TurtleNumber = TurtleNumber::from(((6, (5, (4, (3, 2)))), 1));
let output3 = TurtleNumber::from(((6, (5, (7, 0))), 3));
input3.reduce();
assert_eq!(input3, output3);
let mut input4 = TurtleNumber::from(((3, (2, (1, (7, 3)))), (6, (5, (4, (3, 2))))));
let output4 = TurtleNumber::from(((3, (2, (8, 0))), (9, (5, (7, 0)))));
input4.reduce();
assert_eq!(input4, output4);
}
#[test]
fn sample_part1() {
test_implementation(part1, SAMPLE, 4140);
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 3993);
}
}

View File

@@ -1,9 +1,355 @@
use std::collections::HashMap;
use std::collections::HashSet;
use std::io::Read;
use std::ops::Add;
use std::ops::Deref;
use std::ops::Sub;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
use nom::bytes::complete::tag;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::delimited;
use nom::sequence::preceded;
use nom::sequence::terminated;
use nom::sequence::tuple;
use nom::IResult;
use crate::common::read_input;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
struct Point3(pub [i32; 3]);
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()
}
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
impl Sub for Point3 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Point3([
self.0[0] - rhs.0[0],
self.0[1] - rhs.0[1],
self.0[2] - rhs.0[2],
])
}
}
impl Add for Point3 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Point3([
self.0[0] + rhs.0[0],
self.0[1] + rhs.0[1],
self.0[2] + rhs.0[2],
])
}
}
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],
rotation_index: usize,
}
impl<'a> Rotations<'a> {
const ROTATIONS: [[i32; 3]; 8] = [
[1, 1, 1],
[1, 1, -1],
[1, -1, 1],
[1, -1, -1],
[-1, 1, 1],
[-1, 1, -1],
[-1, -1, 1],
[-1, -1, -1],
];
pub fn new(points: &'a [Point3]) -> Self {
Self {
points,
axes: [0, 1, 2],
rotation_index: 0,
}
}
}
impl Iterator for Rotations<'_> {
type Item = Vec<Point3>;
fn next(&mut self) -> Option<Self::Item> {
if self.rotation_index >= Self::ROTATIONS.len() {
if !next_permutation(&mut self.axes) {
return None;
}
self.rotation_index = 0;
}
let axes = &self.axes;
let rot = &Self::ROTATIONS[self.rotation_index];
let result = self
.points
.iter()
.map(|Point3(coords)| {
Point3([
coords[axes[0]] * rot[0],
coords[axes[1]] * rot[1],
coords[axes[2]] * rot[2],
])
})
.collect();
self.rotation_index += 1;
Some(result)
}
}
fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
use nom::character::complete::char;
use nom::character::complete::i32;
map(
tuple((i32, preceded(char(','), i32), preceded(char(','), i32))),
|(x, y, z)| Point3([x, y, z]),
)(input)
}
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 = map(
preceded(parse_header, many1(terminated(parse_point, newline))),
Scanner::new,
);
separated_list1(newline, parse_scanner)(input)
}
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 {
let translated_iter = rot.iter().map(|&other| other - start);
if translated_iter
.clone()
.filter(|p| correct.contains(p))
.count()
>= 12
{
// Found a solution, build the correct output
let translated = translated_iter.map(|point| point + matched_pivot).collect();
return Some((start - matched_pivot, Scanner::new(translated)));
}
}
}
None
}
fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
let mut scanners = read_input(input, parse_input);
let mut points: HashSet<_> = scanners[0].iter().copied().collect();
let mut todo = vec![scanners.remove(0)];
let mut scanners_found = vec![Point3::default()];
while let Some(matched) = todo.pop() {
if scanners.is_empty() {
break;
}
let mut i = 0;
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);
} else {
i += 1;
}
}
}
assert!(scanners.is_empty());
(points, scanners_found)
}
pub fn part1(input: &mut dyn Read) -> String {
let (points, _) = parts_common(input);
points.len().to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let (_, scanners) = parts_common(input);
scanners
.iter()
.flat_map(|&first| {
scanners
.iter()
.map(move |&second| (first - second).manhattan())
})
.max()
.unwrap()
.to_string()
}
pub fn next_permutation<T: Ord>(list: &mut [T]) -> bool {
// Based on: https://en.cppreference.com/w/cpp/algorithm/next_permutation
if list.len() <= 1 {
return false;
}
if let Some((i, val1)) = list
.windows(2)
.enumerate()
.rev()
.find_map(|(i, window)| (window[0] < window[1]).then(|| (i, &window[0])))
{
let it2 = list
.iter()
.enumerate()
.skip(i + 1)
.rev()
.find_map(|(idx, val2)| (val1 < val2).then(|| idx))
.expect("Unreachable, ascending pair exists");
list.swap(i, it2);
list[(i + 1)..].reverse();
true
} else {
list.reverse();
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_implementation;
const SAMPLE: &[u8] = include_bytes!("samples/19.txt");
#[test]
fn test_next_permutation() {
let mut list = [1, 2, 3];
assert!(next_permutation(&mut list));
assert_eq!(list, [1, 3, 2]);
assert!(next_permutation(&mut list));
assert_eq!(list, [2, 1, 3]);
assert!(next_permutation(&mut list));
assert_eq!(list, [2, 3, 1]);
assert!(next_permutation(&mut list));
assert_eq!(list, [3, 1, 2]);
assert!(next_permutation(&mut list));
assert_eq!(list, [3, 2, 1]);
// Note the negation!
assert!(!next_permutation(&mut list));
assert_eq!(list, [1, 2, 3]);
// 24 is a bit too much to write out, but we can check the number
let mut list2 = [1, 2, 3, 4];
for _ in 1..24 {
assert!(next_permutation(&mut list2));
}
// Should be back to the start
assert!(!next_permutation(&mut list2));
assert_eq!(list2, [1, 2, 3, 4]);
}
#[test]
fn sample_part1() {
test_implementation(part1, SAMPLE, 79);
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 3621);
}
}

View File

@@ -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);
}
}

View File

@@ -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, &current, &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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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)
}

View File

@@ -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);
}
}

View File

@@ -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);
}

10
2021/src/samples/18.txt Normal file
View File

@@ -0,0 +1,10 @@
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]

136
2021/src/samples/19.txt Normal file
View File

@@ -0,0 +1,136 @@
--- scanner 0 ---
404,-588,-901
528,-643,409
-838,591,734
390,-675,-793
-537,-823,-458
-485,-357,347
-345,-311,381
-661,-816,-575
-876,649,763
-618,-824,-621
553,345,-567
474,580,667
-447,-329,318
-584,868,-557
544,-627,-890
564,392,-477
455,729,728
-892,524,684
-689,845,-530
423,-701,434
7,-33,-71
630,319,-379
443,580,662
-789,900,-551
459,-707,401
--- scanner 1 ---
686,422,578
605,423,415
515,917,-361
-336,658,858
95,138,22
-476,619,847
-340,-569,-846
567,-361,727
-460,603,-452
669,-402,600
729,430,532
-500,-761,534
-322,571,750
-466,-666,-811
-429,-592,574
-355,545,-477
703,-491,-529
-328,-685,520
413,935,-424
-391,539,-444
586,-435,557
-364,-763,-893
807,-499,-711
755,-354,-619
553,889,-390
--- scanner 2 ---
649,640,665
682,-795,504
-784,533,-524
-644,584,-595
-588,-843,648
-30,6,44
-674,560,763
500,723,-460
609,671,-379
-555,-800,653
-675,-892,-343
697,-426,-610
578,704,681
493,664,-388
-671,-858,530
-667,343,800
571,-461,-707
-138,-166,112
-889,563,-600
646,-828,498
640,759,510
-630,509,768
-681,-892,-333
673,-379,-804
-742,-814,-386
577,-820,562
--- scanner 3 ---
-589,542,597
605,-692,669
-500,565,-823
-660,373,557
-458,-679,-417
-488,449,543
-626,468,-788
338,-750,-386
528,-832,-391
562,-778,733
-938,-730,414
543,643,-506
-524,371,-870
407,773,750
-104,29,83
378,-903,-323
-778,-728,485
426,699,580
-438,-605,-362
-469,-447,-387
509,732,623
647,635,-688
-868,-804,481
614,-800,639
595,780,-596
--- scanner 4 ---
727,592,562
-293,-554,779
441,611,-461
-714,465,-776
-743,427,-804
-660,-479,-426
832,-632,460
927,-485,-438
408,393,-506
466,436,-512
110,16,151
-258,-428,682
-393,719,612
-211,-452,876
808,-476,-593
-575,615,604
-485,667,467
-680,325,-822
-627,-443,-432
872,-547,-609
833,512,582
807,604,487
839,-516,451
891,-625,532
-652,-548,-490
30,-46,-14

7
2021/src/samples/20.txt Normal file
View File

@@ -0,0 +1,7 @@
..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#..#.
#....
##..#
..#..
..###

2
2021/src/samples/21.txt Normal file
View File

@@ -0,0 +1,2 @@
Player 1 starting position: 4
Player 2 starting position: 8

22
2021/src/samples/22.1.txt Normal file
View 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
View 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
View File

@@ -0,0 +1,5 @@
#############
#...........#
###B#C#B#D###
#A#D#C#A#
#########

9
2021/src/samples/25.txt Normal file
View 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.>

27
2022/Cargo.toml Normal file
View File

@@ -0,0 +1,27 @@
[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"] }
itertools = "0.10.5"
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
View 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
View 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 = 4;
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
View 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

File diff suppressed because it is too large Load Diff

300
2022/inputs/03.txt Normal file
View File

@@ -0,0 +1,300 @@
NJvhJcQWTJWTNTFFMTqqGqfTmB
VwVzPldRZVLVRmfsvfjvqfmm
ZDPDHZHVcvDhbvnv
FHHwHBzzVCWWmmCzCPrVmgBwbLTtRFFbbbttRGRLjTcLpbbT
vhZZvdsNSdSMdNvjncppCLcLnGnj
CDZZsNZMZqdNSdlNZCqrzPHDzgrgzwVVWwmwwm
ndlndntsFJntFvccLjjLrjBShcBBfc
GpCGHzVwmmzqQWSSSfWHBhQL
mpCMGGCZVzVwGGVwmJsZnFtZnTSTJtdsvl
nCnPDGmDNmVCsVQDmGSWqvzchWSjjcWGqS
gTnBRLpfTRnrTdZgdLfRdrThvqcvWWhFFWvcFSSgjqqzjv
pfZfTMwrbLTTfsbmQtlVtHHnbs
wNdSdsbTvTZMTvTv
rrdRWdWQhFVdHWBGWQmmmnnMvCfmnhvmCmtZ
rJrVDRWpGddpbSlNSlspPP
chTNrthMMwWMTjfsmRzZszJpwm
BLnFFCngbcBnbbldDlpRjGpmsCzGsGsRGmmG
dqvnvlgbqtcPPMhH
QcLNqZbCzJDQBJJRpwzRpdnRldgnpf
GmmmvVGsHrWffrlwdCWd
CMsFVVFjCmFStGQbbLZNBbJBcTjc
LQVggbQvcLbQLHgvVLhWGGsChssrMWfzGccc
qDnRTTRqJttPfWMChJhGslWlzh
qRTRwPBTBtRZdnjnqqqnQVbjbNLFbbfLgVmgHLQm
cZbzwCwZPlJcMLrNSNfHWNBBNZ
vsQsDCqtsDhmtjVrBNWNjBHrhr
TtDTGnvTlgbbRCGg
BgBlplHlsgNNsJlVpBtPwJhMPRRQSSttRtSP
bvhTnmdFTzddStwStQRddt
ZnZDLvnvqZzbbhFzzmTbnFsVjVlNgsCCNVsVLpNWVgsB
TdptqrrcVGhhzFtw
DRnSfwJlDmmDDVGv
RCSQNSCQZndwbcMqQrBB
wvRlrlwVwwqzgbZRdCJBWfmdzCWfBdhf
cFcsQpNtLLsGTtNGpMdPmDdPBmmBvJPWvDtC
TpjssTFFvLLLcFFQpwbwwHngjHRrZRqZVH
mqqddrPPcPmqPDlrQnjTrbvMvbHzzsjjpTvz
gtBWgGgVhLGWHzMDztzstDHj
hfWRhBBNBGgLNQDPwdNPcPdw
LhQzdhhbTzpMhddhhhTzhnZcBFllHZFtrrHZHMHFjlHr
mwwssqDvjptrvplr
NCSgVDPDwmDgVJVpLfTznQJdhfLhnhQQ
GzjzDhjhhZzcrRgQCBjBPBBjQCgT
vHHHmntsbSgLwbsSmNHbwNbvpqPCBVppCpFTpTPTBtqWBCqV
NJbwNSwdndvmvwhGhgzcfMcDJfgJ
GncgDvvcMGnttjDvrgRRFSZZLZFWdJFJwGQwZBWZ
bPqpChPfsshfZZBdZdLTFZ
lNqqsClmbsNlPbHqPsmblmsrHdvdMngcVrjggvrvggRDcn
bDvtgVVVpMQvjQWmQL
rwTflmlfZJBBdQWQWjQqdM
HsJJmZZwscHrwTrcRbzpcbPgtCSbgz
CsCsRvshMjpbqCqf
ncblgDBgtDmmmTlBgwlgbHHqMFHLqPDMHPHHpqWfFM
TcBctSmTZTtSTzsZvsvJZRsGVb
znznvngttwltzlLwhtThHbqHPvNbNHSSHmmNWHjP
FBcLrRMFQpPqpPSpqHHW
fRQMJZJfrcMcMVrQJJftnwCzVCltgTnstTVnVL
MfLlRfCMrLzRlQgwNqQFcsGd
jtTjjBTvbdqcGjqFcj
vvShDSBDppzhCmzq
plWMptTvfrnncvcRfwqzqLGhzhzThNzNNJqD
jSdSHFPQQbdPCQCssjSbBmhJGNZZNGNqqJNBlJqqLh
VCCCVCQgjdddjCgljCjbbwgRRttgrpftfWrgvpwpnf
MWlbBcPjjvvjPWWMPqgRQZfJZDGGbRZJffQQwh
HrHrnncHpzrJQJfVDQVR
zzsSTtSTLzsspSdtTmHHmpmtFgqcgPlgFqWBqqqBMdWWvFlg
nSqBbJbqlnBBClVZcMgZVgcP
FQwrwHrRwWWFBRPNgNgcCGZZZC
rWFWFTwpwwWzHrnDbfJDLDbBBbbz
BMmNtLMMtFCNFNMvvLmcndpgcdgppPrgrGPPrgJD
WVWWhbTtVnGpjrrPhr
HWssSTHWfRHRsQQFLvfvFFCLCNMNlt
sTmDsQffVrrLCjTFltTFWL
BnwwQBJbJndMMRzMwCLlWlLWWCWLLtRlWF
cqqBMcMqwnznMGzcvDmQhrvssHmPDVssrP
pQGQGJDDrDVJbbfVzvvgPcCZwhZhncscZWWc
SqMMlBBljMmRlchhPTqThCZnPs
FMjMBmjRNFHQJJpHVhVDhG
tHNNdBdNtBBBMgsMpsZm
wVPzVvbwqzhrVqvjqzzsZpDsZDsZmsCPCgZgCM
bVbvLThvvbrWqHmmnJLdHdJQLn
PzTspPZpdLLDZTplPLpPDpvbfhnqNvqzfvNMzQQfNwnQ
GWRHmjmFWMMSnhbhHw
JWWcmtBrBtWBFWGJpsgTgldhLVLpJl
DwLMDzLMhvMcwvgdVqWWlCVgvlqF
TTSBBRpbStHZVgjWFldjRVlV
SnbTBdJBmnpQzMPDMcMznr
nNlMNBPPNtJQnbZhZsgSbh
czzCjcwTdvSbgQNcgNQq
VTdNdGDTzDTdlFFPtBrtLtDr
FMbbfMlzvFsmgVZmmg
SrNTHGmdSQDqLhtQhhgggs
dRDTSDPPcHRdHGDHlwJBbmwljmMcfjbW
sQgWLtqLtWhdqlpNZRpG
blTHTjlvTCJnJvRZdGGhHHGZhFGV
CCDlJclnCmbrmBMgcwcLWtcBsB
vqPWWvqwwCFvFZfZPRFRrcGQrQwsDrNcrwnbDNcQ
LVgJLSBBVtzTLzBMmTMJmLnnDNQcrsGbsQbNbrbDjs
zggVSmmhVdfqFhvHWG
WwdndGGmmmLwwwmRwWSncLRnZqZqhqZthBtqtBqZBgtdtvMH
FfHHzlQQDsFzzrNsVTfttZvTvttTqqtbqb
lQjFDNQFPjCsVCCDjGCwwSGGnccwcHppGp
mrjggcFsFMjdjZRpSZpn
NCqfLCFNbQPzPPlPzNfSRTRZdSdWWwndpqRSSd
vDvzzbPQFNCFtllLLNMBhMcDHGBGMggMmcBc
jhjlBvvnjbtDNPjtSjBDBbDNgHggrQrhghRQrqRrZcRwwqVg
pLdTMsWdLLmpMdqZZdPdVqZgHPwH
WLTCGmMLfPSlbGjlnnJD
gtbwhgHbHgqqbgQthgQLtZZCRjMcjjnRnrRNJmMRJrNhRc
bGWVTTvDvfpVFFBpvvVTdRDMJcrccCrJnMRnNnNCcc
FVWTBsdvdTzTBFWssVQtLgSQtHqqPzPbqHbw
dlzrPTSSjSrllzWhsvVmVtTRTWtf
bJMpLGcqGhNbJQttVQmmvRWWsp
qLbMwqqbGHFGzrlZrjhPHCrj
rNrrffVlqqrfLlPpltcBBTTGRzzZRPRsBTcJ
msbsmWSsMmQwjdMbWMhMhQmcRZRzGjTBGTBcBJBjCHJGcC
FwWbvdhbmrsFrfrgsN
rHjrQHdhdQrvSddcHWLssBSVVpBSWWWWWf
JNfTGtqDwVWBMBMpwM
qlltZgfJFvcRgcRjvc
CqfcwfDqwwmRnnqmRdNRBTRTRrdGdNpTvF
WVbzsZszBbrsvpdMpdQM
tJhbVZHWLLHDgnSwnSSgHB
TZCqqlTsqpZVVsZQJSBSLpLmppnJzmFz
brSgNtGjjRjRRjDddDtrRJcJJbJmmwcmBmnPcJFwFB
jgdRtMjNNjfqlMvShvSZSZ
dJTdqCwMNCgqTQllGBdlGBmmmZ
fcVfVcnbVfrwDLWVfncZBQPlBHRGljLZQjHGQl
brwnnfSFDvfzCTqFzgMJTh
njnsPBjjsrrnGLnbTTjGvcldQPCMllNzMvRQPCdd
ggZgfZtmZVpqZqZWDgFmgqfCcQRcRcWhQcccQddMcvRQdQ
tfqgggVgHpDwDtfwbGLJRjbLjsrLTj
JmrfrmTlDWTfgQCdHCdpqBvQdD
jsZtVzNsSNVQQHnBlVQR
PljljFjPljSsLPtFLTTgTcFrrfMJmrrmrr
hmGcmmndhmGnfmtGnDzFLwrFJQsQFzNFrNJG
ZSqPlSWcWlbgqWVTVWRVZPrjQqjzjFNJzLsNJsLJNqNL
RHcWTZbSMMMPgZcWgSWPPbVMDnBffmtdpDBddfnnvmCdfC
vSJvsbFfJfvqCsTHJswssJnLTZjjhzrrzLrzLMrzhdjM
pBNQDPcpmWDcBNgMMnZPVjdddnndhH
QWlDgmpmgDBlGRgDDgffSqwSwGCwHfvqwSFJ
jvlgvMJclPdGdtdcjMVmMHbFHFVHWHbZHZ
CwhLzLhzQpnqfpfqDVHCHbsbDFZDmHmj
LnBzfQjSzQrPvJvdSSrr
wpcvcsqclDCnVCVvWfnZ
BLRMRtbnbbBLNCjNCjVVZhbC
rFgMPSRnrRpmqpJwqFDs
LZQNQbMrZppLNLQplvlGLNvVmmmfjbwVCfjbwJwCmBCwfj
ShTPRFtTHZPCsnwswsFwCF
WtHRPdThSqZTRtDqtdRWTdpGDLLzrNczvzMGLlQLGDDM
hdcffBvldjhCMljqPwWwWNwWdwqHZr
LtQmbQRVsZQZMZPQSN
tmMRsJMpDhjJzJhv
wNQCMFCDQDBmrHmmRWrrHN
SShLnfqpcqpSZSfrzJvRVrvfrrJH
cRpqdGclpScltTQQtsFQMQsTCT
NCjggZmgfBgnBmgWbcwcTFctcWWfvb
HsDGthRGrtppSQpbFFJTVcJdFbTRvd
rPDGhDDrSzZLtzBLZMCB
RsBBMBsCBlFFCgRsBJzlMjMPNSdPhSrSrzLbmSDrDNmDSd
pZHZZJpGHHHpTTHvTncZqVLdqLbhLrDLdhrSLLbLDDdD
tGtwnJccvCtCffMBgt
wbddvVjfwPhbjjbDbbvbjvTNCNmfHZfpCZRJNzCmJmnJNC
BslcLtclZWsZJWNrRRNRpRmR
BSLBlScGtFMcssMBBFGLlQZTDZQjPddVwwbTdvvdhTZb
NSZHzmLZBnzHmLLzLSntDttDDtddhDtttDWW
QgfjsrrvNNJwtMddcvcvtq
jrfgfQpQrTTVLSNBClFV
GQWcWWPPQRcrJQNDdRcDmmLCFSnqNSmqhCNvFnql
zHfwjzpMjwZmCLqvvnlljC
ZgtVZBtHHZtgQGgPrbPRJdPv
TWdWpJTJTdgLWfWLlLFLrfrgBGsNqhGslBGHqSNqqBNshnws
ZpQmjzbZZCjZCCCPZtttRCCwsBnHNssBHbShsshHqsGBqN
RDRRPpPCzmZCtRpVVJFrfTfWFLLJggJrDv
pDDFlglsvFMgntlTMMqNffmTdfddRM
jhGJLVCHQpHGQCCzLjWdTTdZZdNdcRWNccWfNN
jQjSGjrjCQLhzVSLSCSHGDpngbrnDFtFBwBglBnBvg
wsLzstsgszcpcGLHGpcgcghlDBvQvjQvbFbQCbJBtCCJJv
mnSqRSSqSRThWRnmWWRSJDFTFCFCblbBCFQFCjFj
rZRRWqSSdZZfMVnZLspPsMgHpzMhHGPg
mwHrCLSWWwrsHCHDDsVrsmhfFZFnSSBlFlgZbbgBglbggj
GJdpcRtGJvNRdcPtdpJJdbQZfjfQBlnQBjnBtbfFnB
qcPpqqzFzJqvPVCCmWrVwhrWrz
jjMbvbhDvnRjNRGMmjbMZftSSwwwthJSffStctcwqd
lTQrVlpCVvCcfdcSJqLVcw
srHFWCHrFlrHlrsBsprljjRmDZZnmbDngNBgbNZv
MgTlQJlTQJZWpgLrRssrVqqqpRts
bBNbbzSSjMBPjzhMjsPtRVVRVPRqLttGGs
SjHBbfjNCDfjZgTlZdMJnDJW
lpThgTwtplhghgwhThqnnrdZctSZSjSZcRSRfbdrrc
RBVBGvmBmfdrcvrbbr
PmVGNGmmGRLLQwwLqTnglQ
nHwnBwBTnFHQwRsMhwghmzcm
GtprdCpdtqWdbqbrfdnPPszsWmRzRnShPszS
dGptbCfCrlnVDBJNLDLLVDLQ
CZtCjhTndCzqbCNq
dwpGvpsmwGslDszrNNrzqDMzWMgJ
vmcGccvpBVPTVTjTdTTTdZ
jWZhvZLjZfCZDwrDrSSzJGhVdJccscGsgV
blMBlRqqqgSJLBLcsJ
blmHLmFMMMnRqLmMMFqHmfPDfjQDnCDDQrZvfCjvDr
rnvnHrDLFZmMFLvrHQBMGQggBztzglplRl
sbWWhdNzsshsfhcsjJJPPbWdtQGVGllRTRjRRgBgQlpRlppB
PPCCwNWhPhNfWCzbqmFnDFFnCDLSrvZS
GChNjwWlWJWTJZBggvdgnQgdhdnd
HPsHfHHrpHDpFFrcSfsfpCMmQdntLBMgtmtBgDdLLC
SqpPscpPzpSWzjlCjjCGjl
nvgLvcLgvgvngbLprpJNTDCCRNVJrNPlDDTV
WZsMtsffGQtMzWFqFmWmWsVNJNlDwwCDVRTwJlCCDVLz
BQfGZGmmsMWFstWFmfMsfBccdncbpbSbvbbvHnLbpc
tsmDsvswNZmcZTccfh
zCTpGCbWBRWFWHGRFZJbMbJfnrhnhfMnnZ
TzFGFBRLdpHHNNQddDQDvwQN
fhBBpJgdHddjZQfmVmNzNNLmFN
qvMRrvlbwqlbTTMBMvLssFNmVzzwFDmLLzVD
TRSRWqRRMcBHhGHcdGgPGp
lSjHmtmnpHStblnpSlHSrtmMzLWzqzqCZDDTzTTWqMFqCqVV
sLRLLfPPRQfCTqqVVqFT
dNJgRPNQNsJJhBRvdJvQvNNsjSrrSmrcctpbpHtBrBjLjmSH
nwFwpppjfwSlpLTsqsTgNshhjM
ccBRGvtsmgGNPqNNGP
BCcJHvssdcWBCVmVHSSrZrwVzblpwbzZnf
rcfQRrBPPczjcRBctZDNlnVNHbgZGjVDjN
TvMsFJGSFMhJnNZlwVVnDNTZ
qhSqqmqLCLhFdJLqSvLhmQRQRWcRPczPtzrCrWGRBp
JVhdPhsFPFqLDBHVdHLPvhHDCMwcgJJwbwRgnnCMbwGwcmGC
fzjzpTZTQQQLwCbgGgbMmQcR
jzNpTzfSZtfNSWZlVVtdFFFDHHqLHVqv
TwSNnSnSGVTpNppGlPTlTcVqQrRhVBqdqBRqZqQZqQ
DcDCMfDbCMHJdrRBqbdjRBRZ
gvftMCJHcHfCDmDLgfMmMmmWlwWnWsTTwlGTlWTwppNlGL
pbGMbllDQPhhWWQDpPgVGlMCvRRrQLcCCcfBBQzLBcvQBv
wqnJjSmjrstdqwwFBLcRsBRRszzLFC
qwdddTJTdHtjndqJqHZHmwVWGpDbGTlbWWpWWrPGhhhM
WGllqLjjLCpSffmBmvfpHs
dnrQwZzRTdZwnCThdzzFTVmcBHBJBmsHfBPHcfvcSVHs
QgQrzCdrTRCZzrZLbjGLqNMWGgNNLt
sgPnhPPTTPTTwlJfwNHlqcfs
LMCpFbLLbRpMGbMcCFLVlNlNqrHqVfbHHwNDwr
GjBcCCtWMtMRZTSvgWQTngvg
BCMtJJMpRDlMMvBJBBnfjtcjPhPmZgnhgdcf
NrsrsqFNvrVLVGVrsHsqFgfmcPGdcmhfjdPgfjcnZd
zFTzsNqHqFssLVLQqNTFbsBDwCCwvWlDwRMRCTRBDMDS
zQtLgvggSRtgvVRtLvvnzdnjnGwGdmmrlpnlGz
JssBFpqsDqPNnlWWjrrjqrnj
DHDFBNDfPbJBsFHNMPvpvStQvMRVTtgVTVtv
FvzttFvBTJJzLbvwhCnnVnWwjCnBNC
mQdZgZPDPdPPSsMSQPdZgCwVGmnwnWpGnGhqNWjWCG
ggdDgfQSdcjtFHjlLJfF
ghcgScNNSsCvGSzmpVFlZbrzcFcV
MWWRLRqqqdQwTtLjjmqMlFpFlzVnbFVDwplFzlDr
LHMHqdHWjdQMdMtLHHLtWjJRsGCGSNghmSvPBJBNhsGfvfGP
CbVqqqDbcbMHnnDqcCbrRFCfBvvwGjzrBwQGzrwwBjGwBQ
sTPmpNWdWPTJssSSLPfNljjBvflGtjwwBzMG
mmWgmgSZLTLMZWpnhqZbhFFCnhqnnn
QQmjmZqnmQrfTZlbbcVbBcfbHfzf
vpdSNShNppFdSRtdGBqvJBDlDzqbPPHVBH
tRNSNRFhNpSRhFRMFtGhRGswLZZsZqWnmrmZwqwsTZmmmQ
gGWCllFCGWtGGWdlGlWNZdwpnnSbwpMvpphZpndn
RsshDDLcQVMSJQwJwnvw
HVPzrPcDNhPFGhPC
jtHQGHjGGtdTLjnqTQlmvRPRPBBwRBnFPPWP
hZbzNzVrczZzcbNssVspZZVvBwbmPmJPWmvbBRvPlmvRJF
fzNVDsZMhzpVhpVhlZcMNfcDDdQTLTjGDTCqGCjtSQHdHL
GrbFggGrTrzSrgfwJjdTmwmNJZJd
VMPQplPDptchwdsjmlml
MqMWtBDPPWDWHQtvqQtWPjbzCGLgSBgGbzgrzFgnnz
fcJccCcwcDfcpbRnCfWJnQJqtqtqPQdsGdgPsgTQqg
LSjVMhzSFFrljdNbltNGtgdqQq
MMhSHFFMLzBWDcHHcfcHwb
rwmWtJWMwSNRJMtwNmMrrSsmtTjjlgqnTqZZZPlHnTngTTgn
BGqGqqFBFggjjdGHlj
QDhhLbDQCDFMNcmhRhqJNW
BnRnRvMnLGLSCHvvSnlRfWbbTNQJsJsbNbJTBfQT
tzMmmMwjhcpFjDmMcptrcjzFQggfQPTsWsfgNbbgfhJbPhQT
FdzcrtDwDMtcwtFGRZdRLvdnHRSZZv
HVpsSpvjpNjsBmbGFBnMNnDM
WRRWhZtfrVtLJrBZMnDmDbnZBTGF
thhPLzWzhzwPtLRLWrQlpPvvClcVcCppSvpl
lZPbhnZLRPnnPZZPdlGMBWcBMgMQHBBcvvvzBL
jpFjmwwwCDDbsjvjjgcvQgcNBQ
rbFmppbwhqhGRGZr
ggrLwFgWCBwbMWBbFwLMgNBZdmZHclJPllnJlNRPmSNZRR
ppszzDfhDfhsqpnvDVTfGpSPlPmclHcdRcZmmmdPPGSP
pvtDDVDVpqDfzDfngBLCwQrgCtCwFwrg
pbGjFFGGDjpbsGsmNhNFNRBBBtRhhhHv
JnczJVCvwWJvhPgghgNtNtNJ
nwVSSzdzzqSpvQSZQG
mssLLttQrsMrMzLCRmMmrrSQpvWpDNlBTBDlvNTccDQl
HdHJwJqVPwHnqJwbjJbGjnSgSTWPpNgWWpgBBgcvDWWN
ZHVwVZGwwdndqJVJqfHbGwnwrRLtLMftMvMMRrhmLMthhLmz
RgHGLbTqlZlPRZPHfvvfZttJnvfvjnzr
sVcChDVDccwNhhvjTvVzWJjnzFff
mpNcCMTCGmLqBLGH
wVJwHJHVMtMpBmDDWPQVPWDGDD
zCrlZzCblBvnCDWNGLmvGDLPNG
dqZglgbzrzbbgZqzTFSBHHFJSSSfjjSMfwhj
NMWJSjLMCnHHNMNNHWCHMbVVGBPZTrPVPBVDrBSDGTTr
zvttlFpgdtldwwvftPDPTWQdBZrsrWrGBZ
hFlFmhRFvfCbmWJWHcnj

1000
2022/inputs/04.txt Normal file

File diff suppressed because it is too large Load Diff

106
2022/src/common.rs Normal file
View File

@@ -0,0 +1,106 @@
//! 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))
}
}
}
}
/// Return the minimum and maximum of two unordered variables
pub fn minmax<T>(a: T, b: T) -> (T, T)
where
T: PartialOrd,
{
if a < b {
(a, b)
} else {
(b, a)
}
}

50
2022/src/day01.rs Normal file
View File

@@ -0,0 +1,50 @@
use std::ops::Add;
use anyhow::Result;
use nom::character::complete::newline;
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)
}
pub fn part1(input: &[u8]) -> Result<String> {
let elves = parse_input(input, parse_elf_list)?;
Ok(elves.into_iter().fold(0, Ord::max).to_string())
}
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");
}
}

125
2022/src/day02.rs Normal file
View File

@@ -0,0 +1,125 @@
use anyhow::Result;
use nom::character::complete::newline;
use nom::combinator::map_res;
use nom::multi::many0;
use nom::sequence::separated_pair;
use nom::sequence::terminated;
use nom::IResult;
use crate::common::parse_input;
#[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_plan(input: &[u8]) -> IResult<&[u8], Vec<(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)
}
fn parse_line(input: &[u8]) -> IResult<&[u8], (Rps, Rps)> {
separated_pair(parse_rps, nom::character::complete::char(' '), parse_rps)(input)
}
many0(terminated(parse_line, newline))(input)
}
pub fn part1(input: &[u8]) -> Result<String> {
let plan = parse_input(input, parse_plan)?;
let result: u32 = plan
.into_iter()
.map(|(them, us)| us.score() + us.score_against(them))
.sum();
Ok(result.to_string())
}
pub fn part2(input: &[u8]) -> Result<String> {
let plan = parse_input(input, parse_plan)?;
let result: u32 = plan
.into_iter()
.map(|(them, us)| us.score_result() + us.needed(them).score())
.sum();
Ok(result.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")
}
}

79
2022/src/day03.rs Normal file
View File

@@ -0,0 +1,79 @@
use anyhow::Result;
use itertools::Itertools;
fn priority(item: u8) -> u32 {
match item {
b'a'..=b'z' => item - b'a' + 1,
b'A'..=b'Z' => item - b'A' + 27,
_ => 0,
}
.into()
}
fn seen(backpack: &[u8]) -> u64 {
let mut seen = 0;
for &b in backpack {
seen |= 1 << priority(b);
}
seen
}
pub fn part1(input: &[u8]) -> Result<String> {
let mut total = 0;
for line in input.split(|&b| b == b'\n') {
let (first, last) = line.split_at(line.len() / 2);
let seen = seen(first);
for &b in last {
let prio = priority(b);
if (seen & (1 << prio)) != 0 {
total += prio;
break;
}
}
}
Ok(total.to_string())
}
pub fn part2(input: &[u8]) -> Result<String> {
let mut total = 0;
for chunk in &input.split(|&b| b == b'\n').chunks(3) {
let mut mask = u64::MAX;
for backpack in chunk {
let seen = seen(backpack);
mask &= seen;
}
if mask != 0 {
debug_assert_eq!(1, mask.count_ones());
total += mask.trailing_zeros();
}
}
Ok(total.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/03.txt");
#[test]
fn sample_part1() {
assert_eq!(part1(SAMPLE).unwrap(), "157")
}
#[test]
fn sample_part2() {
assert_eq!(part2(SAMPLE).unwrap(), "70")
}
}

75
2022/src/day04.rs Normal file
View File

@@ -0,0 +1,75 @@
use std::ops::RangeInclusive;
use anyhow::Result;
use nom::bytes::complete::tag;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::multi::many0;
use nom::sequence::separated_pair;
use nom::sequence::terminated;
use nom::IResult;
use crate::common::parse_input;
type Assignment = RangeInclusive<u32>;
fn parse_assignments(
input: &[u8],
) -> IResult<&[u8], Vec<(RangeInclusive<u32>, RangeInclusive<u32>)>> {
use nom::character::complete::u32;
fn parse_single(input: &[u8]) -> IResult<&[u8], Assignment> {
map(separated_pair(u32, tag("-"), u32), |(start, end)| {
start..=end
})(input)
}
let parse_line = separated_pair(parse_single, tag(","), parse_single);
many0(terminated(parse_line, newline))(input)
}
fn is_contained(a: &Assignment, b: &Assignment) -> bool {
if a.size_hint().0 > b.size_hint().0 {
a.contains(b.start()) && a.contains(b.end())
} else {
b.contains(a.start()) && b.contains(a.end())
}
}
fn is_overlapping(a: &Assignment, b: &Assignment) -> bool {
b.end() >= a.start() && b.start() <= a.end() || a.end() >= b.start() && a.start() <= b.end()
}
fn parts_common(input: &[u8], filter: impl Fn(&Assignment, &Assignment) -> bool) -> Result<String> {
let assigments = parse_input(input, parse_assignments)?;
let overlapping = assigments.into_iter().filter(|(a, b)| filter(a, b)).count();
Ok(overlapping.to_string())
}
pub fn part1(input: &[u8]) -> Result<String> {
parts_common(input, is_contained)
}
pub fn part2(input: &[u8]) -> Result<String> {
parts_common(input, is_overlapping)
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/04.txt");
#[test]
fn sample_part1() {
assert_eq!(part1(SAMPLE).unwrap(), "2")
}
#[test]
fn sample_part2() {
assert_eq!(part2(SAMPLE).unwrap(), "4")
}
}

9
2022/src/day05.rs Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,5 @@
use anyhow::Result;
pub fn part1(_input: &[u8]) -> Result<String> {
todo!()
}

91
2022/src/lib.rs Normal file
View 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
View 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(())
}

View File

14
2022/src/samples/01.txt Normal file
View File

@@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

3
2022/src/samples/02.txt Normal file
View File

@@ -0,0 +1,3 @@
A Y
B X
C Z

6
2022/src/samples/03.txt Normal file
View File

@@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

6
2022/src/samples/04.txt Normal file
View File

@@ -0,0 +1,6 @@
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

View File

@@ -1,6 +1,6 @@
# Advent of Code
[![Advent of Code 2021](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml/badge.svg)](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml)
[![Advent of Code 2021](https://github.com/bertptrs/adventofcode/actions/workflows/2022.yml/badge.svg)](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)