63 Commits

Author SHA1 Message Date
561fd2f07c Replace collecting then computing by reduce.
This is a bad idea; it's actually slower
2022-12-02 09:23:02 +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
dfd8b2b985 Partially smart, partially brute-force day 17 2021-12-17 10:04:36 +01:00
0f6167e90f Merge common parts of parsers 2021-12-16 19:26:10 +01:00
3e2a3f5206 Avoid allocating and tracking bits manually 2021-12-16 19:12:34 +01:00
8cc2245492 Optimize hex parser 2021-12-16 18:46:19 +01:00
fb167ef899 Implementation day 16
Not clean but it works.
2021-12-16 09:55:53 +01:00
4240f8fc8c Avoid queueing worse routes 2021-12-15 18:40:20 +01:00
9a4ac427e0 Use Dijkstra instead of A*
The available distance heuristic doesn't save enough steps to offset its
overhead.
2021-12-15 18:29:08 +01:00
c3929a56d8 Slow implementation for day 15 2021-12-15 07:54:14 +01:00
9e37026f30 Remove unnecessary indexing 2021-12-14 19:54:45 +01:00
a926243f0d Improve "winning" logic
You don't need to check every possible win condition, just the one you
touched.
2021-12-14 19:51:57 +01:00
a35ae82548 Replace unnecessary HashMap and allocations 2021-12-14 19:39:00 +01:00
88 changed files with 10454 additions and 162 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"
@@ -16,6 +16,10 @@ criterion = "0.3"
# Keep debug information in release for better flamegraphs
debug = true
[profile.bench]
# And same for benchmarking
debug = true
[[bench]]
name = "days"
harness = false

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 = 13;
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/15.txt Normal file
View File

@@ -0,0 +1,100 @@
5698271399793414121494916897678273334792458352199237144928619653191794144917556817941885991921787155
5661218626919981949139858312691785612259857529334128895157352159114297128511813456894839991981828919
1829946539172173769987529428979213588624889988719998181167931129997731961946189278688942251875931179
1999119539431115938818955166792951461581819916221516821681692884358864981966117818421936138119178448
8248487982679211958329811353187936515794549929583184191911666793879132359192179796818752613119298188
7391613611139499971186919159397755657961352334771192112294557688911149919935819422199281134255797767
8124729396114568961156298172414395681961627813193215526122172712983935817479529728239799416288287177
9649211889945273498525484578866135611815817899936588391937238711562851327977738262898917714539618992
1141741151396594515311116985514997126571483473844951949329748922961996548324126664446185813879832188
6514441248746823748338931782958583948711212951974131921212693782738511196996128897191782852921157717
9391886829151987712527174199971418888695457266233516772351113144394198243117872737133772919969819519
1198331423874598397283651925996811591794589456846981969193281925566799829729889189889897828398875973
3993119331859999411778999198997168314599391886293921999193929916292896686191667979558511312556596894
4885648184914319438678987185948358172121994124174189148399374584265796556987819754991475787318732495
7161834654516953633561499967999394938799899319729924222599794975138255185728879581989683917238688499
5984849949933778929823916964338381451782979977879923213397398539961494556984787412996655398495998949
5715125898984926281417488864215481241818325728147899985999237792243119997919523716364219919384984139
9859999616929285298541192766179418656994667513839176241589982149119397731438826191347741844116719249
8175137179841286592241832831664588945248987741981849615626887738291971771877815459199919596297762924
1195455998712612867139126669399111711242319181378472389957511612195887919281465911167399661193991259
6683294289715197916912936717981879539595921479689377149531198421412217683129512395995551899999253636
4384549778929184387719457231348656645896889888925317219969479184937844937194733193727596993257773958
3276812228776279165124713927385779131439398642869891821824228691957821333121694837396724995969152871
9919942131189697791118151719399685129324814276422561998279371918941781591744772893513849374159719689
9381491523919433281119518148692169889399181847183427693123932741321897894329241437714386791132191185
9491214195479284697132149999835916255594317799411165638929858419125934487114527249742829613155512959
6311661999995998283745198816594176551398793726177951929118916489667398222393341857119652996537191216
6982112288787347411291733589694945315895949612819676734199121729449261277878511178985354939268994351
3674562711198699238983994755221985299338191681822892997159181992896128148896975971957144448941814152
9899194386288999913747123919122811877922937176682999664964885597922734185747279621687621731836928862
2116816742597199191219978826825994722615889928911124939448369538185829869273435191136937156632583851
4349941568369745619775621261571293998779732985286699593958874613332787391776856914459351828283129499
2139545889871837989617135399996761155985919219131927394712919919165898258917812865693299999372143937
2797918178177159361299151932139531949921215449467992544898132943871367946184259699282519985747111894
1486233998921528551532861544482468798798911836599829829996424887757819971589876285997126989165281171
8861164846365591334792621191572483286587764653747651579926829499721832813168648324199795414996798928
9291853568543999152479124588672419544474748794822216282929683566381835292497918418175413139195238875
4459193479395871171969518189835778911861995829613879912466644113246996925946217134981986998535612761
3917415977315473896693284392244697742378915475693115524188981984797471519797297767819983299114674163
9479997975888641554837851979187615719199134617129683999813865847829191959434496893219481276491982115
1192917311668797426356261998346738779982194786382977926498879633266998527258133639952619989139917922
7719288735263969519584635229174517995733918532265569199269899656492443157891869119696416131629593639
2184119869185523966813259979736987537578526292398798983845392291835172615194758136222947294271887893
8729953944813191318117475998726288371635861354847924941923488971912998769489173795899411912899358291
4865718997911481411828882919717899614955999831128828316982172988928635967691754477941769257918149225
2993917151292413828544861759731699793999794939134673192415919816989946192187733812832551933836349353
2392657723121896915129994993779197965282385759494924426239478311328999729999373913937519813997858629
1231999494818876979724169419419112419866229157682954926121898668165939174414423891657921992944249919
9918532449129634933779591992923399274618345391686218726361524731393799762548689548319471496829728796
9998799217976696793819516835698899484118485923118178917448293998592525822132531922781281129488216397
5192761493599676289836184964748349843714842349297638881284681117695677295987225931879393958925236789
7268883329987412183226822596174125816931195839329615165616819294836862793251385934133841918139897811
6965568945376938749193143429716268629281259918717113392767177211856962116259137767717711199819531318
9946637998921258586362681893277981845668197589625911332226897948938743394789819211693113189244919914
4871851551891469283341781775791494521158119524555886558545149797364636497391519989229278417113895118
1345983432979827816668993821658815763434864899249549719186967999197848321762371279955891998781349927
6314411929798522969667512333572214219998191666968187141597233789569459669912829965921239279371936316
3992169277898367859361361786747537912321799661448888219875991399581567758199888738334192143862413181
2222496914541859183177213262919191272991899639234997678238191986198749293843119619698119988293199525
5915371189328353219855382685759969775542849935211982181425259529898186916649392484997392838711191117
8169587973671717318581118999998425389847631991852491196188179989154396999942138113786691868241134889
5344685492577218115877995132456423826951924968919925139319849473936971671795487241479296442941929811
1251739861149952116921832956986111819961136698717996819282184146866727525158711738228839674622782386
9847314199798528792466291586899159199338477391961835887792183113688154215493472212798899991864295742
5257272784491799827451173416779878548132798785993631488174276918175531348892491918523719192299467898
7992979991181179831169821468119411577879187992796818917682661441819267843277919392835983139489719471
4128797488218887928681673379728116122642549998949328966228125433858567196198751462818891984938354911
3475959599312382511869439189922686358873981983568449243997159614192913999914236993319949291439999198
1517571791296243999998371134995497132685919198842128735596841665424591185199389913668775951218689423
5654967112585715992259299352411729124559287912759919919348673481869219527276935916149899615111454338
7959995196194629598269761799738458135587969367688876114561929169848572742199927976195348111813159694
8341237826999851918267518141919121565937312914613679117869654472139112992413357268683764935191892197
9191144725134452491124119549826718699739659572818352415387359897217137915122751995997915493159884984
6114992423997191951469189895299879231999121815923893319995434539493649119619119321913937699983662725
8691733293139727547586431961128887545859836374323612455831994799481883935133399817678718165893368111
9561258499233959148319937411137559674714812297689646923979591185916186723579892829686891551677119835
3817583836164917989158856146991679117129286763822991921599939389559162988815144775134949221893987156
8869393821317962938731194192326717912615937839319191487729718951863811937788448721968368554499469998
9779931174618997891716996479823339528914111348193299619911134519591869598192982377992849895786861628
9228849524211171112561193761591642939783616849941114962751144449512592397581717151998199129916399569
3681981471397593418983945941198912291467516143121382229831485899639873221948653399284748979865113829
4511319899177843659998889999335128559884168939718989492987161554392999453863694462822117736248363914
6889791329888928324783251893783438993799912282811711691692819391686821652429416117277191688919199791
1813466918799319576952728154162197258151141791197279928841612511822193355919372971629299829231292443
6929796618267421196847896679863622321769172269232621692961879886142891298588221949715178615764931656
2181488467213697845251891984157371193949716425395214118928493219545175866269193351849171839139818194
9145886424872389992784162159124115362691198296549871231961989118911915871253826391146992645811797217
7261813715196955953539695411269291743513585462916998619485955985198911978299891114856577679915119891
2395375323918811172993132575669768211797188142297317469339437887956823821249292252996118812429293966
3493698117398613593295939911464991949189591628859269618891373198822876449981519279397383938445938961
7188399498811299474499795927858692591488691212476189948484913298291739588851722167749543818816918814
6639711919811875921558499577359957913939617544713997397137148176493159178897792388987517214382594658
9868637769618335566138613187813295523435485163161618919397998236266915715199319761642818478856959385
1181969758279137971179348866926365624188612783894276496899793241258119122436174649949517195172514793
6282561199121299888181471164167212292274611428169718849631799674421998399218169533259817922649993996
7892189127116936145295482897726952912496729194898291625689311833439971918991813338319988542899569332
1984849148728139499199899219892824339819797636941197152362487518771542766624971973432971739847999929
1389955743198821981998929159786983988371511612124611537771554447966118799114165127857297139873268292
7114948568589988719191915583826591117862589116475856191177131841299229935172958819245872994369999426
4275554996585879411196552781973718511282969951492149869419418957345666452981882879663949917972311592

1
2021/inputs/16.txt Normal file
View File

@@ -0,0 +1 @@
620D49005AD2245800D0C9E72BD279CAFB0016B1FA2B1802DC00D0CC611A47FCE2A4ACE1DD144BFABBFACA002FB2C6F33DFF4A0C0119B169B013005F003720004263644384800087C3B8B51C26B449130802D1A0068A5BD7D49DE793A48B5400D8293B1F95C5A3005257B880F5802A00084C788AD0440010F8490F608CACE034401AB4D0F5802726B3392EE2199628CEA007001884005C92015CC8051800130EC0468A01042803B8300D8E200788018C027890088CE0049006028012AB00342A0060801B2EBE400424933980453EFB2ABB36032274C026E4976001237D964FF736AFB56F254CB84CDF136C1007E7EB42298FE713749F973F7283005656F902A004067CD27CC1C00D9CB5FDD4D0014348010C8331C21710021304638C513006E234308B060094BEB76CE3966AA007C6588A5670DC3754395485007A718A7F149CA2DD3B6E7B777800118E7B59C0ECF5AE5D3B6CB1496BAE53B7ADD78C013C00CD2629BF5371D1D4C537EA6E3A3E95A3E180592AC7246B34032CF92804001A1CCF9BA521782ECBD69A98648BC18025800F8C9C37C827CA7BEFB31EADF0AE801BA42B87935B8EF976194EEC426AAF640168CECAF84BC004AE7D1673A6A600B4AB65802D230D35CF81B803D3775683F3A3860087802132FB32F322C92A4C402524F2DE006E8000854378F710C0010D8F30FE224AE428C015E00D40401987F06E3600021D0CE3EC228DA000574E4C3080182931E936E953B200BF656E15400D3496E4A725B92998027C00A84EEEE6B347D30BE60094E537AA73A1D600B880371AA36C3200043235C4C866C018E4963B7E7AA2B379918C639F1550086064BB148BA499EC731004E1AC966BDBC7646600C080370822AC4C1007E38C428BE0008741689D0ECC01197CF216EA16802D3748FE91B25CAF6D5F11C463004E4FD08FAF381F6004D3232CC93E7715B463F780

1
2021/inputs/17.txt Normal file
View File

@@ -0,0 +1 @@
target area: x=14..50, y=-267..-225

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

@@ -1,94 +1,92 @@
use std::collections::HashMap;
use std::io::Read;
use crate::common::LineIter;
use nom::bytes::complete::tag;
use nom::character::complete::multispace1;
use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::preceded;
use nom::sequence::tuple;
use nom::IResult;
use crate::common::read_input;
#[derive(Debug)]
struct BingoCard {
ticks: [[bool; 5]; 5],
mapping: HashMap<u8, (u8, u8)>,
}
struct BingoCard([(bool, u8); 25]);
impl BingoCard {
pub fn cross(&mut self, num: u8) -> bool {
if let Some(&(x, y)) = self.mapping.get(&num) {
self.ticks[y as usize][x as usize] = true;
true
} else {
false
}
pub fn cross(&mut self, num: u8) -> Option<usize> {
self.0
.iter_mut()
.enumerate()
.find_map(|(pos, (ticked, x))| {
if *x == num {
*ticked = true;
Some(pos)
} else {
None
}
})
}
pub fn has_won(&self) -> bool {
pub fn has_won(&self, crossed: usize) -> bool {
// Check horizontal lines
if self.ticks.iter().any(|s| s.iter().all(|&b| b)) {
if self
.0
.chunks_exact(5)
.nth(crossed / 5)
.unwrap()
.iter()
.all(|&b| b.0)
{
return true;
}
// Check vertical lines
(0..5).any(|x| self.ticks.iter().all(|row| row[x]))
self.0.iter().skip(crossed % 5).step_by(5).all(|b| b.0)
// Diagonals do not count
}
pub fn remaining(&self) -> u32 {
self.mapping
self.0
.iter()
.filter_map(|(&num, &(x, y))| {
if self.ticks[y as usize][x as usize] {
None
} else {
Some(num as u32)
}
})
.filter_map(|&(ticked, num)| if !ticked { Some(num as u32) } else { None })
.sum()
}
}
fn read_input(input: &mut dyn Read) -> (Vec<u8>, Vec<BingoCard>) {
let mut reader = LineIter::new(input);
fn parse_numbers(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
use nom::character::complete::u8;
separated_list1(tag(","), u8)(input)
}
let numbers: Vec<u8> = reader
.next()
.unwrap()
.split(',')
.map(|num| num.parse().unwrap())
.collect();
fn parse_bingo(mut input: &[u8]) -> IResult<&[u8], BingoCard> {
use nom::character::complete::u8;
let mut bingo_cards = Vec::new();
let mut card = [0; 25];
while reader.next().is_some() {
let mut mapping = HashMap::with_capacity(25);
let mut parse_num = preceded(multispace1, u8);
for y in 0..5 {
reader
.next()
.unwrap()
.split(' ')
.filter_map(|s| if s.is_empty() { None } else { s.parse().ok() })
.enumerate()
.for_each(|(x, num)| {
mapping.insert(num, (x as u8, y));
});
}
let card = BingoCard {
mapping,
ticks: Default::default(),
};
bingo_cards.push(card);
// fill doesn't work with preceded
for num in &mut card {
let result = parse_num(input)?;
*num = result.1;
input = result.0;
}
(numbers, bingo_cards)
Ok((input, BingoCard(card.map(|x| (false, x)))))
}
fn parse_input(input: &[u8]) -> IResult<&[u8], (Vec<u8>, Vec<BingoCard>)> {
tuple((parse_numbers, many1(parse_bingo)))(input)
}
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 {
if card.cross(number) && card.has_won() {
if matches!(card.cross(number), Some(pos) if card.has_won(pos)) {
return (number as u32 * card.remaining()).to_string();
}
}
@@ -98,14 +96,18 @@ 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();
for num in numbers {
for (won, card) in bingo_won.iter_mut().zip(bingo_cards.iter_mut()) {
if !*won && card.cross(num) && card.has_won() {
if *won {
continue;
}
if matches!(card.cross(num), Some(pos) if card.has_won(pos)) {
*won = true;
num_won += 1;

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

@@ -103,7 +103,6 @@ pub fn part2(input: &mut dyn Read) -> String {
parts_common(input, 40)
}
#[cfg(test)]
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -1,9 +1,157 @@
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
use crate::common::LineIter;
type Point = (i32, i32);
struct Map {
width: usize,
data: Vec<u8>,
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
impl Map {
pub fn from_input(input: &mut dyn Read) -> Self {
let mut reader = LineIter::new(input);
let mut data = reader.next().unwrap().as_bytes().to_owned();
let width = data.len();
while let Some(line) = reader.next() {
let line = line.as_bytes();
debug_assert_eq!(line.len(), width);
data.extend_from_slice(line);
}
data.iter_mut().for_each(|b| *b -= b'0');
Self { width, data }
}
pub fn from_input2(input: &mut dyn Read) -> Self {
let mut reader = LineIter::new(input);
let mut lines = Vec::new();
while let Some(line) = reader.next() {
let mut line = line.as_bytes().to_owned();
line.iter_mut().for_each(|b| *b -= b'0');
lines.push(line);
}
let mut data = Vec::new();
let width = lines[0].len();
for _y_repeat in 0..5 {
for line in &mut lines {
data.extend_from_slice(line);
for _ in 0..4 {
let starting_pos = data.len() - width;
data.extend_from_within(starting_pos..);
let starting_pos = data.len() - width;
data[starting_pos..]
.iter_mut()
.for_each(|b| *b = (*b % 9) + 1);
}
line.iter_mut().for_each(|b| *b = (*b % 9) + 1);
}
}
Self {
width: width * 5,
data,
}
}
pub fn shortest_path(&self, start: Point, end: Point) -> u32 {
let mut todo = BinaryHeap::new();
todo.push(Reverse((0, start)));
let mut best = vec![u32::MAX; self.data.len()];
let height = self.height() as i32;
while let Some(Reverse((distance, pos))) = todo.pop() {
if pos == end {
return distance;
}
if best[self.index(pos)] < distance {
continue;
}
let (x, y) = pos;
for dy in -1..=1 {
if y + dy < 0 || y + dy >= height {
continue;
}
for dx in -1..=1 {
if x + dx < 0 || (x + dx) >= self.width as i32 || dx * dy != 0 {
continue;
}
let new = (x + dx, y + dy);
let index = self.index(new);
let new_distance = distance + self.data[index] as u32;
if best[index] <= new_distance {
continue;
}
best[index] = new_distance;
todo.push(Reverse((new_distance, new)));
}
}
}
panic!("No route found from {:?} to {:?}", start, end);
}
pub fn height(&self) -> usize {
self.data.len() / self.width
}
pub fn index(&self, (x, y): Point) -> usize {
y as usize * self.width + x as usize
}
}
pub fn part1(input: &mut dyn Read) -> String {
let map = Map::from_input(input);
map.shortest_path((0, 0), (map.width as i32 - 1, map.height() as i32 - 1))
.to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let map = Map::from_input2(input);
map.shortest_path((0, 0), (map.width as i32 - 1, map.height() as i32 - 1))
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_implementation;
const SAMPLE: &[u8] = include_bytes!("samples/15.txt");
#[test]
fn sample_part1() {
test_implementation(part1, SAMPLE, 40);
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 315);
}
}

View File

@@ -1,9 +1,220 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
use nom::bits::complete::tag;
use nom::bits::complete::take;
use nom::branch::alt;
use nom::combinator::map;
use nom::multi::count;
use nom::sequence::preceded;
use nom::sequence::tuple;
use nom::IResult;
type Input<'a> = (&'a [u8], usize);
#[derive(Debug, Eq, PartialEq)]
enum Contents {
Literal(u64),
Operator(u8, Vec<Packet>),
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
#[derive(Debug, Eq, PartialEq)]
struct Packet {
version: u8,
contents: Contents,
}
fn capacity(input: Input) -> usize {
8 * input.0.len() - input.1 as usize
}
impl Packet {
pub fn version_sum(&self) -> u32 {
match &self.contents {
Contents::Literal(_) => self.version as u32,
Contents::Operator(_, sub_packets) => {
self.version as u32 + sub_packets.iter().map(Packet::version_sum).sum::<u32>()
}
}
}
pub fn value(&self) -> u64 {
match &self.contents {
Contents::Literal(val) => *val,
Contents::Operator(0, sub_packets) => sub_packets.iter().map(Packet::value).sum(),
Contents::Operator(1, sub_packets) => sub_packets.iter().map(Packet::value).product(),
Contents::Operator(2, sub_packets) => {
sub_packets.iter().map(Packet::value).min().unwrap()
}
Contents::Operator(3, sub_packets) => {
sub_packets.iter().map(Packet::value).max().unwrap()
}
Contents::Operator(5, sub_packets) => {
(sub_packets[0].value() > sub_packets[1].value()) as u64
}
Contents::Operator(6, sub_packets) => {
(sub_packets[0].value() < sub_packets[1].value()) as u64
}
Contents::Operator(7, sub_packets) => {
(sub_packets[0].value() == sub_packets[1].value()) as u64
}
unknown => panic!("unknown packet {:?}", unknown),
}
}
}
fn parse_literal(mut input: Input) -> IResult<Input, Contents> {
let mut val = 0;
loop {
let (new_input, result) = take::<_, u8, usize, _>(5)(input)?;
input = new_input;
val = (val << 4) | (result as u64 & 0xF);
if (result & 0x10) == 0 {
return Ok((input, Contents::Literal(val)));
}
}
}
fn parse_operator_len(input: Input) -> IResult<Input, Vec<Packet>> {
const SIZE_LEN: usize = 15;
let (mut input, to_read) = take(SIZE_LEN)(input)?;
let mut packets = Vec::new();
let initial = capacity(input);
while initial - capacity(input) < to_read {
let (new_input, packet) = parse_packet(input)?;
input = new_input;
packets.push(packet);
}
Ok((input, packets))
}
fn parse_operator_count(input: Input) -> IResult<Input, Vec<Packet>> {
const SIZE_LEN: usize = 11;
let (input, to_read) = take(SIZE_LEN)(input)?;
count(parse_packet, to_read)(input)
}
fn parse_packet(input: Input) -> IResult<Input, Packet> {
let parse_literal_packet = preceded(tag(4u8, 3usize), parse_literal);
let parse_operator_packet = map(
tuple((
take(3usize),
alt((
preceded(tag(0u8, 1usize), parse_operator_len),
preceded(tag(1u8, 1usize), parse_operator_count),
)),
)),
|(operator, contents)| Contents::Operator(operator, contents),
);
map(
tuple((
take(3usize),
alt((parse_literal_packet, parse_operator_packet)),
)),
|(version, contents)| Packet { version, contents },
)(input)
}
fn convert_hex(hex: &[u8]) -> Vec<u8> {
fn val(c: u8) -> u8 {
match c {
b'A'..=b'F' => c - b'A' + 10,
b'0'..=b'9' => c - b'0',
_ => panic!("Invalid hex digit {}", c),
}
}
let mut binary = Vec::with_capacity(hex.len() / 2);
binary.extend(
hex.chunks_exact(2)
.map(|chunk| (val(chunk[0]) << 4) | val(chunk[1])),
);
binary
}
pub fn part1(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
let binary_data = convert_hex(&buffer);
let (_, packet) = parse_packet((&binary_data, 0)).unwrap();
packet.version_sum().to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
let binary_data = convert_hex(&buffer);
let (_, packet) = parse_packet((&binary_data, 0)).unwrap();
packet.value().to_string()
}
#[cfg(test)]
mod tests {
use crate::test_implementation;
use super::*;
const SAMPLE: &[&[u8]] = &[
&*b"8A004A801A8002F478",
&*b"620080001611562C8802118E34",
&*b"C0015000016115A2E0802F182340",
&*b"A0016C880162017C3686B18A3D4780",
];
#[test]
fn sample_part1() {
let answers = [16, 12, 23, 31];
for (&sample, answer) in SAMPLE.iter().zip(answers) {
test_implementation(part1, sample, answer);
}
}
#[test]
fn test_parse_literal() {
let (_, packet) = parse_packet((&convert_hex(b"D2FE28"), 0)).unwrap();
assert_eq!(
packet,
Packet {
version: 6,
contents: Contents::Literal(2021)
}
);
}
#[test]
fn test_parse_operator_len() {
let (_, packet) = parse_packet((&convert_hex(b"38006F45291200"), 0)).unwrap();
assert_eq!(packet.version, 1);
assert!(matches!(packet.contents, Contents::Operator(6, _)));
}
#[test]
fn test_parse_operator_count() {
let (_, packet) = parse_packet((&convert_hex(b"EE00D40C823060"), 0)).unwrap();
assert_eq!(packet.version, 7);
assert!(matches!(packet.contents, Contents::Operator(3, _)));
}
}

View File

@@ -1,9 +1,150 @@
use std::io::Read;
use std::ops::RangeInclusive;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
use nom::bytes::complete::tag;
use nom::combinator::map;
use nom::sequence::preceded;
use nom::sequence::separated_pair;
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;
if d < 0. {
None
} else {
// Don't care about the smaller solution due to problem statement
if a > 0. {
Some((-b + d.sqrt()) / 2. / a)
} else {
Some((-b - d.sqrt()) / 2. / a)
}
}
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
fn position(initial: i32, time: i32) -> i32 {
time * (2 * initial - time + 1) / 2
}
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() as f64;
let b = initial as f64 + 0.5;
let hit = if let Some(hit) = solve_quadratic(-0.5, b, -middle) {
hit as i32
} else {
// Cause an empty range
-1
};
(0..=hit)
.rev()
.take_while(move |&n| range.contains(&position(initial, n)))
}
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;
let min = (0..=max)
.rev()
.take_while(|&n| range.contains(&position(n, n)))
.last()?;
Some((min, max))
} else {
// Might hit the target at speed
let max = (x * x + 2 * *range.end() - x) / (2 * x);
let min = (0..=max)
.rev()
.take_while(|&n| range.contains(&position(n, n.min(x))))
.last()?;
Some((min, max))
}
}
fn parse_range(input: &[u8]) -> IResult<&[u8], RangeInclusive<i32>> {
use nom::character::complete::i32;
map(separated_pair(i32, tag(".."), i32), |(start, end)| {
start..=end
})(input)
}
fn parse_input(input: &[u8]) -> IResult<&[u8], (RangeInclusive<i32>, RangeInclusive<i32>)> {
preceded(
tag("target area: x="),
separated_pair(parse_range, tag(", y="), parse_range),
)(input)
}
pub fn part1(input: &mut dyn Read) -> String {
let (x_range, y_range) = read_input(input, parse_input);
let check_value =
|y_speed| find_hit(y_speed, &y_range).any(|time| find_speed(time, &x_range).is_some());
debug_assert!(*y_range.start() < 0);
let y_max = -*y_range.start();
(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 (x_range, y_range) = read_input(input, parse_input);
let num_options = |y_speed| {
find_hit(y_speed, &y_range)
.filter_map(|time| find_speed(time, &x_range))
.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)
};
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)]
mod tests {
use crate::test_implementation;
use super::*;
const SAMPLE: &[u8] = &*b"target area: x=20..30, y=-10..-5";
#[test]
fn test_find_hit() {
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]
fn sample_part1() {
test_implementation(part1, SAMPLE, 45);
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 112);
}
}

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/15.txt Normal file
View File

@@ -0,0 +1,10 @@
1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581

1
2021/src/samples/17.txt Normal file
View File

@@ -0,0 +1 @@
target area: x=20..30, y=-10..-5

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

26
2022/Cargo.toml Normal file
View File

@@ -0,0 +1,26 @@
[package]
name = "aoc_2022"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.66"
clap = { version = "4.0.19", features = ["derive"] }
nom = "7.1.1"
[dev-dependencies]
criterion = "0.4.0"
[profile.release]
# Keep debug information in release for better flamegraphs
debug = true
[profile.bench]
# And same for benchmarking
debug = true
[[bench]]
name = "days"
harness = false

20
2022/README.md Normal file
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 = 2;
fn read_input(day: u8) -> Vec<u8> {
let input_path = format!("inputs/{:02}.txt", day);
let mut buffer = Vec::new();
File::open(input_path)
.expect("Failed to open input file")
.read_to_end(&mut buffer)
.expect("Failed to read input file");
buffer
}
pub fn benchmark_days(c: &mut Criterion) {
for day in 1..=DAYS_IMPLEMENTED {
let input = read_input(day);
let part1 = get_implementation(day, false).unwrap();
c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
b.iter(|| part1(i));
});
if day < 25 {
let part2 = get_implementation(day, true).unwrap();
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
b.iter(|| part2(i));
});
}
}
}
criterion_group!(benches, benchmark_days);
criterion_main!(benches);

0
2022/inputs/.gitkeep Normal file
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

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

@@ -0,0 +1,94 @@
//! Common helper utilities to all days
use anyhow::Result;
use nom::error::ErrorKind;
use nom::error::ParseError;
use nom::Finish;
use nom::IResult;
use nom::InputLength;
use nom::Parser;
/// Parse input from some nom parser and return as an anyhow result
///
/// This method exists as a convenience because nom's errors cannot otherwise be easily converted to
/// an anyhow error, and I don't want to keep track of custom error implementations here.
pub fn parse_input<'a, O>(
input: &'a [u8],
mut parser: impl Parser<&'a [u8], O, nom::error::Error<&'a [u8]>>,
) -> Result<O> {
let (unparsed, output) = parser.parse(input).finish().map_err(|e| {
anyhow::anyhow!(
"Parser error {:?} to parse at {}",
e.code,
String::from_utf8_lossy(e.input)
)
})?;
if !unparsed.is_empty() {
Err(anyhow::anyhow!(
"Not all input consumed: {}",
String::from_utf8_lossy(unparsed)
))
} else {
Ok(output)
}
}
/// Applies a parser iteratively and reduces the results using the given function. Fails if the
/// embedded parser doesn't return at least one result.
///
/// # Arguments
/// - `f`: the function to apply
/// - `g`: the function that combines the result o `f` with previous results
///
/// This implementation is based on [`nom::multi::fold_many1`] with minor differences. If
/// successful, this should probably be upstreamed.
pub fn reduce_many1<I, O, E, F>(
mut f: F,
mut g: impl FnMut(O, O) -> O,
) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Clone + InputLength,
E: ParseError<I>,
F: Parser<I, O, E>,
{
// Cannot delegate to fold_many0 because that would make the function FnOnce rather than FnMut,
// since it would transfer ownership of the embedded parser to fold_many0.
move |i: I| {
let _i = i.clone();
match f.parse(_i) {
Err(nom::Err::Error(_)) => {
Err(nom::Err::Error(E::from_error_kind(i, ErrorKind::Many1)))
}
Err(e) => Err(e),
Ok((i1, mut acc)) => {
let mut input = i1;
loop {
let _input = input.clone();
let len = input.input_len();
match f.parse(_input) {
Err(nom::Err::Error(_)) => {
break;
}
Err(e) => return Err(e),
Ok((i, o)) => {
// infinite loop check: the parser must always consume
if i.input_len() == len {
return Err(nom::Err::Failure(E::from_error_kind(
i,
ErrorKind::Many1,
)));
}
acc = g(acc, o);
input = i;
}
}
}
Ok((input, acc))
}
}
}
}

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

@@ -0,0 +1,55 @@
use std::ops::Add;
use anyhow::Result;
use nom::character::complete::newline;
use nom::combinator::opt;
use nom::multi::separated_list0;
use nom::sequence::terminated;
use nom::IResult;
use crate::common::parse_input;
use crate::common::reduce_many1;
fn parse_elf(input: &[u8]) -> IResult<&[u8], i32> {
reduce_many1(terminated(nom::character::complete::i32, newline), Add::add)(input)
}
fn parse_max(input: &[u8]) -> IResult<&[u8], i32> {
reduce_many1(terminated(parse_elf, opt(newline)), Ord::max)(input)
}
pub fn part1(input: &[u8]) -> Result<String> {
let result = parse_input(input, parse_max)?.to_string();
Ok(result)
}
fn parse_elf_list(input: &[u8]) -> IResult<&[u8], Vec<i32>> {
separated_list0(newline, parse_elf)(input)
}
pub fn part2(input: &[u8]) -> Result<String> {
let mut elves = parse_input(input, parse_elf_list)?;
let (first, third, _) = elves.select_nth_unstable_by(2, |a, b| Ord::cmp(b, a));
let result = first[1] + first[0] + *third;
Ok(result.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/01.txt");
#[test]
fn sample_part1() {
assert_eq!(part1(SAMPLE).unwrap(), "24000");
}
#[test]
fn sample_part2() {
assert_eq!(part2(SAMPLE).unwrap(), "45000");
}
}

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

@@ -0,0 +1,129 @@
use std::ops::Add;
use anyhow::Result;
use nom::character::complete::newline;
use nom::combinator::map;
use nom::combinator::map_res;
use nom::sequence::separated_pair;
use nom::sequence::terminated;
use nom::IResult;
use crate::common::parse_input;
use crate::common::reduce_many1;
#[derive(Copy, Clone, Eq, PartialEq)]
enum Rps {
Rock,
Paper,
Scissors,
}
impl Rps {
/// Score we get by playing this move
fn score(self) -> u32 {
match self {
Rps::Rock => 1,
Rps::Paper => 2,
Rps::Scissors => 3,
}
}
/// Score we get from the result from playing given other
fn score_against(self, other: Self) -> u32 {
match (self, other) {
(a, b) if a == b => 3,
(Rps::Rock, Rps::Paper) | (Rps::Paper, Rps::Scissors) | (Rps::Scissors, Rps::Rock) => 0,
_ => 6,
}
}
/// Score if the result is according to the instruction
fn score_result(self) -> u32 {
match self {
Rps::Rock => 0, // Rock is lose
Rps::Paper => 3, // Paper is draw
Rps::Scissors => 6, // Scissors is win
}
}
/// Move we need to achieve the result indicated by self
fn needed(self, other: Self) -> Self {
match (self, other) {
(Rps::Paper, other) => other,
(Rps::Rock, Rps::Rock) => Rps::Scissors,
(Rps::Rock, Rps::Paper) => Rps::Rock,
(Rps::Rock, Rps::Scissors) => Rps::Paper,
(Rps::Scissors, Rps::Rock) => Rps::Paper,
(Rps::Scissors, Rps::Paper) => Rps::Scissors,
(Rps::Scissors, Rps::Scissors) => Rps::Rock,
}
}
}
impl TryFrom<u8> for Rps {
type Error = anyhow::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
b'A' | b'X' => Ok(Rps::Rock),
b'B' | b'Y' => Ok(Rps::Paper),
b'C' | b'Z' => Ok(Rps::Scissors),
_ => Err(anyhow::anyhow!("Invalid RPS: {value}")),
}
}
}
fn parse_line(input: &[u8]) -> IResult<&[u8], (Rps, Rps)> {
fn parse_rps(input: &[u8]) -> IResult<&[u8], Rps> {
// Note: alpha1 also sort of works but is significantly slower
map_res(nom::bytes::complete::take(1usize), |v: &[u8]| {
Rps::try_from(v[0])
})(input)
}
terminated(
separated_pair(parse_rps, nom::character::complete::char(' '), parse_rps),
newline,
)(input)
}
pub fn part1(input: &[u8]) -> Result<String> {
parse_input(
input,
reduce_many1(
map(parse_line, |(them, us)| us.score() + us.score_against(them)),
Add::add,
),
)
.map(|sum| sum.to_string())
}
pub fn part2(input: &[u8]) -> Result<String> {
parse_input(
input,
reduce_many1(
map(parse_line, |(them, us)| {
us.score_result() + us.needed(them).score()
}),
Add::add,
),
)
.map(|sum| sum.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/02.txt");
#[test]
fn sample_part1() {
assert_eq!(part1(SAMPLE).unwrap(), "15")
}
#[test]
fn sample_part2() {
assert_eq!(part2(SAMPLE).unwrap(), "12")
}
}

9
2022/src/day03.rs Normal file
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/day04.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/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

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)