changeset 32:05ddc45b4210

Move old puzzles to 2022 directory
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 02 Dec 2023 12:22:41 +0100
parents 8590a79087a0
children 00f7efc7934e
files 01/01.jl 01/input.txt 02/02.jl 02/input.txt 03/03.jl 03/input.txt 04/04.jl 04/input.txt 05/05.jl 05/input.txt 06/06.jl 07/07.jl 07/input.txt 07/small.txt 08/08.jl 08/input.txt 09/09.jl 09/input.txt 10/10.jl 10/input.txt 10/test_input.txt 11/11.jl 11/input.txt 11/test_input.txt 12/12.jl 12/input.txt 12/test_input.txt 13/13.jl 13/input.txt 13/test_input.txt 14/14.jl 14/input.txt 14/test_input.txt 15/15.jl 15/input.txt 15/test_input.txt 16/16.jl 16/input.txt 16/test_input.txt 2022/01/01.jl 2022/01/input.txt 2022/02/02.jl 2022/02/input.txt 2022/03/03.jl 2022/03/input.txt 2022/04/04.jl 2022/04/input.txt 2022/05/05.jl 2022/05/input.txt 2022/06/06.jl 2022/07/07.jl 2022/07/input.txt 2022/07/small.txt 2022/08/08.jl 2022/08/input.txt 2022/09/09.jl 2022/09/input.txt 2022/10/10.jl 2022/10/input.txt 2022/10/test_input.txt 2022/11/11.jl 2022/11/input.txt 2022/11/test_input.txt 2022/12/12.jl 2022/12/input.txt 2022/12/test_input.txt 2022/13/13.jl 2022/13/input.txt 2022/13/test_input.txt 2022/14/14.jl 2022/14/input.txt 2022/14/test_input.txt 2022/15/15.jl 2022/15/input.txt 2022/15/test_input.txt 2022/16/16.jl 2022/16/input.txt 2022/16/test_input.txt 2022/17/17.jl 2022/17/input.txt 2022/17/test_input.txt 2022/Manifest.toml 2022/Project.toml Manifest.toml Project.toml
diffstat 85 files changed, 12789 insertions(+), 12642 deletions(-) [+]
line wrap: on
line diff
--- a/01/01.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-
-const input = "01/input.txt"
-
-function count_calories(data::Vector{Vector{Int}})::Int
-    reduced = [sum(v) for v in data];
-    maximum(reduced)
-end
-
-function top_three(data::Vector{Vector{Int}})::Int
-    reduced = [sum(v) for v in data];
-    sort!(reduced);
-    sum(reduced[end-2:end])
-end
-
-function parse_input(filehandle::IO)::Vector{Vector{Int}}
-    input = Vector{Vector{Int}}();
-    while true
-        current = Vector{Int}();
-        while true
-            line = readline(filehandle);
-            if isempty(line)
-                break;
-            end
-            push!(current, parse(Int, line));
-        end
-        if length(current) == 0
-            break
-        end
-        push!(input, current);
-    end
-    input
-end
-
-function run_01(f::String)::Tuple{Int,Int}
-    input = open(f; read=true) do fh
-        parse_input(fh)
-    end;
-    count_calories(input), top_three(input)
-end
-
--- a/01/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2264 +0,0 @@
-17034
-
-13495
-7368
-13905
-
-68034
-
-7796
-10348
-5088
-8836
-
-15061
-1842
-7047
-
-2477
-6629
-7998
-4235
-6505
-2875
-6059
-9423
-5315
-
-4054
-6388
-5278
-4163
-10438
-10821
-2650
-
-6424
-2420
-10363
-4275
-1876
-6357
-6364
-
-5123
-1271
-3991
-2792
-2513
-4890
-2900
-7820
-6020
-4612
-3109
-
-9072
-18898
-13848
-11609
-
-1793
-1434
-2288
-4573
-5087
-7366
-3233
-3052
-5754
-1418
-6255
-
-5372
-2497
-2289
-6782
-4154
-5081
-5984
-3164
-4111
-2951
-6928
-1798
-6525
-
-19803
-23713
-7818
-
-7662
-2324
-8206
-5409
-8225
-5513
-2664
-3870
-1428
-5189
-
-5603
-8006
-1486
-1469
-5413
-5638
-2242
-8559
-6333
-1389
-
-4187
-2794
-1067
-1632
-1679
-4572
-5964
-1170
-4199
-5612
-6321
-6658
-3737
-
-2093
-2221
-4741
-5892
-3781
-4034
-1030
-1542
-1547
-5429
-1896
-1371
-4041
-2522
-
-15827
-1404
-8514
-8983
-6878
-
-56181
-
-11350
-12192
-12659
-9552
-14896
-
-5308
-6289
-5069
-3594
-1499
-1034
-5546
-3430
-2292
-2825
-4427
-2315
-2738
-
-5102
-3295
-6423
-1653
-6199
-2459
-1569
-6588
-5691
-4490
-7235
-
-6470
-9298
-10054
-6316
-1773
-6657
-4398
-4420
-
-25785
-1283
-
-9366
-10257
-3221
-2899
-7247
-4711
-
-4108
-6265
-4824
-6589
-2869
-4826
-5853
-1770
-5627
-6581
-2591
-2107
-
-1300
-1774
-9933
-6743
-11425
-8454
-8080
-
-1292
-6230
-1017
-5895
-2718
-6219
-5511
-7161
-1201
-4493
-
-3268
-1306
-5417
-4691
-13018
-13021
-
-9165
-12000
-7531
-10585
-2802
-10764
-2744
-
-8261
-4961
-3019
-3309
-6632
-7955
-3538
-7392
-
-2730
-4479
-1909
-6013
-5214
-1188
-5074
-1589
-1103
-1393
-1745
-4162
-4231
-4197
-3307
-
-1246
-5200
-2648
-6419
-5659
-7380
-4479
-4589
-4108
-7290
-5514
-4406
-
-4256
-5658
-9668
-8745
-6698
-11874
-9277
-
-19436
-11206
-7547
-1540
-
-4757
-11223
-9685
-6113
-10587
-5328
-1896
-
-3312
-2758
-3528
-3501
-1933
-5876
-3471
-1208
-3892
-5302
-2674
-1282
-1195
-5675
-5753
-
-3127
-21845
-
-5244
-9557
-8744
-2783
-6549
-6225
-1122
-7317
-7574
-
-5154
-2790
-3239
-6496
-7433
-5770
-3835
-6644
-5503
-1273
-1244
-7098
-
-4307
-1882
-9426
-7432
-3558
-5765
-9957
-6974
-
-9510
-35767
-
-3109
-5208
-4756
-1226
-5645
-7133
-2308
-5784
-5194
-2739
-
-1850
-9199
-6957
-6793
-9231
-9094
-7275
-2519
-
-52651
-
-2337
-6455
-5574
-3001
-1296
-5120
-5175
-1704
-7041
-2118
-3446
-2219
-
-10123
-2817
-6853
-11370
-9490
-
-11194
-1887
-1922
-2390
-10687
-3573
-8476
-
-3646
-1365
-5255
-1882
-5705
-2428
-5833
-2242
-3674
-2254
-5141
-1317
-4873
-4421
-4178
-
-7264
-12898
-4423
-1871
-4998
-10540
-
-9143
-9081
-6136
-6734
-6955
-6956
-5693
-8110
-
-8820
-11554
-5474
-9848
-
-7445
-8434
-7883
-3523
-2562
-5174
-3178
-5766
-5322
-5347
-
-2666
-1556
-4772
-5053
-5874
-5711
-1684
-3351
-4037
-4770
-4755
-6280
-1326
-5756
-
-4322
-10058
-6727
-3217
-9987
-3195
-10711
-5728
-
-8382
-32068
-
-3385
-1384
-3110
-1205
-2932
-4065
-3886
-5950
-6443
-2657
-2229
-4438
-2100
-3961
-
-1654
-2028
-8414
-3662
-4270
-3923
-4827
-5443
-2710
-3406
-
-8262
-6401
-2115
-7528
-1359
-1934
-1560
-3271
-8459
-8387
-
-8437
-5394
-5589
-5243
-3421
-5228
-3601
-
-6306
-5779
-5119
-2453
-1289
-1164
-1175
-7252
-7215
-2632
-6832
-2304
-
-4788
-3723
-5887
-2748
-7350
-5974
-6015
-1545
-1092
-2524
-4130
-7297
-
-3455
-5668
-1435
-2738
-5520
-4374
-2594
-4144
-4457
-6479
-1230
-3682
-6157
-4284
-
-10449
-6988
-2505
-6083
-3844
-2655
-8953
-
-6061
-5493
-4922
-3375
-1273
-4181
-4643
-4039
-1482
-5952
-3468
-4719
-4101
-4702
-
-1135
-3886
-3308
-3986
-2662
-1814
-5813
-1079
-4916
-5059
-2155
-1404
-2398
-2730
-1972
-
-5868
-5201
-3725
-4905
-1655
-3585
-6339
-5563
-6869
-4779
-4072
-5106
-3587
-
-5997
-1240
-2115
-4558
-1572
-7031
-1568
-3230
-4081
-3767
-1916
-5388
-
-6672
-7355
-7362
-6232
-6112
-7095
-5350
-8343
-8171
-8331
-
-4370
-11625
-6923
-1583
-9520
-11093
-11708
-
-4475
-23713
-
-6310
-6536
-3243
-2910
-2861
-5076
-6562
-3924
-5933
-4044
-1572
-2351
-6665
-
-6994
-5704
-5165
-7364
-5819
-1816
-3929
-6967
-1009
-2528
-6107
-6954
-
-6855
-11865
-9195
-18609
-
-5582
-3987
-7772
-2106
-1006
-5441
-6201
-7748
-1386
-1898
-7790
-
-5332
-5371
-3515
-6367
-6657
-2677
-4790
-2448
-3401
-1668
-4425
-3758
-5385
-
-4105
-3883
-4389
-2214
-1943
-2510
-2544
-1330
-6275
-1492
-5837
-1830
-4440
-
-5041
-
-40092
-
-34451
-
-14820
-10096
-24218
-
-2095
-3608
-1467
-6098
-9586
-4062
-6745
-1217
-2074
-
-5660
-7032
-7666
-2711
-3050
-2260
-6274
-4672
-1028
-6916
-7861
-
-37401
-29831
-
-15255
-6714
-2378
-13864
-
-7618
-15264
-8496
-7847
-8750
-
-6392
-4892
-1200
-2133
-2879
-6033
-5634
-1979
-5066
-3965
-4734
-1761
-5627
-2369
-
-19691
-16626
-6806
-
-3594
-1824
-4264
-5058
-2286
-6836
-4687
-4016
-2660
-7224
-6390
-
-6213
-6396
-5387
-5318
-3022
-5080
-6098
-3699
-2437
-6430
-6091
-1255
-2480
-2490
-
-8795
-3287
-14228
-10078
-
-6720
-3431
-
-13856
-2609
-
-1683
-1241
-5941
-8021
-11838
-
-3961
-3033
-4069
-3200
-2598
-3133
-6007
-2048
-2850
-2605
-5111
-3726
-1994
-1910
-2289
-
-11960
-3800
-11919
-3808
-12138
-7118
-
-60979
-
-10777
-8860
-3736
-3591
-12500
-8963
-
-3474
-3027
-5923
-1874
-3555
-5312
-5568
-1796
-2831
-3105
-3501
-4378
-5999
-4528
-5948
-
-2493
-13969
-
-6992
-14112
-3430
-14233
-13381
-
-17059
-5737
-1290
-12844
-
-6302
-4418
-2067
-5059
-2085
-3061
-4411
-5662
-4097
-3333
-2182
-1090
-4185
-
-4811
-1351
-6050
-7344
-2745
-6588
-3506
-2056
-4229
-4256
-1853
-5912
-
-9673
-2207
-4646
-2680
-12985
-3873
-
-1110
-6118
-4411
-6331
-1668
-6023
-6977
-5049
-6669
-4421
-5027
-3131
-
-9968
-2987
-5041
-18431
-
-7436
-5660
-15858
-7130
-12737
-
-5232
-9051
-10275
-9404
-3384
-5719
-5724
-10218
-
-4350
-2456
-7892
-1318
-6932
-7890
-9595
-4605
-7672
-
-2666
-9981
-1959
-5686
-3655
-2763
-6737
-8621
-
-9915
-5955
-10523
-3976
-4166
-9602
-2985
-6160
-
-25160
-18830
-7409
-
-1322
-1283
-3839
-3054
-5782
-4615
-2579
-3332
-3046
-3634
-2428
-1373
-5638
-
-13941
-
-2653
-14138
-2355
-12340
-6598
-
-4857
-9417
-13144
-9072
-4174
-
-1946
-6030
-5875
-1649
-1757
-2198
-2673
-3743
-1357
-1134
-1602
-
-2791
-10432
-4037
-2767
-11295
-11255
-9762
-
-9232
-11015
-21925
-
-6365
-1170
-4253
-5122
-5390
-7061
-7781
-4584
-6362
-6367
-5321
-
-23166
-21313
-16147
-
-7915
-10734
-6921
-4796
-6442
-3520
-4416
-5702
-
-31627
-21575
-
-9569
-2837
-3816
-5052
-9399
-6174
-3291
-2513
-2932
-
-6255
-14356
-5389
-18970
-
-26896
-3552
-
-19037
-5180
-6855
-
-4929
-5212
-15135
-
-1114
-1338
-8702
-7914
-6690
-5981
-6129
-4246
-4660
-
-2696
-4528
-4053
-5982
-2308
-6097
-1933
-6410
-4851
-4526
-5705
-5510
-3951
-
-4693
-4906
-4570
-1161
-2974
-4099
-5423
-4146
-3305
-3057
-2079
-6187
-3196
-2285
-
-6300
-6253
-5892
-3636
-5373
-5345
-1990
-7456
-1218
-4220
-3845
-
-3028
-1790
-2104
-6750
-2516
-2482
-2574
-6806
-1613
-2279
-5389
-3979
-6672
-
-48619
-
-15159
-1029
-
-13352
-5081
-
-6292
-6989
-5568
-6181
-2773
-4529
-3205
-1134
-6416
-5199
-2830
-4813
-
-4718
-5530
-5036
-2874
-2658
-2353
-5402
-3476
-1924
-3147
-2883
-6331
-
-14524
-30079
-
-4071
-4399
-3021
-5165
-2110
-6084
-1863
-3614
-4336
-5688
-1960
-
-25783
-28718
-
-13615
-1645
-11870
-8796
-
-5951
-6447
-2501
-7770
-2999
-6715
-8707
-5124
-6215
-3113
-
-6241
-2189
-1752
-1812
-2727
-5703
-2710
-6113
-1732
-6237
-
-7990
-6499
-8481
-3443
-9375
-10439
-5892
-2758
-
-7919
-8753
-5124
-6388
-8026
-7326
-4457
-4352
-5781
-5549
-
-49501
-
-10500
-23249
-
-8352
-9128
-4905
-5833
-1218
-2859
-11489
-
-6104
-6546
-6243
-6716
-3511
-3433
-4327
-2453
-2887
-5007
-4404
-4506
-2315
-
-7269
-3193
-3535
-2566
-2745
-6483
-3880
-5042
-6931
-4519
-3442
-6667
-
-16325
-7397
-21391
-
-12648
-9268
-8280
-1497
-13788
-3384
-
-1373
-2171
-2065
-5461
-4854
-2427
-5814
-2197
-4077
-5138
-6861
-6083
-1995
-
-4817
-3501
-1937
-4840
-4299
-6083
-1330
-2737
-5361
-5941
-2762
-3191
-5530
-3913
-4139
-
-10082
-7801
-5221
-4785
-6847
-4672
-8824
-4507
-
-25999
-21078
-
-34976
-27760
-
-6972
-2714
-1051
-4905
-1102
-6332
-6113
-4218
-7125
-4372
-4669
-
-3986
-10129
-16175
-6193
-11015
-
-6260
-5523
-2032
-5304
-5167
-2908
-6518
-5491
-1718
-6229
-3264
-4899
-2873
-
-6613
-4234
-6130
-1017
-7986
-7727
-3564
-8250
-
-12031
-11879
-11614
-13472
-8471
-7369
-
-4315
-1636
-6292
-6768
-3788
-4643
-6397
-7402
-1379
-3518
-6438
-6196
-
-5667
-7559
-13899
-18285
-
-5266
-34337
-
-29305
-22273
-
-9371
-5132
-1652
-2573
-8840
-8636
-4700
-3145
-7728
-
-5864
-4845
-3567
-1247
-3070
-1378
-2836
-5574
-2398
-5191
-3520
-1395
-4933
-5530
-2656
-
-5504
-5002
-4944
-4903
-3186
-1446
-3886
-1506
-2669
-5362
-2456
-2150
-4468
-5212
-2319
-
-1543
-1581
-4295
-5685
-1977
-4361
-2381
-5288
-5557
-3159
-4833
-5577
-5892
-
-8109
-4061
-
-7132
-2394
-9579
-7360
-9023
-8589
-5666
-3108
-
-25582
-3178
-2616
-
-5742
-2967
-2577
-2141
-6022
-1148
-1971
-1779
-5039
-5210
-1043
-1633
-2697
-
-5024
-1439
-3535
-4723
-3271
-3904
-4303
-2706
-2878
-2882
-4417
-5580
-2685
-5028
-2243
-
-4788
-2903
-6717
-5514
-4434
-6396
-3370
-2964
-6940
-3018
-1328
-6527
-4651
-
-5796
-7350
-15943
-7116
-11040
-
-9110
-1795
-10997
-9811
-5571
-8786
-8690
-
-1173
-4256
-2326
-2947
-3133
-4930
-1653
-4548
-3971
-4837
-4084
-3362
-4144
-4015
-2631
-
-22258
-
-1270
-8084
-3413
-1180
-7841
-3467
-1068
-3763
-7479
-2988
-5377
-
-4833
-2453
-2985
-5365
-1128
-2411
-2103
-
-29169
-
-9451
-5237
-3547
-13513
-3528
-4937
-
-14834
-6011
-11685
-17950
-
-3040
-4721
-1809
-5755
-2326
-4373
-1018
-1433
-3180
-3173
-1313
-4158
-1867
-3349
-5629
-
-4201
-12336
-18265
-14378
-
-5248
-2091
-6755
-4523
-6049
-1183
-3834
-1242
-6517
-1561
-6666
-5117
-5600
-
-2907
-1482
-2765
-8934
-1654
-3786
-8807
-8924
-
-6131
-4724
-4774
-1030
-6359
-4452
-5557
-1501
-5743
-2434
-1809
-4657
-5609
-4773
-
-24218
-26128
-
-11710
-8138
-7143
-7236
-11903
-4547
-2419
-
-1474
-13551
-6009
-12136
-13007
-9816
-
-7230
-3816
-5352
-5591
-
-7237
-5129
-2630
-3158
-4131
-1324
-2439
-2828
-1922
-6051
-3871
-3577
-
-21875
-13945
-15782
-
-10156
-15069
-18789
-6685
-
-6292
-12221
-17527
-
-11396
-11684
-2362
-12055
-6888
-9393
-11909
-
-37154
-17860
-
-22974
-
-3693
-2551
-3077
-7444
-8973
-5966
-2728
-
-2554
-3119
-2796
-1993
-3959
-4421
-2691
-3002
-4104
-5876
-2748
-3633
-3567
-2280
-3852
-
-9583
-4003
-
-3100
-4338
-6077
-4813
-3223
-2373
-1607
-7412
-7798
-7684
-
-4354
-3140
-2957
-5563
-6119
-2571
-1742
-3603
-5854
-3755
-2827
-
-1302
-4160
-1944
-1215
-1603
-5361
-5959
-3698
-5329
-3118
-4941
-1624
-4755
-3249
-5205
-
-4707
-3243
-6299
-3689
-8496
-8594
-4187
-
-5986
-4431
-1006
-1707
-1202
-4184
-3438
-5148
-4472
-6561
-5882
-5693
-
-11346
-8748
-12659
-
-2456
-2147
-1401
-5715
-5128
-5560
-1635
-3947
-5021
-4850
-1414
-2316
-5949
-4779
-2867
-
-2530
-3901
-7034
-4665
-7109
-2416
-5461
-8825
-
-5287
-4195
-9609
-5697
-3135
-6638
-2780
-6876
-6032
-
-17278
-18581
-4060
-13610
-
-14199
-19618
-4500
-
-4423
-15765
-6614
-11352
-1941
-
-30048
-17442
-
-6881
-8630
-10121
-9792
-6340
-8848
-7245
-7764
-
-5138
-9396
-2975
-5036
-6776
-7205
-8991
-3595
-4894
-
-1065
-4272
-2155
-2655
-9405
-10274
-8344
-
-8234
-3276
-1914
-11975
-8096
-
-7358
-13681
-13640
-1543
-13683
-
-24588
-22649
-
-5034
-2818
-4103
-2328
-2311
-4241
-6145
-2694
-5191
-4266
-6477
-6412
-4566
-3077
-
-4442
-2199
-7109
-6674
-5257
-4611
-
-2544
-1810
-1941
-3389
-3473
-1813
-1232
-3782
-1733
-4191
-3953
-3793
-4832
-2560
-1321
-
-3331
-2853
-5284
-1989
-4543
-4447
-5852
-2847
-3260
-5583
-5429
-2967
-3563
-1925
-2799
-
-9448
-3662
-6703
-7356
-1600
-
-4050
-6662
-7169
-2836
-2231
-1149
-5204
-4275
-6231
-7478
-1388
-6980
-
-2185
-1526
-1640
-9156
-6623
-8572
-7426
-9419
-
-10637
-9584
-8293
-7473
-3529
-7532
-
-3987
-12127
-10749
-3399
-11041
-4600
-9896
-
-3728
-1878
-5192
-3264
-6367
-4429
-6449
-7005
-4883
-5359
-2112
-6228
-
-13574
-6574
-11518
-11909
-13625
-
-16357
-19546
-7520
-8254
-
-2122
-1712
-2729
-2847
-1157
-2895
-4850
-2805
-5603
-2321
-6113
-5468
-1230
-2385
-
-3947
-3326
-2395
-5776
-4035
-3206
-5845
-6429
-5039
-4540
-5047
-4237
-6953
-
-1738
-8822
-11967
-10160
-4327
-8382
-2686
-
-2778
-6909
-7649
-2787
-8749
-1720
-6863
-5515
-8631
-3257
-
-1369
-2470
-2726
-7415
-5232
-1919
-2981
-4437
-3168
-6412
-7072
-3201
-
-19275
-10942
-
-12930
-12593
-9356
-5680
-10193
-4399
-
-11119
-10651
-8687
-12028
-1713
-8311
-10089
-
-3752
-
-10177
-9060
-4817
-3564
-7272
-10452
-
-1563
-3885
-3191
-6312
-5524
-5207
-3669
-
-8105
-7217
-4719
-9214
-3973
-10782
-10563
-
-10142
-4264
-
-7283
-
-15973
-9578
-9884
-4478
-10540
-
-5548
-4654
-3024
-2243
-3985
-1220
-3461
-1042
-1845
-2888
-3931
-2356
-1430
-3373
-4604
-
-8036
-3016
-3510
-2659
-8700
-1539
-1202
-2116
-4351
-7388
-
-2995
-7003
-8022
-2012
-1976
-3938
-3744
-6146
-5056
-7590
-4008
-
-4459
-12305
-7633
-2742
-12867
-12607
-
-3791
-5059
-6361
-3008
-4543
-1374
-6821
-5967
-8461
-4241
-
-1641
-1364
-2037
-2479
-1413
-4250
-5042
-2438
-2855
-3081
-3535
-3966
-3574
-1149
-3606
-
-3397
-2787
-5638
-2321
-3765
-5617
-4870
-4456
-6681
-1890
-1068
-3609
-3043
-
-3436
-4011
-5212
-5576
-4139
-1387
-6298
-4179
-4000
-4207
-3302
-1539
-2793
-3551
--- a/02/02.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-const input = "02/input.txt"
-
-struct InputLine
-    opponent::Char
-    choice::Char
-end
-
-function parse(fh::IO)::Vector{InputLine}
-    v = Vector{InputLine}();
-    while true
-        l = readline(fh);
-        if isempty(l)
-            break;
-        end
-        a, b = split(chomp(l));
-        push!(v, InputLine(a[1], b[1]));
-    end
-    v
-end
-
-function score(il::InputLine)::Int
-    shapescore = Int(il.choice - 'W');
-    op, me = Int(il.opponent-'A'), Int(il.choice-'X')
-    @assert abs(me-op) <= 2
-    if abs(me-op) == 0
-        shapescore + 3
-    elseif abs(me-op) == 1
-        shapescore + (me > op ? 6 : 0)
-    else
-        shapescore + (me < op ? 6 : 0)
-    end
-end
-
-function score2(il::InputLine)::Int
-    winscore = 3 * Int(il.choice-'X');
-    winshape = (Int(il.opponent-'A')+1)%3;
-    loseshape = (Int(il.opponent-'A')-1);
-    if loseshape < 0
-        loseshape += 3
-    end
-    shape = (if il.choice == 'X'; loseshape elseif il.choice == 'Y'; Int(il.opponent-'A') else winshape end);
-    shape+1 + winscore
-end
-
-function calc(v::Vector{InputLine})::Tuple{Int, Int}
-    sum(map(score, v)), sum(map(score2, v))
-end
-
-function run_02(file::String)::Tuple{Int,Int}
-    open(file; read=true) do fh
-        p = parse(fh);
-        calc(p)
-    end
-end
-
-print(run_02(input))
--- a/02/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2500 +0,0 @@
-A Z
-C X
-A Z
-A Z
-C Y
-C Y
-A Z
-A Y
-C Y
-A Y
-A Z
-A Z
-A Z
-A Y
-A Z
-A Y
-C Y
-C X
-A Y
-C Y
-C Y
-C X
-A Z
-C Y
-C X
-A X
-A Y
-A Z
-A Y
-A Y
-C X
-C X
-B Y
-C X
-C X
-A Y
-A Z
-A Z
-A X
-A Z
-A Z
-C Y
-A Z
-A Z
-A Y
-C X
-C Y
-C X
-B X
-C Z
-A Y
-A Z
-A Z
-A Z
-A Y
-A Y
-C X
-A Y
-A Z
-C Y
-A Y
-A Y
-A Z
-A Z
-C Y
-A Z
-C Y
-A Y
-A Z
-A Z
-C Y
-B Z
-A Z
-A Z
-A Z
-A Z
-C X
-C X
-A Y
-A X
-A Y
-A Z
-A Z
-C X
-A Z
-C X
-A Z
-C Y
-C X
-A Z
-A Z
-A Z
-A Z
-C X
-C Y
-A Z
-A Z
-C Y
-A Z
-B Z
-C X
-A Z
-A X
-C X
-A Z
-C Z
-A Z
-C X
-A Z
-A Y
-C X
-C Z
-A Z
-C X
-C Y
-A Z
-B Z
-B Y
-A X
-A X
-A X
-A Z
-A Z
-A X
-A Z
-A X
-A Z
-A Z
-C X
-C X
-B Z
-A Z
-A Y
-A Z
-A Z
-A Z
-A Z
-C X
-C X
-C X
-A Z
-A Z
-A Z
-A Z
-A X
-A Y
-A Y
-C X
-C X
-B Z
-C X
-A X
-A Z
-A Z
-C X
-C Z
-A Z
-A Z
-C Y
-A X
-A Z
-C Y
-A X
-A Y
-A Y
-A Y
-C Y
-A Z
-A Z
-C X
-C X
-C X
-C X
-B Z
-C Y
-C X
-C X
-A Y
-A Y
-A Z
-A Z
-A X
-C X
-A Z
-B Z
-A Z
-C X
-A Y
-A Z
-A Z
-A Y
-A Y
-A Z
-C X
-A Y
-C X
-C X
-A Z
-A Y
-C X
-A Z
-A Z
-A Y
-A Z
-A Z
-C Y
-C Z
-A Y
-A Z
-C X
-C X
-A Z
-A Z
-C Y
-A Y
-A Z
-A Y
-A Z
-C X
-A Z
-A Z
-C X
-A Y
-A Y
-C Y
-A Z
-C Y
-A Z
-A Z
-C Y
-A Y
-B Z
-C Y
-C X
-C X
-A Z
-C Y
-A X
-C Y
-A Z
-A Y
-A Z
-C X
-C X
-C Y
-C Y
-A Y
-A Z
-C X
-C X
-A Y
-A X
-A Y
-B Z
-A Y
-C Y
-C X
-C X
-A X
-C X
-B Z
-A X
-C Y
-C X
-C X
-A X
-A Z
-B Z
-A Z
-A Z
-A Y
-A X
-A Z
-C X
-A X
-C Y
-A Z
-A Z
-A X
-A Z
-A Z
-C X
-C X
-A Z
-A Z
-A Z
-A X
-A Z
-A X
-B Y
-A Z
-A Y
-C Y
-A Z
-C X
-A Z
-C X
-A Y
-A Z
-C X
-C Y
-A Y
-C Y
-A Z
-C X
-A Z
-A Z
-C X
-A Y
-A Z
-A X
-A Z
-A Z
-A Z
-B Y
-C X
-A X
-A Z
-A Z
-C Y
-C Y
-C X
-C X
-C X
-A X
-A X
-A Z
-A X
-A Y
-A Z
-A Y
-A Z
-C Y
-C Z
-A Y
-A Z
-A Z
-A X
-A Z
-A Z
-C X
-C Y
-A Y
-C X
-C X
-A Z
-C X
-C X
-C X
-A X
-A Z
-A Z
-A Z
-A Z
-B Y
-A Y
-A Y
-A Z
-C X
-A Y
-A Z
-C X
-A Z
-C Z
-A Y
-C X
-A Z
-B Z
-A Y
-A X
-A Z
-C X
-A Z
-A Z
-A Z
-A Z
-A Z
-B Z
-A Z
-C X
-A Y
-C X
-A Z
-A Z
-A Y
-A Z
-B Z
-C X
-A Y
-C Y
-A Z
-A Z
-C X
-C X
-A Y
-C X
-C Y
-B Z
-A Y
-C X
-A Y
-C X
-A X
-A Y
-A Z
-A Z
-A Y
-C X
-A X
-C X
-B Y
-A Z
-A Y
-B Y
-A Y
-C X
-A Z
-A Z
-C X
-C Y
-A Y
-C X
-C Y
-A Y
-A Z
-A X
-B Z
-C X
-A Z
-A Y
-A Z
-B Z
-A Z
-A X
-C Y
-A X
-A Z
-A Y
-C Y
-A Z
-C Y
-A Z
-C X
-C X
-A Y
-C X
-C X
-A Y
-A Z
-A Z
-A Y
-A X
-C Y
-A Z
-A Z
-C X
-A X
-A Z
-C Z
-A Z
-C Y
-A Z
-C X
-A Z
-A Z
-A X
-C X
-C X
-C Y
-B Z
-B Y
-C Y
-A Y
-A X
-A Z
-C X
-A Y
-A Y
-A Z
-A Z
-C Z
-C X
-C X
-C X
-A Z
-C X
-A Z
-A Z
-A Y
-C Y
-C X
-C X
-C X
-A Y
-C X
-B Z
-C X
-A Z
-C Y
-A Y
-C Y
-A Z
-A Z
-C X
-A X
-A Z
-A Y
-A Z
-B X
-C Z
-A Z
-C Z
-A X
-C X
-C X
-C X
-C X
-A Z
-A Y
-A Z
-A Z
-A Z
-A Z
-A Z
-C Z
-C Y
-C Y
-C X
-C Y
-A Z
-C X
-C X
-A Z
-A Z
-C X
-C Y
-C Y
-A Z
-A X
-C Y
-C Y
-C X
-A Y
-C X
-A Z
-A Z
-A Y
-C Y
-A Y
-C X
-C X
-A Z
-A Z
-C Y
-A Z
-C X
-A Y
-A Y
-A Z
-C Y
-A Z
-C X
-A Y
-A Z
-A Z
-A Z
-A Z
-C Y
-A Y
-C Y
-A Z
-A Z
-A X
-A Y
-A Y
-A Z
-C Y
-A Z
-A X
-A Z
-B Z
-C X
-C X
-C Y
-A Z
-A Z
-C X
-C Z
-A Z
-C X
-C Y
-A Z
-B Z
-A Z
-B Z
-A X
-A Y
-A Z
-A Z
-A Z
-A Z
-C Y
-A Z
-A Z
-A Z
-B Z
-A Z
-C X
-C X
-A Z
-C X
-A X
-A Z
-A Y
-A Y
-A X
-A Z
-A Z
-A Z
-A Z
-B Z
-A Z
-C Y
-C Y
-C X
-C X
-B Z
-C Y
-A Z
-C Y
-A Z
-A Y
-C Y
-A X
-A Y
-C X
-A Y
-C X
-A Z
-A Z
-B Z
-A Y
-C Y
-C X
-A Z
-A Z
-C X
-A Y
-A Z
-A Z
-A X
-A Y
-A Y
-A Y
-A Z
-A Y
-A Z
-C X
-A X
-A Z
-A Z
-C Y
-A Z
-C X
-A Z
-C Y
-A Y
-A Z
-A Z
-A Z
-A Z
-C Y
-A X
-A Z
-A Z
-A Y
-A Z
-B Z
-A X
-A Y
-C X
-C X
-A Y
-A Z
-C Y
-A Z
-A Y
-A Y
-A Z
-A Y
-A Y
-A Z
-A Z
-A Z
-C X
-A Z
-A Y
-A Z
-A Z
-C Y
-A Z
-C X
-A Y
-C X
-C Y
-A Z
-C Y
-A Z
-A Y
-C Y
-C Y
-A Z
-C X
-C X
-C X
-A Z
-A Z
-A Y
-C X
-A Z
-A X
-A Z
-A Z
-C X
-A Z
-C Y
-A Y
-A Z
-A Y
-A Z
-A Z
-C Y
-A Z
-C X
-A Z
-A X
-A Z
-A Z
-C X
-A Z
-A Z
-C Y
-C X
-A Z
-C Y
-C X
-C X
-A Z
-A Z
-A Z
-A X
-C X
-A Z
-A Z
-C Y
-A Y
-C X
-A Y
-C X
-C Y
-A Y
-A Z
-C X
-A Z
-B Y
-A X
-B Z
-A Y
-A X
-C Y
-A Z
-A X
-A Z
-A Z
-C Y
-A Z
-B Z
-C X
-C X
-B Y
-A Z
-A Z
-A Z
-C Y
-C X
-A Z
-A Y
-A Y
-A Y
-C Y
-C X
-A Z
-A X
-A X
-A X
-A Z
-A Z
-A Z
-A Z
-C X
-C X
-A Z
-C X
-A Y
-C X
-B Z
-A Z
-A Z
-C X
-A Z
-C X
-C X
-C X
-A Y
-C Y
-C X
-A Y
-C X
-C Y
-B Z
-A Z
-C X
-A Z
-A X
-B Z
-A Y
-B Y
-A Z
-A Z
-A X
-A Z
-A X
-A Z
-A Z
-C X
-C Y
-A X
-C Y
-C X
-A Z
-A Z
-A Z
-C Y
-A X
-A Y
-A Z
-A Y
-C X
-B Z
-A Z
-A Y
-C Z
-C X
-A Z
-A Z
-A Z
-B Z
-A X
-C X
-A Z
-A Z
-B Z
-A Z
-A Z
-B Z
-A Z
-C X
-A Z
-C X
-A Z
-C X
-A Z
-C Y
-A Z
-A X
-A Y
-A Y
-C X
-A Y
-C X
-B Z
-A Z
-A Z
-A Z
-A Z
-C X
-A Z
-C X
-A Z
-A Y
-A Z
-B Z
-A Y
-C Z
-A Y
-C X
-A Z
-A Z
-A Y
-B Z
-A X
-C Y
-A Z
-A Y
-A Z
-A Y
-A Y
-A Z
-A Z
-A Z
-A X
-A Z
-C Y
-A Y
-A X
-A Y
-C X
-A Y
-C X
-A X
-C X
-A Z
-C Y
-A Y
-A Z
-A Z
-A X
-A Y
-C X
-C X
-A Y
-A X
-A Z
-B Z
-A Y
-A Z
-A X
-A Z
-B Y
-A Y
-A Y
-A Z
-C X
-A Z
-A Z
-A Y
-A Z
-C Z
-A Z
-A Z
-A Z
-A Z
-C Y
-C Y
-A Y
-B Z
-C Y
-A Y
-C Y
-A Z
-A Z
-A Z
-A Z
-C Y
-A Z
-A Z
-C Y
-C X
-A Y
-A Y
-A Z
-C X
-C Z
-C X
-C X
-A Z
-A Z
-A Y
-A Z
-A X
-C Y
-A Z
-A Z
-C Y
-C X
-A X
-A Z
-A Z
-A X
-C X
-C X
-C X
-A Z
-A X
-C X
-C Y
-A X
-A Z
-C X
-A Z
-A Z
-C X
-A Y
-A Z
-A Z
-A Y
-A Z
-C X
-A Z
-A Z
-C X
-A Y
-A Z
-A Z
-C X
-A Z
-A Y
-A Z
-C Y
-A X
-A Z
-A Z
-C X
-A Z
-A Y
-C Y
-B Z
-A Z
-A Y
-C X
-A Z
-B Z
-A Z
-C Z
-A X
-A Z
-A Z
-C Y
-A Z
-A Y
-C X
-C Y
-A Z
-A Z
-A Y
-A X
-C Y
-A Y
-C X
-C Y
-A Z
-C Y
-A Z
-C X
-A Z
-A Z
-A X
-A Z
-A Z
-B X
-A X
-A Z
-C Y
-A Z
-A X
-C X
-A Z
-A Z
-C X
-C Y
-C Y
-A X
-A Y
-C Y
-A Y
-A Z
-A Z
-A Z
-A Z
-A Y
-C X
-C X
-C Y
-C X
-A Z
-A X
-B Z
-B Y
-C X
-C Y
-A Y
-A Z
-A Y
-C X
-C Z
-A Z
-A Y
-C Y
-C X
-A Z
-A Z
-A Y
-C X
-C Z
-C Y
-A Z
-C X
-C Y
-A X
-A X
-A Y
-A Z
-B Z
-A X
-A Y
-A Y
-C X
-C Y
-A Z
-A X
-A Z
-A X
-A Y
-A Z
-A Z
-A Z
-C X
-A Z
-A Z
-A Z
-C Z
-C Y
-C Y
-A Z
-C Y
-C Y
-C Y
-C X
-A Z
-C X
-C X
-A Z
-A Y
-A Z
-A Z
-A X
-A Y
-A Y
-C X
-C X
-A Z
-A Z
-A Z
-A Z
-A Y
-A Z
-A Z
-A Z
-A Z
-A X
-A X
-A Y
-A X
-C Y
-A Y
-A Z
-C X
-A Y
-A Y
-A Z
-A Z
-A Z
-C X
-A Z
-C X
-C X
-C Y
-A Y
-A Z
-A Y
-A Z
-C X
-C X
-A Z
-A Z
-A Z
-C X
-A X
-A Z
-A Z
-C Y
-C Y
-A Y
-A Y
-A Z
-A Z
-C Y
-C X
-C Y
-A X
-C Y
-C X
-C Y
-A Z
-A Z
-A X
-C Y
-C Y
-A Z
-A Y
-C X
-A X
-B Z
-A Z
-C X
-A Y
-A X
-A Z
-A Z
-A Z
-C Y
-C X
-A Z
-C X
-A Z
-A Z
-A Y
-A Z
-A Y
-A X
-A Z
-C Z
-A Z
-A Z
-A Z
-A X
-A Z
-A X
-C X
-A Z
-A Z
-C Y
-A X
-A Z
-C X
-C X
-A Y
-A Z
-A Z
-C X
-B X
-A Z
-C Y
-A Z
-C X
-A Y
-A Z
-C X
-A X
-A Z
-A X
-A Z
-C X
-A Z
-A X
-A Z
-C X
-C Y
-A Y
-A X
-A X
-A Z
-C Y
-C Y
-A Y
-A Y
-A Y
-A X
-A Z
-A Z
-A Z
-C Y
-C Y
-A Y
-B X
-B X
-A Z
-C X
-C X
-A Z
-C Y
-C X
-A Z
-A Z
-A Z
-A Z
-C X
-A Z
-A Z
-C Y
-A Y
-C Y
-A Z
-C Y
-C Y
-A Z
-C X
-A Z
-A X
-A Z
-C X
-C X
-A Y
-B Z
-A Y
-C Y
-A Z
-C Y
-A X
-C X
-A Y
-C X
-A Z
-C Z
-C Y
-A Z
-C X
-C Y
-A Z
-A X
-A Z
-A Z
-A Z
-C X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-A Z
-A X
-A Y
-C Y
-B Y
-C X
-B Z
-A Z
-A Z
-A Y
-B Z
-A Z
-A Z
-C X
-C Y
-C X
-A Y
-A X
-C X
-C Y
-A Y
-C X
-C Y
-A Z
-A Z
-A Z
-A Y
-C X
-A Y
-C X
-B Z
-A Z
-A Y
-A Z
-A Z
-A Y
-C X
-A Z
-C X
-C Y
-A Y
-A Z
-B Z
-C X
-A Y
-C X
-A Y
-A Z
-C X
-A X
-C X
-B Y
-C X
-A Z
-A Y
-A Z
-A Y
-A X
-C X
-C X
-A Y
-C X
-A Y
-A Y
-A X
-B Y
-A Y
-C X
-C X
-A Y
-B Z
-B X
-B Z
-A Y
-A Z
-C Y
-A Y
-B Y
-A Z
-C X
-A Z
-A Z
-A Z
-A Z
-B Z
-C X
-C Y
-A Z
-C Y
-C Y
-A X
-C X
-A Z
-A Z
-A Z
-C X
-C X
-C X
-A Y
-C Z
-C Z
-A Z
-C X
-A Y
-A Z
-A Z
-A Z
-C X
-A Z
-A X
-A Z
-A Z
-A Z
-A Z
-A Y
-C Y
-C X
-A X
-A Y
-C X
-A X
-A Z
-A Z
-C X
-A Z
-A X
-A Z
-A Z
-A X
-A Z
-A Z
-A X
-A Z
-A X
-B Y
-A Y
-A Y
-C Y
-A Z
-A Y
-C X
-A Z
-A Y
-A X
-C Y
-B X
-C Y
-A Z
-C X
-A Y
-A Z
-A Y
-A X
-C Y
-A Z
-A Z
-C Y
-C X
-A Z
-C X
-A Y
-C X
-A Z
-A Y
-A Z
-A Z
-A Z
-A Y
-A Z
-C X
-C X
-A X
-C X
-C X
-A Z
-C X
-A Z
-C Y
-C X
-A Z
-A Z
-A Z
-C X
-A X
-C Y
-A Z
-C Y
-A X
-A Z
-C X
-A Z
-A Z
-A X
-A Z
-C X
-B X
-A Z
-A Z
-A Z
-C X
-A Y
-A Y
-A X
-C Y
-C Y
-A Z
-A Y
-A Z
-A Z
-C X
-A X
-A Y
-A Z
-A Z
-A Z
-A Z
-B Z
-C X
-C X
-C X
-A Z
-C Z
-A X
-C X
-A Z
-C Y
-A Z
-A Z
-A Y
-A Y
-C X
-A Z
-A X
-A Z
-A Z
-A Z
-A Z
-C Y
-A Z
-A Y
-A X
-A X
-A Z
-C X
-A X
-A X
-A Z
-A Y
-C X
-A Z
-A Z
-A Y
-A Z
-B Z
-C X
-C X
-C Z
-C Y
-C X
-A Z
-C Y
-A Z
-C Z
-A Z
-A Y
-A Y
-A X
-A X
-A Z
-A Y
-A Y
-A Y
-A Y
-A Z
-C Y
-A Z
-A Z
-C X
-A Z
-A Z
-C Y
-A Y
-C X
-A Y
-C X
-A Z
-B Z
-A X
-B X
-A Y
-A X
-A Y
-B Z
-A Y
-A Z
-C Y
-C Y
-A Z
-A X
-A Z
-A Z
-C Z
-A Z
-A Y
-C X
-A Y
-C X
-A X
-A Y
-C Y
-A Y
-A Z
-A Z
-C X
-C X
-B Z
-A Z
-A Z
-A X
-C X
-C Y
-A Z
-A Z
-A X
-C X
-C Z
-A Z
-C Y
-A Y
-B Z
-C Y
-A Z
-C X
-A X
-A Z
-A Z
-A Z
-A Y
-C Y
-A Z
-C Y
-A Z
-A Z
-A Z
-A Z
-A Y
-C X
-A Y
-C Y
-B Z
-A Z
-C X
-C Y
-A Z
-C X
-A Z
-C X
-C Z
-A Z
-C X
-C X
-A Z
-A Z
-A Y
-A Y
-A Y
-C X
-A Y
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-A Z
-A X
-C Y
-A Z
-A Z
-A Z
-A Y
-A Z
-A Z
-A Z
-A Z
-C X
-B Z
-A Z
-A Y
-A Y
-A X
-A Z
-A Z
-C Z
-A Z
-C X
-A Y
-A X
-B Z
-A Z
-A Z
-A Z
-C Y
-C Z
-C X
-A Z
-C Y
-C Y
-C Y
-C X
-B Z
-A Z
-A Z
-C Z
-A X
-A Z
-A Z
-A Z
-C X
-A Z
-A Z
-C Y
-C Y
-A Z
-A Z
-C X
-A Y
-C Y
-C Y
-A Z
-A Z
-A X
-A Z
-A Z
-A X
-A X
-C X
-A Z
-A X
-C X
-C X
-A Z
-A X
-A Z
-C X
-C X
-C X
-C Y
-A Z
-A Z
-A X
-A Z
-A Y
-A Z
-A Z
-C Y
-A Z
-A Z
-A Z
-A X
-A Z
-C X
-A X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-A X
-A Y
-A X
-C Y
-A Z
-A Z
-C X
-A Z
-A Z
-A Z
-A X
-A Z
-A Z
-A Y
-C X
-A Y
-A Z
-C X
-A X
-A Y
-A Z
-A Z
-A X
-A Z
-A Y
-C X
-A Y
-A Z
-A Z
-A Z
-A Z
-C X
-C Y
-A Z
-B Z
-C X
-A Z
-A Z
-C Y
-C Y
-C X
-A X
-C Y
-B Y
-A Z
-A Z
-A Z
-C Y
-A Z
-A X
-A Y
-A Z
-A Z
-A Z
-C Y
-A Z
-C Y
-C X
-A Z
-A Z
-A Z
-A Z
-A Z
-A X
-A Z
-A Z
-C X
-A Z
-A Y
-C Z
-A Z
-A Z
-A Z
-B X
-C X
-A Z
-A Z
-A Z
-A Z
-C X
-A Z
-A Z
-A Y
-A X
-C X
-C Y
-A X
-A Y
-C X
-A Z
-A Z
-C X
-C X
-A Z
-C X
-A Z
-A Y
-C X
-A Z
-B X
-B Y
-A X
-C Y
-A X
-A Y
-C Y
-A Z
-A Z
-A Z
-C X
-A Z
-A X
-A Z
-C Y
-A Z
-A Z
-C X
-A Z
-A Z
-A Y
-A Z
-A X
-A Y
-A Z
-C X
-C Y
-B X
-C Y
-A Y
-A Z
-C X
-A Z
-C X
-C Y
-A X
-A X
-A Z
-A Z
-C Y
-A Y
-A Y
-A Z
-A Z
-C X
-A X
-C X
-A X
-A Y
-C X
-A Z
-A Z
-B Y
-A Z
-A Z
-A Z
-A Z
-A Z
-A X
-A Y
-A X
-A Z
-A Z
-C X
-A Y
-A Z
-C Y
-C X
-C X
-C X
-C X
-C Y
-A X
-A X
-C Y
-A X
-A Y
-A Y
-B Z
-A Z
-B Y
-C Y
-A X
-A Y
-A Z
-A Z
-A Z
-A X
-C X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-A Z
-B Z
-A Z
-A Z
-A Y
-C Y
-C Y
-C X
-A Z
-A X
-C X
-A Y
-B Z
-C X
-A Z
-C X
-C Y
-C Y
-A X
-A X
-C X
-A Z
-A Z
-A Y
-A X
-A X
-A Z
-C Y
-B X
-A Z
-A Z
-A Z
-A Z
-A Y
-A Y
-A Z
-C Y
-C Y
-A X
-A Z
-A Z
-C Y
-A Y
-A Y
-A X
-A Y
-A X
-A X
-A X
-A Z
-A Z
-A Y
-A Z
-C X
-A Z
-A Y
-A Z
-A Z
-A Y
-A Z
-A Z
-C X
-A Z
-A Y
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-C X
-B Z
-C Z
-A Z
-A Y
-A X
-A X
-C Y
-C Y
-A X
-C X
-B Z
-A Z
-C X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Y
-A Z
-A Z
-A Y
-A Z
-A Y
-A Y
-A Z
-A Z
-A Y
-A Z
-C Y
-A Z
-A Z
-A Z
-C X
-C X
-A Z
-C Y
-A Z
-A Z
-C X
-A Z
-C X
-A Y
-A Z
-C Y
-A Z
-A Z
-C X
-C Y
-A Z
-C X
-C X
-A X
-A Y
-C Y
-A Y
-A Z
-C X
-A Z
-A Z
-A X
-A Z
-C Y
-A Z
-C X
-A Z
-C X
-A Z
-C X
-A Y
-C Y
-A X
-A Z
-A Z
-C Y
-A X
-A Z
-A Y
-B Z
-A Z
-A X
-A Z
-A Z
-A X
-C X
-A Z
-A Z
-C Y
-A Z
-A Y
-A Z
-C Y
-A Z
-A Y
-A Z
-C Z
-A Y
-A Z
-A Y
-C Y
-A Z
-C X
-A X
-B Z
-C X
-C X
-A Z
-A Z
-A Y
-A X
-A Z
-A Z
-B Z
-A Z
-C Z
-A X
-A Z
-A Z
-A Z
-A Z
-A X
-A X
-A Z
-A X
-A Z
-A Z
-A Z
-A X
-C X
-C Y
-A X
-C X
-C X
-A Z
-A X
-C Y
-B Z
-A Z
-A Z
-C X
-B X
-A Z
-A Z
-C X
-C X
-B Z
-C Y
-A Z
-A Z
-C X
-A X
-A Y
-C Y
-C Y
-B Z
-A Y
-C X
-A Z
-A Z
-A Y
-C X
-A Z
-A Z
-C X
-C Y
-A Z
-C X
-C Y
-C Y
-C X
-C Y
-A Z
-C Y
-A Z
-C X
-A Z
-C Y
-C Z
-A Z
-B Z
-A Z
-C X
-C X
-B Y
-B Z
-C Y
-C X
-C X
-A Y
-C X
-C X
-A Z
-A Y
-A Z
-C X
-A X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-C X
-C X
-A Z
-C Y
-C X
-A Z
-B Z
-A Z
-A Z
-A X
-C X
-A Y
-A Z
-A Z
-A Y
-A X
-C Y
-B X
-A Z
-A X
-C Y
-C X
-C X
-C Y
-C Y
-A Z
-A Z
-C Y
-A Z
-A Y
-C Y
-A Y
-C X
-A Z
-C X
-C Y
-C Y
-A Z
-A Z
-A X
-A Y
-A Z
-A X
-A Z
-A Z
-A Z
-C Y
-A Z
-A Z
-C X
-C Y
-A Z
-A Z
-A Z
-C Y
-C X
-A Z
-C X
-A Z
-A Z
-A Z
-A X
-A Z
-A Z
-A Y
-B Z
-A Z
-A Z
-A Z
-C Y
-A Z
-B Z
-A Z
-C Z
-A Z
-A Y
-C X
-C Y
-C X
-C X
-A Z
-A Z
-A Y
-A Y
-A Z
-A Y
-B Z
-C Y
-A Y
-A Z
-C X
-A Z
-A Z
-C Y
-A Y
-A Z
-A Y
-C Y
-A Z
-A Z
-A X
-B Z
-A Z
-A X
-C X
-A Z
-C Y
-C Y
-A Z
-B Y
-A Y
-A Z
-A Z
-A Z
-A Z
-C X
-C X
-A Z
-C X
-A Y
-A Z
-A Z
-C Y
-A Z
-A Z
-C Y
-C X
-B Z
-A Y
-A Y
-C X
-C X
-A Z
-A X
-B Z
-A Z
-C Y
-A Z
-A Y
-A Z
-A Z
-A Y
-C Y
-C X
-A Z
-C X
-A Z
-C Y
-A Z
-C Y
-A Y
-A Z
-A Y
-A Z
-C X
-A Z
-A Z
-C X
-A Z
-B Y
-A Z
-A Z
-C Y
-C X
-C X
-A Z
-A Z
-C X
-B Z
-A Y
-A Z
-A Y
-A Z
-A Z
-A Y
-A X
-C X
-C X
-A X
-A Z
-A Y
-A Y
-A Z
-A Y
-A Z
-A Z
-C Y
-A X
-A Z
-A Z
-C X
-A Z
-A X
-B X
-C X
-A Z
-A Y
-B Z
-C X
-C Y
-A Z
-B Z
-C Y
-A Z
-A Z
-A X
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
-A Z
--- a/03/03.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-const input = "03/input.txt"
-
-function parse(fh::IO)::Vector{String}
-    readlines(fh)
-end
-
-function run(v::Vector{String})::Int
-    count = 0;
-    for s in v
-        l = length(s);
-        a, b = s[1:div(l, 2)], s[div(l, 2)+1:end];
-        c = intersect(a, b);
-        @assert length(c) == 1;
-        c = c[1];
-        score = islowercase(c) ? 1+c-'a' : 27+c-'A';
-        count += score;
-    end
-    count
-end
-
-function runbadge(v::Vector{String})::Int
-    count = 0;
-    for i in 0:div(length(v), 3)-1
-        group = v[1+3i:1+3i+2];
-        shared = intersect(group...);
-        @assert length(shared) == 1;
-        c = shared[1];
-        score = islowercase(c) ? 1+c-'a' : 27+c-'A';
-        count += score;
-    end
-    count
-end
-
-
-function run_03(f::String)::Tuple{Int,Int}
-    open(f; read=true) do fh
-        p = parse(fh);
-        (run(p), runbadge(p))
-    end
-end
-
-println(run_03(input));
--- a/03/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-WjmsdnddnmQPZPPJPL
-bQllTtpBlgwtrbbCwfZcfSFPSfLCSF
-GgVgQrlpphBGrlVGgTtsRHRWVRMzRdVsqdnDnV
-MMTcbpnfNGQbMjgsRwSzRptRzz
-lPqCCqQdQqQmCPRzRVSwtzgqqwqR
-lrDdllPdBWdDFQFnMbDNDn
-FldWTldlpBSLzvpnpSTpWbDhbHNDPHhJcNHNDwbH
-qVCGQRGrrgMQrJhPNchgvgJhNc
-frjGfMrGQMjsRrRQjvQGmrQQszTTpSLBznlzBlLLSBLLSZTn
-TPZZZMTTbNTZNtTlTbjPVRVGzpGQLLzdGgmslhzSzgLzQh
-wrfwDDvcnFvCfrrSQsmzGGQQdndsGg
-qfHwHCqCqCrFJrcBHCCJRmWTRTmVMttjRjRHZMNV
-vpbqnzbPmWLFjFLBnjZg
-NltQcCClQlcGQGtMTCRdGTGBFZRLZjFFZZhBPLrFHZFjHf
-lMtlGMwMsCCNlTwtsCPzzmPmmVpmpWqVWsWz
-VmWVSchSrScGtwlVtBnwBVFF
-RZZPRNpPCLZvZPZNCLbQPZNBFtttmwBMTMTtttCwtgwBgl
-RNNmPvbQQjPRQQNNHpNbhsfzWJqqSJcsGHhHcfhq
-dtJvcpccWvLDztRCRRCrCC
-qHVslPzPqHqzmPhTzmDFggjrHrSCNFFFSjgR
-qPVPMhszZPVhwBZcdpvZJncbcJ
-HBNLlBDtvLDHhHLvfwlFjqfQTFqqWfST
-ddsGcggJncZVRdGCdZdcWWzSFrjzQFrfTzqfCjFw
-VdgscZmbZNBvbDHTbL
-GtSZQqpHpHfGHzzqHzHfSbPbnJCrRCnJChmjnJnbSh
-DvcTNTDWlNDWdlbnnbjmRhRrCCRd
-cclNlwBRvvTNccRlBNRspVLLZzVzVZQqfqqLpzpw
-dBSfHdZvMQMdNVpWRmWmLCmmtB
-rbTTrrjDcqcrrqrjjJGGclltPCWDmvtpmpPpvRDsCspsLC
-vlhjThlqcjrnTvThndddHZngMnfwNQFNFM
-tHqfszrgLsvgqtHrHtwVCGBRRjGSCwsCsmmV
-MdFMclPmcDQFDlDdlZPmbVpCbFpCbBSCCRGCFpbV
-mcDJdDQMcDTZQhhNNPldhhDtvHLgqtzgLvzTzWHWnWfvvz
-sVdGlTMMVTGCdsTMHHWWnNBzNWpNWCpW
-mPmjFhlwmwmWrpSrSWHB
-jhPhjwgthtFFjRwjZgjGdJcdflfqMsZLLsdZdc
-CBRsTsBBzLCfLqtqBRPNDQglSttlcgDlgGGt
-rJdbrJjrdbVJZdVZCGrNNcgDQlcQrggl
-FpFbbppjFCdwmTvsvfzmTnTBfq
-cqhcWqqCNjGWqcqhGGZzngftmptLZLGZTn
-brJHBbPVHPvSsdHrzQLzZgpfVzpfQtnL
-dHFPBPrBJFRzcWNFhWwN
-QTBTfQTZsjWDJBJd
-FgFWNqWGDPqlPllp
-CCvHzSWFrrtvNvNNHLGQQfbVRRfHZcZcVTTTnZ
-ZCCHHCVRZzBZQThM
-nljDtcqnhcfbwjwltfLQMLLQQppJBMLQJL
-qDsqschsqblDqjcqtRmNVVdNsddNNPmFgV
-QQRnqGBSpQnMmSGmRQQFtdcbbtHHccjpTFcTfF
-wCNPNwNNWNgZHJHJFffqCjbj
-ZNPzNWgNrsmzMVqsqs
-pVWlMBWjlWWqspWDjdjMpMDCPtmmdbhtQtQtbGPCzChchz
-HZNgrHSvHwnFZnvgNvnwLPBGQHmCmtPmtBCGGCmQhG
-FrNfvSNSZLZJrJsVlRWWWqRBVTff
-PQctSHQDPSQcbShpFzbmFddpmdmR
-wqWVwvwNCJRhmdhwJw
-nMnWggVqRVZqHBSBsQsQGDSZ
-qppwrgZSLsVbbfvZ
-hhBHPQQChCDcPcsvvhbGbsllJTfv
-MDWmWFCPFWtgpRWjws
-bmRjdmrJRjhJdJLZBjTFfHGTtQFTSQBS
-wCNVnsspwsnvNDwnsDwSBHtDHHQGTFQFtMrQMS
-nWsNvqVgVcqdJrchrz
-MZlfqlmblmMRWhWNsjSQfh
-CznczgtDFnVtFBNSRNttvhQsNh
-SGDFzVrzVPrGHVnzCPVnlZlPwTbpTqlbqLMpbLlq
-lbbbGDlwLDLjvDvm
-FQfQnLTWVcPChtjmjWSj
-cfgzzgfgfVdzTdfNwBpbLbwdRbpZGrdw
-mwnWtbmdWdccwtgTmwnQfPqsqLQQJQQLsfQQ
-SjrZbhvBZzPHQqfGJfjG
-FlrMBSvMZZFBZhShMMdctWDtmFNDbDTmtmpt
-ndHWprpqFTnnpdNFlhljzlGTwDGzlhGz
-fvZmmVVfJctMZsgMgmcBmsZhwQlGDCzPPZWDGDjCllhC
-WsmvmsmRNnpRHdbS
-LgZSvhvcsWtcWnjrFrWjjjnPWW
-DJDfNlDNRFlpMlFLFP
-TmqTqDHdmfwJRwfdQJLHzzSggHZZcGzhtZvcZhzG
-lbTpqhhgSlgtlTqSDzzLPPPrLGTTGnLm
-VwGfQGBGZWNnmDLPznLB
-vQdfZFWvFMMFwWGGhpGqJbpFtgbS
-hSvCvFRDwmzCCHrszb
-jdMgfTblgjJTLLLzqqGscmPmlqPzHc
-bjQLTTbZMfJffZBBWdjBBQwVDntFpRvvDVvSnhppFv
-FFnFQndPqzmjHscmJFwc
-ZrZrRgDphGGDZgRRBSBNMHHvmwJJSNJHcv
-DGrbbthfWWWDgtfffttfpGPVqnmblqPqCdQTlTPCzTll
-sHTsGrHpsftmddRRZfRv
-MqFcqcMQbMcVPCdFZCzZsRsFzL
-qnVlBbcJJbbMcbgQJMMbQlDWWwHWSWwpTsGHGrpDWG
-qpmvVVcGvVVcVmDsCfqTHLLJzTjfZzLZ
-rSSgwwnSRRBrQrZzZHCQrZ
-BFgFRgdNnSBbbnhSMBSNFdsWVtpWmzsGtvpVPvGWVDDN
-fBBRfJBzzMRGRzCBgWtbCWtbgHHHWdqt
-mvNcDcsDLLnnqfbv
-hpTsTsTrDrfpMSFFZjPFMrSP
-CNQGGDMFWGnWWvvNMQFPvrgzBLVBLszwgggLgw
-mppZVZtZRTbTTpRccVbgrSLzSPSzBrfbPBbSPw
-VtZJhRJcTpJTHlhtHZCFFWFjNjGGnFhCqDqG
-cppcZGcGgGpdTgSSnmpFMFrFzmwqwmrHwz
-RStQJNCNvfBQNjrqmrjFrBMzFB
-LJDNNJCDLcdLnSVd
-gNrBNSrNNtSjBndzmzlVnm
-MbfqfpCLpCsLqsLFSbQLfnMdcdRRcdzldlnljzncnJ
-QPQLqZqhSqhvtvTTWrNg
-DtrrcGvtLnrrvLrfctfHztrfQpbwwphpdSbbPPPwFSFFRPwH
-gggBqTNdTNjqWBlNmCqCmNggQPhpPPPbhhQpSBpJwbSJSQFR
-ZglTmgWNgVZMZdsGMcvDcMdMnz
-bjtTFsPmmtpvVlQHlQJQnJjn
-WzDzwLCSLrrDNLdrSZRCwNzrlQlJMnJQJJVhbcMhgllwnJQh
-fRCZzrWRzzGbGvTmBPTf
-lVlfJVblPQbllflfLdJdvGpjnFRFqJFnDqpJjnpF
-HcwZMgmwWCHHCSwcWCcgSCtCqqpFppGDqvDnRhgnnqFDpjFT
-cwCHtGrCssWHCCWZZMbPPNBVbNfVbPllVszf
-DSpSnRwrZDPWsJdZ
-zjjlQVjlNZmCVCfhCfgFFfFFFqWJbgbFWHJH
-lNQMlGjQBZjCmhNMCChGzlVNrpTnccLLwcRwTSppSpprLRcB
-vLfvcgglbfLfgqdgNpPtzqDmPzmJTTztPCHT
-ZWSQVGwQcWjSshGwVcnSzDJZtPPTzmzzJHCTzDtJ
-SjVSrWVhQVQhwrLMcrFbfplcflvv
-NgtfSRPnnRrSlgsPhnShDWQlMWpVBMMMpCWVBpCQBB
-LLJnvwJvZHZbHTbVCQBppCFJCWWQBz
-wHTGZmZvdvLvjLwZdqngNgsGtrDPSDhtNfDf
-DwrDRlrwmbSbRgwsSbRwGJvQGqjJqGNTJTNGTSGn
-PZdMZzCQFBZWWFQvJZvcNcjqNjjZJG
-WHWCFHBBdzzMWhPFtFdMzlRsVbVmDrRVVrtQplwVwD
-bpWbJMWpJbprfNMrBfJfprWhPnGtnHnLHjPPjLvsWnHGvGvj
-qZdgVVgDQhQZlwcqgDcchldjjmLtntmntPQsmLnLPjssnL
-RVRlgcSSdglZczdqbTCrhBrBpNBSBSbF
-SgbGvfbnGgmnNnnzqMqqHHRzbZBzZR
-TWlssdFwWdtswWPtTtWltwdVHlZZzRHZBZRzrprqHMpqgZrq
-dssdCWTFwSvgmDjDCG
-pqsDnNzzZsdZSnDSpwjBCBWvgjvWjNFWQgWC
-lVGtRtLMGGfbTGTtTbQCQnBQBnBFgFQcgjfc
-GPbTbPtnPttmLTGRRbtmdwSDwpwwhZqmdpzDhDJd
-MdccRQMJvHdgZggvhjjMgHcHlWWqFFWmGqFbJWzzFLWlLmPm
-TDpSsTrtblSzQlGQ
-tfVNrwTwtswTssMRjMMQQddNMRCd
-GqGqGpFqqgDGFRqDwwqqmzpGTLPvVWMPVCPLJLRJJMLTlCWV
-rHrSbrsbQcbtdNHHHfdPlvWBLLWlvMTVlVLCJf
-rccbtthHSHsNHrrcttwqpnDFnMmpnzFnFhnF
-vQQQbRvlLjNNLLBzNllNHNBqGqhMWhGGhTqmPmqhWTFhRm
-tnsZwgSnCDrZSCDsfTMSGpPWmPSWmGmbFq
-CrVnfnCCtrCgfrffcrstDnJNlvJdNvzdBcHdLBJHvbBv
-nmQsMqTnLlmmpQZmTZcdHwCFSpHJSSWHSJVSWSHH
-vRgRRtfPvDjzDgDbsjzRvjfNNWWCSJFwrHCFbrCJWJHCSC
-GhsRBztDBgzRPstgzBLZcqmlcLMMlmdLQBZT
-CWfvvhfWrlllSSRrdQrQDQGQdTRr
-jsNctMZLmMZLMmmmbbNZswZNqBTHPHzBMHHTMGqBRMRPDQqP
-jcwjntLngngplgFhgRvJVp
-vchzqzwlhzRqzVZQwqtVPZLnLLbDnDFnbGLnDbPLDGWD
-pBTHpdpHsrNBBsgdrdCpCpCgRFCMFDLFWWnFWLRRGWbDFGSF
-prsBHfggjpjjcRQlqvtw
-VDwzLQrDDWrrwWbJrVJwVrVQfMfSCNPMfSlMlPcMmThChf
-tsjFdsRsgtRmGZHpHRgBClSlGSClcPhGCfPlllll
-qBBFBZZpmgdFHdstjFJbzVwJVqJWWbrvWJDL
-mgjZmrqmdsmGtDplglJgRVVc
-nPhnLvnHLtLnWzzcNwwcchVJRflhpc
-SnnLntLWZsMqZrSZ
-jcrNfnrNLNNqFgbDfCSgSQbS
-zPPHtMrGGptvTWPVvzvHRgQsbDsSRRCCQbtJsJDS
-wHzrWVzPwThGGwMHzTGGPGwhdlZnBndZLljNjBcLdZdNBN
-qNPhNqddBNhqvPhFvllNgNBHCrrCQnjpCfPVJnnJQJCjJj
-ZZbZTZcmGWWMDWRSDnBVQCjVDffJjnnVCJ
-SGBRTTZGGcLSSWTScsmcMbGlhgwFqslhzqggghwhNvwwvw
-GCCPwpsBqNSsBPpSCrSshzQzLhTvQhqTnhtTVQcT
-JDjFJfMJgWbWWlDJcnvvhvtdLnjnzhjz
-FlDflbZfZgJgMgbmgZJfSpGCvvrGrRCpCBrZRprw
-HwqhgFGSMgPPCGQQQnvvcpjn
-BllbdfRBsBmsmZlBTmQCjTnNWNCmNmvc
-lJDlBflDdbbRlLbfsbZBJtbRqrVFPnwwwhVMHwVrgJwwrSwH
-LTvLtTFLCddFTTthsbVVmHHcqVHmWRcmHL
-lBgwwNggwMwNVbjBCQcCqCRB
-nCMCwZGGNGJnGhtrzsdDDndtsF
-ZlZdJJplLZBDpJjNJlGjQCLmCQmTwVVCbQQbqWCT
-SfgFzftrnRzMnVbPPPQmPq
-FfmrRvgShchvFfghzRvgtvFBpJDpcGNGdBHJlpDDDJlDJZ
-LdNrLzjdWQnrDHsD
-tBZmBZtVZpldVMPRnsRQsnnsHVbRHs
-MlfldwMBBFMZTSFTSqLqcvSJ
-nJqBlvvBjHhBcqqRrGPrTrGpBCGzTG
-MfVCVMLZVZtQCdtLMtQtQSSSTSzFRSRPFpFRGpdTFd
-CCQQtQVgfbbQNggsNfQZZbHbcWmnhlhnvlnlHjJWvnhv
-SGmmGwVwnmhbhnhwhhwbdMgNNgjmvMDrJTCgmBTBBj
-ztFWcWQQfcRzzRFllvjDjggjDDfBgJMBgC
-QtzcJtFtqcFQRRWRRQWFzFGpVnVSGLLGZVGVqddbLqGL
-tBmdmQtjMMqDLqBtttQMjDdwwgwccMMbffllgzncwfFflF
-TPVHTVsRsJVHVrVvHvrRhVJbfCgFbzwbCGgFlwgcCwbn
-hssVWnRrTVZSSZZqjLddWtLBddqtQL
-WhhtGZtZGQZmvCfCwtvhqgbfdDJdfjlSDlSlBBJDSg
-rHnpFHnDrdBggJngnL
-HVcTzFPNzTpPPVrzmtwtvvvmNQwDQvWw
-dStBwStGGBrNnBdrSSMzvjhgFcvvDcnnvPDn
-RLZbCWWJbHRsTHspZWLcDWcPPhzczfjgPjjvjz
-ZmLHJqJsLJJHLRsmmmGSztQdQzmNBrBN
-JrmRVdvcmvvmvvRTdBVVfjFQLwjqLFLWFMqwcFjz
-DDhhttDHHHbHSnsDbHqMqzwQLLFwLsjjLLQf
-bSbPthtgGQPNPHnSDChCRJZZJRCZdCrCBZZZZvJd
-rqvVqNJpVVNwnqqTwthMMq
-jsFRFDQRLQDQmsPRmQsmcQFMzGhwBGBhTzTTzHnRhnhBhRwz
-dCccQcQsFCmCQfbJbvZMNZfJrJll
-TGjrrTRLHvrQrFDCrmzzVm
-NwWqqhndWtzDQhCzVCsh
-CSSwNNwqgBBBBbGGvLTTvb
-fRBRBHCVRRzcCdZHvRvZVCZLNjtwtNwNTtLjNtTpTNttfS
-DZshMssZmTMjwjSLtw
-QPrJDDJsPDFmFrFDscHHRzrcvccCZRVzrR
-zgqzLLvlvdgpgrWpWW
-RnJmNRncnScFmZSScrJQQdbpGdHbWHtPHpBHsdFdsW
-JDfRcrSnmDSJcNfrNZNjvlwjhllhMzlDqMqMvh
-fDLzSMLhhtDWMvtjCRRZjCHHJjChHN
-pmTNpVwPNbPwPBFRqRJqjCnFjZFV
-dTwpddsTbgbQBssprsgtvgcNLzWMctfSgcfWLt
-fbBsBTsNDhGBGZcLLLJJQffQLQ
-MpsCCMHClsHQqZcQWLqR
-FtjdCFzVljFlslVCpFrFjPhggBGDgNSTTgbGNmbGTr
-HqTfmsCFmPlGHddNVGpLhz
-JjjcQQJgjZvZZzzwgpNVGwLGgV
-nQnSbDDRbSQJQQpRZtZcZZsPPrFfWCPFWlrFsFPqmqFt
-TgTDDrCmqJDGLrhqLmLGqDQRFtttjMbQZJjtdtjFdsdF
-WHffcHWnlvvcSSWzPVvHpWWVRbFdQQtQnjwZFMwZtwddsZbd
-cBpPplVVPfvVGBDLGCBqmmLM
-dlMMmnmjvCCjJrrvMdgHcbcFbqFbzQrFbGzb
-tPhRBRZPtZRshTzRsNShRZNGDfGgFFbFQqbGHDHbqfGD
-TSPhBVsTwRBTpVtRZpVhZLJjWzLjJlJlJvmwWWzwWn
-WcvLLgLcczLTDtccbLcgzMMfPsGwRPjwfMwHMfMvMp
-QVmlPQCdJlJJJlFJJJnPQQhlwwMMMnMwNMpwMGwwfswwGMsR
-lrSCZZVFhPSZgzgWttWBcc
-bwbbZLlbwlJhBzFCgtTGRGQldQRmQW
-SSnpHnPHqpmggCWgdT
-PPscHHTfcsPSDVfVssjvwFJLBJFjFJJZFJLNLwrL
-nLgDSHgwRgGnHjjNfTRhjPVpWV
-BstQsvhQZQQbMvCvMPVNWpPcTjfmPmmW
-brtCrtvtzrhdSDJDwh
-dTQTwgmZQbDzzMQCCl
-WLLtntFnfnRHbttnSRRzSMVGDDMGzVlV
-JsPhFtfbLWnsLPLqgdJcjmcwTwjcdw
-wMwMbMRRBBMLPBlhLRQlhPcWzgJNvJtzWNtJptpgjJgpBj
-TnmGGmVnFFNSZsnZqFsWzWjrTJzvzWvWgWtTWz
-qnHGnVSsqZCddnGCGCSNdDbLQPcLLQlDhPRMhb
-NGsBTBlqsvfQBQqsTLTFltRMmRwmmHmFtPSRhM
-gjZWJWCZdDpjggDdgnpWdZZJtFwFRFFRMwbbmRPtShnwRbtt
-zZpSDDgpzcDddjVWggJsQGrfQvrQcTGTGrTrqr
-hpJchhFWMpRDWHWcDGnCGrnGnwPTwpQnCt
-bmgddgmlmjjbfddgmmmNvGQLrtfTwrTtLtGTLQVQQP
-qqbmdZgzZbvgPDccHcZPhWWH
-VVrdQZZrZSZFgQTTTzggrVZVMlfBBfvcMBCBslMhBvsMBSff
-bQwnHwbNpwcsCwjMBw
-pHqqPnJHqpPNJFzqTzQWWDQQZq
-HgwTDfgBwBgcRHqRRjHqHTzQQClSzvlzPVSQLvbbPC
-MnhtNZNnJpWpGhMQbCCPVSPLNmSPQQ
-rrhJMFJJZFJpHcjRLFRfHjgj
-vGvGMBlttBltvjdgbPsrsDWdjPPP
-HnJQHVqNmQHmZsDZPPrDWpgFps
-JSqJQVVDqqVfJNfRffGSGMBwGTCCCTlBMSBl
-PsFZPfGbDNbtQmCCmCBBbmmL
-dcRdhSrCqjThTRcTpLzHQzTmpmlgBz
-hhhcqCvwhhVhfPNvsMstZtsZ
-VvGwBBwvZtGgfZCqShnFFjSstCMC
-NlTRdvpDdTRNzdTHHnMssCnCnCqjSz
-LvWvPcWLpGwBwVVgVc
-bVVmSrLmLSJzTZMSFTBdMj
-QnvqRGGDvWpQWGDpvsRZLBzTRjBTtjRTPtBF
-QWGvDpqcvpGWQpGngqGQGwpLhJVNJcrbfrVbfbhHrmlVJHVV
-NGRGPZWZpblGcJtfssSSsbffCs
-gwRhjvrgjmwgnzvJJJtVCtHJqs
-rrmLrhwFFmmTMgFRjNZWNpZlZLppQNcDWP
-qsHZsHZrTBtZrHBNFCJGWrMcpcddWGJWLG
-mRDDzbPVDVlVDgbgRRvmwCcWdGvJwGddpvLm
-PnfDbPbVzDbVfjnnlbzhVFsspBSfFsssHQNTBpFqNQ
-gCmtbDqPVVVqggCGqTJjHMpMQfgMpMHQQpcM
-zNZnsSLzZzrlRhTTJMHppjfHSpvp
-nhdrBsLlRRrdTlsTVmCmGqDVFdtDPGwV
-FnqNfdGfgzmPLGmj
-blvVvbsRwgnzjCPcbT
-RWWvtvphnZQZwMBNdHfNDBZZdq
-DMRhDhdvnjhnPnvPMfdZSGTccGJFjGFFpFpFTbTpTW
-NVgVmtzVlLBmgztsBNmtgCmqFpJJFGGpGbrcGGsrcpbWPr
-zwBztLBzllQPDZvfQZfRfHSR
-mFCgPzmqgtPPqMmFWzbMttcRGvRclvHhWGGcZvclRfHh
-psSNnhnLGnwZHZGv
-hBpNLTNLBhsPmbCgBtPDbM
-JsbLLWLJRfQFnccmQhtvvPCP
-dwgrVwGpgVhCrrhPDHtC
-gpGSjpVdVpVppjjVZBwdCbFRWLzLMSRMbNzfzbWR
-DmMQMJmnmGwzGwwG
-ZcLcgLgcRsZSctHFWLGfjjBwvbvBsvjpfhGb
-GgFPqFtLRHLFSHLRRFRHHtMnJVNCQCrJCJCnMJDdnqDV
-tqdqFqdsRdVdtHMNdRZHTZLrHJgrlZQPJLgr
-GGwVcpGznmhbWhwcVVgzTrDrDDLZlTLLZQrJ
-nhbnbfjcnfMfFNVtBq
-QHmPNZvfCLsSwJSm
-pDhjpVDFcRBpFFjjMnRcVhpFCzbzsZbSSCtwtLMSLZLLtLbs
-FRjrnRchnfHPrrZlHl
-bjjMbdChgRDZthpQpRQnwRTprRwS
-mGzJsGsHzHGPvvvqvzGzSnglSJrrwQgnlQQSrlQl
-qvzHqHLHmHgPsNBdCdZtVBtVVMBFbh
-CctrCwrdpTwcpVrdpTpcrcnSJQttvQPHJQNQnQNjvvHQ
-zsqRlslRLqfgRmWsRgRzqzQnHjSBSQWJHPhHnSvHnJJJ
-GRgllbgfRgbzfRmwwcGdFMcTVPrFCF
--- a/04/04.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-using Transducers
-import BenchmarkTools
-
-const input::String = "04/input.txt";
-
-struct Range
-    a::Int
-    b::Int
-end
-
-function torange(s::AbstractString)::Range
-    a, b = split(s, '-');
-    Range(parse(Int, a), parse(Int, b))
-end
-
-function containsfully(a::Range, b::Range)::Bool
-    (a.a <= b.a && a.b >= b.b) || (b.a <= a.a && b.b >= a.b)
-end
-
-function overlaps(a::Range, b::Range)::Bool
-    containsfully(a, b) || (a.a <= b.a && a.b >= b.a && a.b <= b.b) || (a.a >= b.a && a.b >= b.b && a.a <= b.b)
-end
-
-function parse_ranges(fh::IO)::Vector{Tuple{Range,Range}}
-    collect(eachline(fh) |>
-        Map(l -> split(chomp(l), ",")[1:2]) |>
-        Map(es -> torange.(es)) |>
-        Map(Tuple))
-end
-
-function part1(rs::Vector{Tuple{Range,Range}})::Int
-    (rs |>
-     Map(es -> containsfully(es...)) |>
-     sum)
-end
-
-function part2(rs::Vector{Tuple{Range,Range}})::Int
-    (rs |>
-    Map(t -> overlaps(t...)) |>
-    sum)
-end
-
-function run_04(f::String)::Tuple{Int,Int}
-    open(f; read=true) do fh
-        rs = parse_ranges(fh);
-        a = part1(rs);
-        b = part2(rs);
-        (a, b)
-    end
-end
-
-println(run_04(input));
--- a/04/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1000 +0,0 @@
-1-93,2-11
-26-94,26-94
-72-92,48-88
-36-37,37-52
-2-98,1-98
-1-83,1-84
-74-79,76-76
-66-85,66-86
-6-73,6-73
-31-57,30-58
-1-98,1-98
-28-47,55-97
-29-71,70-72
-40-53,40-53
-14-71,39-71
-19-98,18-94
-94-96,81-95
-79-98,79-97
-52-66,60-61
-2-3,8-89
-53-59,59-83
-79-81,3-80
-14-84,84-92
-90-90,7-89
-10-76,11-76
-9-31,10-12
-8-8,8-72
-2-97,1-96
-3-33,2-94
-3-5,4-99
-46-94,8-94
-97-98,14-92
-60-98,81-99
-11-98,11-97
-27-82,26-81
-21-61,12-18
-26-55,26-56
-89-96,97-97
-29-30,29-31
-66-90,40-87
-7-49,8-88
-37-61,39-58
-8-65,9-96
-7-72,2-51
-14-73,15-56
-7-11,16-24
-12-83,13-85
-72-91,7-71
-78-82,56-77
-1-46,15-46
-1-76,1-75
-75-98,5-98
-37-41,22-41
-1-1,2-98
-76-94,77-93
-88-88,4-89
-86-87,38-90
-85-89,46-86
-64-99,1-99
-16-48,32-96
-6-95,6-95
-44-68,43-49
-19-78,19-79
-35-95,7-34
-72-72,32-71
-21-26,24-26
-20-57,21-58
-17-98,17-98
-22-97,21-98
-62-92,92-99
-1-74,1-75
-9-75,10-74
-5-7,4-8
-37-41,4-81
-3-96,4-99
-92-98,94-96
-69-89,75-88
-13-29,14-18
-35-48,42-49
-10-11,11-95
-17-33,32-32
-16-80,61-77
-38-41,40-42
-6-79,6-80
-51-95,50-52
-18-94,19-33
-95-99,15-96
-18-37,19-47
-25-33,24-31
-9-9,10-98
-5-72,6-72
-6-6,7-95
-39-96,38-84
-79-95,57-78
-61-67,61-61
-44-95,9-94
-69-93,16-68
-24-24,23-95
-56-90,49-57
-13-82,13-13
-5-94,4-94
-46-61,44-46
-3-37,7-84
-3-73,3-72
-2-2,3-95
-12-94,24-94
-37-58,37-57
-79-95,7-78
-10-77,76-76
-4-98,5-97
-64-99,27-99
-68-68,69-69
-18-28,18-29
-58-95,9-95
-4-93,5-94
-9-84,85-85
-50-89,51-90
-38-97,2-39
-22-70,78-90
-62-68,67-67
-36-44,36-44
-59-59,36-58
-97-97,1-97
-14-15,15-94
-90-90,3-62
-2-4,3-80
-29-97,81-97
-8-35,34-54
-14-57,14-60
-42-78,10-56
-32-99,31-98
-31-87,86-87
-44-57,44-57
-1-92,92-92
-8-69,5-83
-33-47,34-59
-94-98,11-98
-60-66,67-76
-20-21,21-81
-18-76,17-76
-24-61,24-62
-48-48,1-49
-28-84,85-91
-4-51,4-50
-30-32,31-69
-38-70,39-39
-28-92,37-79
-22-65,22-68
-29-56,9-46
-11-97,2-99
-4-98,31-94
-29-92,29-93
-93-97,32-92
-24-27,25-48
-54-55,6-77
-10-81,82-96
-27-94,28-89
-32-81,47-81
-64-83,65-97
-41-49,50-79
-99-99,14-94
-66-78,66-77
-16-95,17-95
-98-98,3-97
-2-6,6-53
-26-26,12-25
-2-54,3-86
-59-95,94-95
-40-62,2-40
-9-90,9-91
-3-53,2-52
-91-93,88-92
-63-98,64-99
-32-68,68-84
-34-77,74-80
-2-83,1-2
-32-79,60-73
-96-98,3-96
-28-74,29-87
-8-96,29-96
-50-64,50-65
-26-72,15-73
-63-80,44-86
-10-87,11-86
-5-94,36-94
-5-93,6-92
-3-92,4-93
-83-83,14-83
-9-9,9-40
-88-96,12-89
-31-56,34-42
-83-96,28-84
-5-6,6-36
-31-96,30-96
-26-82,41-82
-95-95,18-96
-32-71,31-71
-55-69,56-85
-1-87,2-98
-15-92,9-91
-1-76,1-76
-3-45,3-27
-53-59,52-58
-1-97,5-96
-2-78,4-78
-65-84,84-89
-74-80,79-79
-36-90,37-66
-3-66,54-74
-35-79,35-80
-76-76,75-75
-66-77,65-78
-3-91,3-90
-25-45,26-62
-35-35,36-82
-28-73,29-72
-36-96,37-64
-46-85,85-87
-70-99,2-99
-27-65,36-39
-8-70,70-84
-39-47,38-50
-66-89,23-66
-2-93,5-92
-1-70,92-92
-12-95,15-95
-44-85,45-84
-17-54,17-72
-20-23,19-31
-27-37,14-33
-16-96,82-96
-8-61,7-62
-11-91,73-96
-3-93,40-81
-30-30,29-90
-7-38,38-44
-70-82,12-93
-53-57,54-58
-37-66,66-99
-94-96,11-95
-11-97,11-96
-39-56,40-55
-27-74,1-96
-43-48,3-98
-62-79,63-79
-16-22,24-25
-1-96,2-99
-58-83,57-83
-43-76,42-67
-41-46,8-46
-2-52,2-55
-50-80,28-51
-9-34,9-9
-47-48,46-46
-47-85,85-99
-29-44,29-45
-20-89,19-88
-51-58,60-75
-57-58,57-57
-39-90,38-89
-18-77,20-76
-55-76,54-62
-26-83,25-82
-2-87,2-86
-1-83,2-94
-7-88,88-89
-6-33,7-99
-17-18,10-13
-40-99,40-99
-14-66,31-95
-46-98,46-98
-50-76,73-76
-39-45,2-80
-19-76,18-23
-19-92,98-98
-95-95,1-94
-1-86,87-88
-44-86,45-87
-4-99,4-87
-15-30,14-16
-11-66,13-76
-1-84,14-55
-2-72,2-87
-34-83,77-83
-13-90,30-33
-55-77,49-54
-18-25,7-16
-46-46,47-91
-14-86,14-58
-14-75,79-99
-13-45,14-46
-6-26,7-81
-24-99,35-48
-3-95,94-99
-71-81,20-71
-30-30,31-82
-15-15,14-41
-81-92,82-87
-3-49,48-67
-2-89,2-90
-18-92,19-92
-9-76,8-70
-40-47,41-64
-53-81,81-88
-44-86,44-44
-4-90,98-98
-8-94,95-95
-31-31,32-78
-31-82,30-83
-59-59,40-60
-48-69,48-68
-9-28,28-51
-23-90,23-91
-25-36,57-93
-31-88,30-32
-6-99,4-15
-9-68,28-69
-2-99,3-99
-3-31,30-32
-4-99,4-98
-17-74,11-18
-19-91,19-70
-74-97,75-89
-80-80,33-79
-10-76,2-4
-4-98,18-94
-1-63,1-63
-5-97,5-96
-16-63,16-81
-2-92,91-92
-1-78,79-79
-60-99,35-98
-74-84,39-73
-9-87,9-88
-78-85,77-78
-1-1,1-43
-11-44,12-43
-33-93,9-98
-6-74,5-65
-4-50,4-6
-27-30,25-39
-3-69,39-45
-83-85,86-86
-10-49,50-50
-81-83,8-82
-17-17,18-63
-10-24,20-24
-28-85,86-92
-36-36,37-69
-49-73,46-49
-8-88,7-88
-8-71,9-62
-10-47,46-75
-95-95,92-96
-10-97,7-7
-4-9,3-97
-58-93,43-95
-41-94,40-75
-5-79,3-79
-45-76,46-77
-15-88,7-14
-3-93,3-93
-96-99,4-97
-4-9,6-13
-69-77,5-61
-47-56,71-72
-98-99,15-97
-19-57,53-54
-14-58,37-59
-5-90,22-97
-79-81,63-80
-32-65,33-70
-2-50,50-50
-84-96,7-96
-26-26,27-95
-99-99,2-98
-21-39,21-21
-53-80,54-80
-69-98,59-68
-51-57,57-59
-56-59,29-72
-1-98,2-99
-23-82,34-83
-29-67,30-67
-69-84,85-85
-7-78,78-88
-26-80,81-81
-12-43,12-97
-46-76,45-78
-10-22,9-94
-26-29,25-36
-26-85,26-26
-14-98,15-19
-5-23,9-96
-54-55,55-70
-97-99,2-98
-39-71,3-26
-6-96,6-99
-24-89,62-89
-21-37,37-38
-16-98,15-99
-62-64,2-63
-4-73,4-72
-4-58,6-59
-14-68,14-68
-48-50,49-88
-51-82,45-49
-17-75,4-76
-31-78,78-78
-22-34,14-34
-2-96,1-92
-1-99,98-98
-41-65,64-73
-80-82,17-85
-23-97,22-59
-19-54,16-58
-85-97,47-86
-4-24,23-50
-12-91,90-90
-91-98,91-98
-10-63,9-9
-49-82,48-50
-22-80,23-99
-12-82,13-98
-1-60,2-47
-28-50,19-72
-44-61,44-44
-98-99,66-97
-37-37,37-83
-22-24,23-25
-65-71,65-70
-10-90,89-93
-10-42,42-66
-13-91,90-99
-38-62,48-62
-3-98,4-99
-26-68,27-68
-8-71,82-83
-5-49,50-70
-1-35,1-36
-20-78,79-79
-39-59,39-39
-61-79,61-80
-94-99,95-95
-51-82,83-90
-1-57,2-72
-10-19,11-42
-55-99,54-54
-24-90,89-94
-24-34,34-88
-98-99,45-97
-27-65,2-90
-6-73,5-73
-73-89,72-90
-81-83,78-82
-3-99,3-98
-96-99,52-95
-75-92,6-92
-58-58,12-57
-17-38,37-41
-75-75,5-75
-22-46,22-47
-89-97,2-98
-53-70,19-53
-25-90,89-93
-36-54,46-55
-1-98,97-97
-34-36,2-33
-32-55,31-85
-2-56,56-68
-1-59,1-58
-83-84,1-82
-3-67,4-66
-65-84,41-85
-7-73,16-73
-66-66,23-68
-42-83,42-76
-17-91,17-82
-29-78,29-36
-29-82,29-81
-17-55,54-55
-64-77,63-87
-85-85,45-84
-4-34,3-3
-16-51,52-73
-4-96,39-95
-1-94,31-94
-1-87,2-88
-11-24,12-25
-1-1,3-79
-26-64,13-17
-35-81,54-71
-1-44,1-43
-59-62,22-24
-14-77,8-14
-64-83,83-99
-64-87,87-89
-1-15,15-99
-43-57,48-48
-2-25,2-26
-39-78,39-79
-13-98,14-56
-5-33,75-93
-98-98,3-98
-11-72,10-72
-6-92,5-6
-4-57,4-56
-94-94,40-95
-55-85,55-84
-46-75,45-74
-35-94,34-94
-33-86,85-90
-85-96,42-86
-7-92,5-92
-11-33,10-33
-43-73,38-77
-22-96,1-99
-5-98,4-6
-79-83,78-81
-4-73,32-72
-14-20,20-52
-31-89,30-88
-18-74,9-75
-2-65,2-64
-17-32,33-41
-4-99,8-98
-96-97,77-96
-91-96,63-94
-23-71,52-54
-40-89,49-56
-10-89,10-90
-21-57,21-88
-32-91,33-57
-44-97,44-44
-5-65,4-86
-19-60,18-45
-30-79,80-80
-9-12,8-12
-60-60,59-59
-18-57,48-53
-32-71,72-85
-65-78,35-66
-27-44,41-44
-43-72,14-42
-28-97,28-99
-35-55,35-56
-27-50,1-51
-69-69,51-70
-65-66,5-25
-4-20,3-20
-30-91,31-91
-61-90,61-86
-38-74,98-98
-45-82,78-81
-64-64,5-65
-3-23,2-99
-26-45,2-26
-97-98,19-75
-76-76,5-77
-13-71,12-72
-17-53,52-99
-15-86,87-87
-57-98,23-29
-15-69,9-12
-8-99,18-91
-94-94,19-95
-1-93,93-96
-10-92,52-92
-47-54,70-85
-13-36,12-13
-7-96,15-47
-10-98,11-98
-79-94,89-95
-28-80,80-81
-36-72,37-56
-67-83,67-83
-91-91,80-90
-8-78,1-84
-16-41,40-42
-3-6,5-7
-12-96,8-12
-68-95,95-95
-88-89,16-92
-97-97,43-96
-20-35,34-92
-45-93,46-92
-8-19,9-32
-30-44,13-22
-5-50,6-50
-30-85,84-86
-11-58,57-74
-36-75,7-26
-6-86,3-6
-21-95,94-98
-10-94,14-93
-72-72,7-72
-50-65,51-97
-67-67,68-75
-97-98,10-94
-37-75,33-38
-4-89,4-98
-3-97,2-98
-3-50,47-68
-51-89,52-59
-50-85,84-85
-97-99,29-98
-95-97,35-96
-51-98,99-99
-4-99,75-75
-35-62,5-62
-22-56,21-56
-38-43,49-86
-5-38,5-15
-11-70,6-69
-63-86,28-86
-8-89,10-20
-14-94,4-97
-10-51,10-50
-3-40,4-41
-45-46,46-85
-61-97,62-96
-5-88,5-92
-29-92,91-96
-89-94,3-88
-3-71,2-72
-33-81,34-82
-48-57,47-84
-2-83,48-76
-24-67,24-66
-30-90,30-89
-82-82,58-83
-52-58,52-59
-23-80,8-80
-33-79,34-80
-22-70,23-70
-24-59,25-77
-1-50,8-61
-19-91,91-96
-6-6,7-85
-84-84,81-83
-25-41,16-41
-1-18,2-8
-40-86,78-83
-24-40,41-84
-92-96,3-93
-5-97,2-3
-59-95,94-98
-13-18,13-19
-1-68,5-65
-39-66,66-84
-12-56,8-9
-37-94,38-71
-27-74,27-75
-18-18,19-92
-14-29,14-81
-91-94,11-90
-61-77,3-62
-5-7,6-74
-24-67,23-66
-4-96,4-98
-40-94,41-93
-30-51,52-91
-3-35,1-35
-24-40,39-39
-91-91,76-90
-13-89,14-69
-6-95,7-96
-2-72,1-71
-71-72,72-94
-5-6,6-58
-14-26,28-77
-63-99,57-99
-32-88,4-88
-3-64,63-63
-62-86,85-87
-48-92,24-47
-69-74,62-80
-10-98,53-56
-22-87,1-22
-23-87,92-98
-30-76,31-76
-20-66,21-40
-23-87,87-91
-10-10,11-12
-36-74,75-94
-36-36,10-35
-20-73,14-81
-56-68,55-66
-8-98,7-61
-4-96,4-97
-13-90,1-90
-45-87,45-85
-66-68,24-67
-53-60,39-66
-98-99,2-97
-6-81,80-99
-4-98,4-97
-88-88,14-87
-20-57,21-38
-25-76,24-76
-8-8,10-61
-13-46,13-45
-71-98,70-97
-3-6,9-41
-18-41,40-40
-9-70,21-36
-33-83,11-33
-8-22,80-83
-5-37,6-36
-32-67,67-87
-26-48,25-47
-15-70,69-71
-11-94,15-93
-16-39,16-40
-81-85,81-85
-23-75,23-74
-55-79,55-79
-30-85,29-86
-7-79,78-78
-13-15,7-16
-82-82,29-81
-2-69,15-68
-63-91,52-63
-35-86,87-87
-17-96,18-96
-57-57,58-87
-46-54,46-53
-26-78,27-93
-12-81,12-82
-15-85,5-20
-28-88,36-88
-62-73,63-72
-42-43,17-43
-56-97,56-98
-20-65,17-66
-32-99,33-57
-14-96,15-95
-8-25,7-25
-56-60,56-59
-20-86,19-20
-19-97,20-96
-86-86,58-87
-60-70,59-72
-9-50,32-51
-8-10,14-62
-56-89,88-88
-46-93,92-97
-12-25,1-66
-11-16,18-95
-62-64,17-61
-78-89,43-78
-30-92,30-90
-68-86,69-71
-89-98,33-44
-9-20,8-20
-57-77,16-57
-12-86,11-53
-7-11,28-53
-13-92,14-82
-49-91,92-92
-60-86,60-99
-73-99,73-97
-34-67,54-63
-75-76,43-76
-9-95,94-96
-37-69,38-77
-76-77,45-77
-42-69,42-68
-2-35,2-14
-95-96,15-96
-1-97,2-98
-31-57,31-56
-34-37,33-68
-25-54,24-54
-19-43,9-59
-38-94,93-95
-38-73,38-73
-58-85,58-84
-64-98,58-63
-12-22,12-21
-13-13,14-82
-17-55,17-81
-90-97,88-96
-8-99,47-99
-2-60,35-60
-5-66,6-60
-78-78,4-79
-61-68,48-90
-23-94,93-97
-13-69,12-12
-17-74,1-74
-17-47,48-48
-56-71,70-72
-17-17,17-99
-11-98,12-63
-58-58,58-59
-64-64,65-94
-83-91,1-65
-31-79,78-80
-4-77,78-78
-53-80,3-52
-34-63,62-64
-97-98,1-98
-93-94,41-94
-49-79,50-80
-14-66,14-66
-53-89,45-53
-11-47,10-99
-60-65,61-85
-27-78,26-78
-18-92,19-98
-31-45,17-31
-6-42,5-61
-52-79,51-84
-82-86,83-92
-8-72,71-82
-7-39,6-6
-3-75,75-99
-22-22,22-55
-6-88,6-88
-3-78,34-71
-70-70,11-71
-88-90,52-89
-11-14,28-33
-61-71,50-60
-80-84,7-84
-5-97,98-99
-2-79,3-80
-8-94,8-94
-5-83,83-84
-41-41,10-40
-51-76,13-96
-47-97,48-98
-6-96,7-96
-40-47,41-51
-22-97,22-23
-3-62,3-61
-48-80,43-80
-86-88,8-87
-80-80,52-79
-30-43,29-44
-57-75,56-75
-4-85,3-77
-39-83,38-79
-2-50,1-51
-12-93,11-93
-4-81,3-21
-80-98,79-79
-44-52,51-53
-2-93,92-93
-15-86,2-15
-5-85,5-85
-36-73,36-72
-4-86,3-4
-7-27,8-28
-11-70,69-71
-36-60,37-60
-10-10,16-55
-87-92,88-94
-21-93,20-92
-16-16,15-92
-18-44,19-45
-24-24,24-79
-50-63,15-76
-64-68,65-66
-34-36,30-35
-83-85,2-84
-37-82,37-82
-17-69,17-80
-29-30,30-90
-9-95,9-94
-58-86,58-58
-96-99,17-96
-4-52,12-64
-7-99,8-99
-7-75,7-75
-2-52,26-75
-92-92,9-93
-2-64,3-70
-2-6,5-69
-19-86,9-19
-76-76,7-76
-4-99,1-99
-44-74,2-43
-20-97,79-96
-31-75,31-74
-13-97,13-96
-76-90,90-94
-3-63,4-94
-16-17,17-98
-2-84,84-98
-6-90,5-89
-23-25,24-24
-56-78,78-80
-8-63,7-29
-23-29,23-29
-26-94,25-95
-51-70,51-51
-9-57,14-57
-26-31,25-28
-59-96,59-94
-3-54,1-1
-57-69,31-57
-6-97,5-97
-2-88,55-82
-74-99,73-77
-36-44,36-43
-15-15,2-26
-3-59,4-69
-25-79,26-81
-97-99,59-98
-10-89,74-89
-56-93,92-93
-73-75,18-74
-89-89,12-88
-30-91,31-94
-16-24,15-92
-52-93,51-93
-42-93,41-98
-73-97,21-99
-12-88,87-94
-10-14,10-15
-83-95,53-82
-72-90,68-72
-52-66,14-81
-70-72,11-71
-43-43,13-42
-2-46,2-45
-46-94,76-89
-27-67,9-67
-9-89,28-89
-2-92,92-92
-5-85,86-99
-38-86,12-38
-4-98,3-98
-1-82,6-82
-24-30,24-29
-28-93,27-68
-39-76,5-38
-6-19,5-86
-12-14,13-17
-86-87,29-86
-12-91,12-91
-3-99,3-99
-7-84,6-65
-30-45,31-90
-11-14,21-57
-8-62,61-62
-20-92,20-91
-8-89,8-89
-18-36,6-14
-18-45,17-45
-66-66,5-65
-95-96,11-96
-1-3,4-74
-12-94,94-98
-25-58,25-57
-15-70,15-69
-6-82,1-6
-4-5,5-12
-28-60,59-64
-2-92,92-98
-61-85,86-94
-48-97,39-97
-51-53,42-73
-7-94,93-94
-19-49,15-68
-14-56,3-56
-21-85,20-84
-18-19,19-63
-2-98,3-99
-86-94,73-99
-62-64,4-63
-18-86,19-86
-24-56,25-96
-93-99,16-93
-37-96,36-50
-16-91,15-53
-27-32,28-34
-16-71,15-16
-55-57,56-70
-82-93,70-83
-24-66,24-83
-1-96,2-95
-8-18,9-28
-1-59,1-60
-26-57,11-26
-45-50,46-48
-7-90,8-41
-56-92,57-93
-8-91,8-91
-1-63,6-12
-48-96,96-99
-26-99,26-97
-51-51,52-68
-47-50,6-46
-3-64,13-40
-5-75,3-3
-66-66,9-65
-92-92,7-91
--- a/05/05.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-const input = "05/input.txt";
-
-mutable struct Crates
-    stacks::Vector{Vector{Char}}
-end
-
-using ParserCombinator
-
-crate = (
-    (
-        (E"[" + p"[A-Z]" + E"]") |> s -> s[1][1])
-    | (E"   " |> _ -> nothing)) + (E" " | Eos())
-crate_row = Repeat(crate) + Eos()
-
-crate_base = Repeat(P"\s*"+ p"\d" + P"\s*", 1, 100) + Eos()
-
-function parse_stacks(lines::Vector{String})::Crates
-    stacks = nothing
-    # start is the line on which instructions start.
-    start = 3
-    for l in lines
-        try
-            cs = parse_one(chomp(l), crate_row);
-            if isnothing(stacks)
-                stacks = Crates([Vector{Char}() for i in 1:length(cs)])
-            end
-            for (i, e) in enumerate(cs)
-                # inefficient but saves reversing
-                if !isnothing(e)
-                    pushfirst!(stacks.stacks[i], e);
-                end
-            end
-            start += 1
-        catch e
-            @assert typeof(e) == ParserException
-            break
-        end
-    end
-    println(stacks)
-    stacks
-end
-
-struct Instr
-    n::Int
-    from::Int
-    to::Int
-end
-
-instruction = E"move " + PInt() + E" from " + PInt() + E" to " + PInt() + Eos()
-
-function parse_instructions(lines::Vector{String})::Vector{Instr}
-    v = Vector{Instr}();
-    for l in lines
-        try
-            i = parse_one(chomp(l), instruction);
-            push!(v, Instr(i[1], i[2], i[3]));
-        catch e
-            @assert typeof(e) == ParserException
-        end
-    end
-    @show v
-    v
-end
-
-function act(init::Crates, instr::Vector{Instr}; newcrane=false)::Crates
-    for i in instr
-        @assert length(init.stacks[i.from]) >= i.n
-        if newcrane
-            push!(init.stacks[i.to], init.stacks[i.from][end-i.n+1:end]...);
-            init.stacks[i.from] = init.stacks[i.from][begin:end-i.n];
-        else
-            for j in 1:i.n
-                push!(init.stacks[i.to], pop!(init.stacks[i.from]));
-            end
-        end
-    end
-    init
-end
-
-function endresult1(c::Crates)::String
-    String([s[end] for s in c.stacks])
-end
-
-function run_05(f::String)
-    open(f; read=true) do fh
-        ls = collect(eachline(fh));
-        crates = parse_stacks(ls);
-        instrs = parse_instructions(ls);
-        crates2 = act(crates, instrs);
-        println(endresult1(crates2));
-        
-        crates3 = parse_stacks(ls);
-        crates3 = act(crates3, instrs; newcrane=true);
-        println(endresult1(crates3));
-    end
-end
-
-run_05(input);
--- a/05/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-    [G]         [P]         [M]    
-    [V]     [M] [W] [S]     [Q]    
-    [N]     [N] [G] [H]     [T] [F]
-    [J]     [W] [V] [Q] [W] [F] [P]
-[C] [H]     [T] [T] [G] [B] [Z] [B]
-[S] [W] [S] [L] [F] [B] [P] [C] [H]
-[G] [M] [Q] [S] [Z] [T] [J] [D] [S]
-[B] [T] [M] [B] [J] [C] [T] [G] [N]
- 1   2   3   4   5   6   7   8   9 
-
-move 2 from 4 to 2
-move 6 from 9 to 7
-move 4 from 7 to 2
-move 2 from 4 to 1
-move 2 from 6 to 7
-move 1 from 3 to 8
-move 4 from 7 to 1
-move 2 from 3 to 2
-move 3 from 8 to 5
-move 3 from 1 to 4
-move 12 from 2 to 5
-move 2 from 6 to 8
-move 12 from 5 to 8
-move 3 from 7 to 9
-move 18 from 8 to 9
-move 2 from 8 to 6
-move 3 from 2 to 3
-move 14 from 9 to 4
-move 1 from 1 to 3
-move 7 from 9 to 3
-move 1 from 2 to 1
-move 8 from 4 to 5
-move 5 from 6 to 3
-move 2 from 7 to 9
-move 3 from 4 to 9
-move 4 from 9 to 6
-move 4 from 6 to 1
-move 8 from 4 to 6
-move 10 from 1 to 2
-move 13 from 3 to 2
-move 17 from 5 to 9
-move 2 from 5 to 1
-move 9 from 9 to 7
-move 1 from 3 to 6
-move 2 from 1 to 8
-move 11 from 2 to 4
-move 5 from 6 to 8
-move 1 from 6 to 3
-move 1 from 1 to 4
-move 3 from 8 to 6
-move 3 from 2 to 8
-move 9 from 7 to 9
-move 4 from 4 to 7
-move 1 from 9 to 5
-move 15 from 9 to 7
-move 7 from 8 to 3
-move 1 from 5 to 6
-move 2 from 6 to 9
-move 8 from 2 to 6
-move 3 from 4 to 3
-move 1 from 2 to 5
-move 4 from 9 to 3
-move 1 from 3 to 4
-move 13 from 6 to 2
-move 1 from 5 to 1
-move 4 from 4 to 9
-move 6 from 3 to 2
-move 11 from 2 to 7
-move 6 from 3 to 4
-move 3 from 3 to 2
-move 1 from 3 to 4
-move 1 from 1 to 3
-move 3 from 9 to 2
-move 1 from 3 to 1
-move 4 from 7 to 1
-move 1 from 9 to 5
-move 5 from 1 to 4
-move 11 from 2 to 4
-move 1 from 5 to 3
-move 1 from 2 to 3
-move 12 from 4 to 2
-move 2 from 7 to 2
-move 7 from 4 to 3
-move 5 from 4 to 1
-move 7 from 7 to 6
-move 4 from 1 to 8
-move 1 from 8 to 5
-move 8 from 3 to 2
-move 4 from 7 to 4
-move 13 from 7 to 1
-move 2 from 8 to 6
-move 5 from 4 to 9
-move 1 from 3 to 6
-move 1 from 5 to 8
-move 1 from 2 to 9
-move 4 from 2 to 6
-move 2 from 8 to 6
-move 10 from 1 to 3
-move 4 from 9 to 4
-move 2 from 1 to 3
-move 5 from 2 to 9
-move 4 from 9 to 2
-move 1 from 1 to 2
-move 13 from 2 to 4
-move 15 from 4 to 5
-move 3 from 6 to 8
-move 8 from 3 to 8
-move 1 from 4 to 2
-move 14 from 5 to 1
-move 1 from 5 to 4
-move 1 from 4 to 2
-move 8 from 6 to 7
-move 3 from 6 to 2
-move 2 from 9 to 1
-move 8 from 8 to 7
-move 9 from 1 to 5
-move 7 from 5 to 3
-move 14 from 7 to 9
-move 2 from 2 to 3
-move 7 from 2 to 1
-move 1 from 6 to 1
-move 4 from 9 to 2
-move 8 from 3 to 6
-move 2 from 4 to 3
-move 4 from 3 to 5
-move 5 from 5 to 7
-move 2 from 6 to 9
-move 6 from 6 to 2
-move 4 from 2 to 3
-move 1 from 6 to 2
-move 2 from 7 to 8
-move 13 from 9 to 5
-move 2 from 7 to 1
-move 14 from 1 to 5
-move 15 from 5 to 7
-move 3 from 8 to 7
-move 5 from 3 to 5
-move 6 from 5 to 7
-move 4 from 1 to 7
-move 1 from 2 to 5
-move 3 from 2 to 8
-move 11 from 5 to 2
-move 10 from 7 to 1
-move 1 from 3 to 4
-move 10 from 2 to 9
-move 1 from 5 to 8
-move 6 from 7 to 3
-move 1 from 4 to 6
-move 2 from 3 to 8
-move 1 from 2 to 1
-move 4 from 3 to 9
-move 3 from 1 to 6
-move 2 from 7 to 1
-move 1 from 5 to 6
-move 1 from 3 to 8
-move 4 from 1 to 4
-move 5 from 2 to 9
-move 3 from 1 to 4
-move 18 from 9 to 7
-move 4 from 8 to 4
-move 3 from 1 to 2
-move 1 from 9 to 7
-move 1 from 4 to 7
-move 1 from 6 to 2
-move 1 from 2 to 5
-move 25 from 7 to 3
-move 7 from 4 to 2
-move 8 from 7 to 9
-move 4 from 8 to 6
-move 1 from 8 to 5
-move 4 from 6 to 5
-move 2 from 9 to 5
-move 3 from 5 to 8
-move 4 from 6 to 4
-move 12 from 3 to 5
-move 11 from 3 to 2
-move 13 from 5 to 8
-move 4 from 9 to 6
-move 7 from 4 to 9
-move 2 from 6 to 2
-move 12 from 2 to 7
-move 1 from 6 to 3
-move 1 from 5 to 6
-move 2 from 5 to 3
-move 15 from 8 to 6
-move 4 from 6 to 7
-move 1 from 5 to 1
-move 10 from 2 to 8
-move 8 from 8 to 3
-move 8 from 6 to 8
-move 2 from 7 to 6
-move 9 from 9 to 7
-move 8 from 8 to 9
-move 1 from 1 to 3
-move 1 from 2 to 7
-move 7 from 3 to 1
-move 3 from 8 to 5
-move 3 from 1 to 6
-move 7 from 9 to 2
-move 2 from 3 to 7
-move 5 from 7 to 9
-move 17 from 7 to 5
-move 2 from 7 to 6
-move 10 from 6 to 3
-move 1 from 1 to 3
-move 6 from 9 to 3
-move 1 from 2 to 9
-move 2 from 7 to 9
-move 2 from 9 to 7
-move 1 from 5 to 8
-move 1 from 8 to 5
-move 6 from 2 to 5
-move 1 from 6 to 1
-move 5 from 3 to 5
-move 1 from 6 to 8
-move 1 from 7 to 9
-move 2 from 9 to 3
-move 15 from 5 to 2
-move 2 from 1 to 8
-move 2 from 3 to 7
-move 2 from 8 to 3
-move 3 from 5 to 9
-move 1 from 8 to 6
-move 1 from 9 to 6
-move 3 from 7 to 6
-move 17 from 3 to 4
-move 1 from 1 to 2
-move 6 from 2 to 9
-move 16 from 4 to 1
-move 4 from 6 to 8
-move 9 from 5 to 6
-move 8 from 6 to 2
-move 2 from 9 to 5
-move 2 from 3 to 5
-move 1 from 6 to 2
-move 1 from 4 to 8
-move 14 from 1 to 3
-move 8 from 5 to 3
-move 20 from 3 to 1
-move 1 from 8 to 2
-move 1 from 9 to 6
-move 1 from 6 to 7
-move 1 from 7 to 3
-move 22 from 1 to 2
-move 3 from 3 to 6
-move 27 from 2 to 8
-move 2 from 2 to 8
-move 2 from 6 to 9
-move 2 from 9 to 4
-move 2 from 4 to 8
-move 1 from 1 to 3
-move 14 from 8 to 5
-move 1 from 3 to 9
-move 3 from 9 to 2
-move 5 from 2 to 8
-move 10 from 2 to 9
-move 1 from 6 to 7
-move 1 from 7 to 5
-move 7 from 5 to 2
-move 2 from 9 to 2
-move 1 from 6 to 2
-move 2 from 9 to 5
-move 3 from 5 to 6
-move 6 from 5 to 3
-move 1 from 5 to 6
-move 4 from 3 to 9
-move 2 from 9 to 8
-move 3 from 9 to 5
-move 23 from 8 to 1
-move 2 from 6 to 1
-move 1 from 5 to 7
-move 2 from 3 to 5
-move 2 from 9 to 5
-move 4 from 9 to 7
-move 2 from 9 to 4
-move 1 from 5 to 4
-move 5 from 8 to 5
-move 2 from 6 to 2
-move 3 from 7 to 3
-move 1 from 3 to 4
-move 3 from 2 to 8
-move 4 from 1 to 6
-move 2 from 6 to 3
-move 4 from 1 to 2
-move 3 from 8 to 1
-move 13 from 2 to 5
-move 4 from 3 to 2
-move 14 from 5 to 7
-move 5 from 2 to 7
-move 18 from 7 to 9
-move 4 from 4 to 7
-move 2 from 5 to 4
-move 17 from 9 to 5
-move 1 from 9 to 1
-move 1 from 7 to 2
-move 5 from 7 to 2
-move 18 from 1 to 4
-move 1 from 7 to 3
-move 1 from 3 to 6
-move 2 from 1 to 3
-move 1 from 6 to 5
-move 2 from 6 to 8
-move 1 from 8 to 9
-move 1 from 8 to 3
-move 13 from 4 to 5
-move 1 from 1 to 6
-move 3 from 2 to 4
-move 1 from 6 to 1
-move 3 from 2 to 9
-move 3 from 3 to 1
-move 5 from 4 to 5
-move 30 from 5 to 3
-move 1 from 4 to 6
-move 1 from 9 to 8
-move 1 from 9 to 6
-move 21 from 3 to 7
-move 3 from 1 to 6
-move 1 from 1 to 4
-move 1 from 9 to 6
-move 1 from 8 to 2
-move 1 from 3 to 6
-move 1 from 9 to 3
-move 5 from 4 to 8
-move 1 from 2 to 4
-move 9 from 5 to 7
-move 2 from 5 to 9
-move 2 from 8 to 2
-move 2 from 6 to 3
-move 1 from 4 to 1
-move 4 from 3 to 8
-move 2 from 9 to 2
-move 4 from 2 to 6
-move 1 from 1 to 4
-move 2 from 6 to 9
-move 2 from 5 to 4
-move 1 from 3 to 1
-move 1 from 1 to 3
-move 2 from 9 to 1
-move 5 from 3 to 5
-move 1 from 1 to 8
-move 4 from 6 to 4
-move 5 from 5 to 6
-move 18 from 7 to 5
-move 1 from 3 to 4
-move 12 from 7 to 5
-move 15 from 5 to 6
-move 1 from 5 to 8
-move 1 from 3 to 7
-move 1 from 1 to 2
-move 1 from 2 to 4
-move 1 from 7 to 9
-move 2 from 8 to 2
-move 1 from 2 to 4
-move 4 from 4 to 2
-move 1 from 2 to 1
-move 1 from 9 to 8
-move 4 from 6 to 4
-move 3 from 2 to 6
-move 1 from 2 to 6
-move 8 from 4 to 3
-move 1 from 1 to 3
-move 6 from 6 to 1
-move 1 from 3 to 6
-move 5 from 1 to 7
-move 10 from 5 to 9
-move 3 from 9 to 8
-move 7 from 6 to 2
-move 1 from 7 to 8
-move 3 from 5 to 8
-move 3 from 6 to 2
-move 6 from 8 to 9
-move 1 from 5 to 3
-move 2 from 3 to 1
-move 2 from 4 to 8
-move 6 from 6 to 9
-move 1 from 1 to 4
-move 17 from 9 to 2
-move 1 from 4 to 1
-move 2 from 7 to 8
-move 1 from 9 to 8
-move 3 from 8 to 4
-move 3 from 1 to 4
-move 9 from 8 to 2
-move 1 from 8 to 4
-move 12 from 2 to 7
-move 4 from 7 to 4
-move 1 from 8 to 1
-move 10 from 4 to 2
-move 3 from 3 to 2
-move 1 from 9 to 7
-move 11 from 7 to 3
-move 1 from 3 to 1
-move 2 from 3 to 9
-move 1 from 3 to 7
-move 2 from 1 to 9
-move 1 from 6 to 5
-move 7 from 3 to 6
-move 1 from 7 to 3
-move 3 from 3 to 4
-move 1 from 5 to 7
-move 2 from 4 to 3
-move 2 from 4 to 8
-move 1 from 7 to 6
-move 2 from 6 to 8
-move 1 from 9 to 2
-move 1 from 9 to 5
-move 1 from 5 to 1
-move 1 from 8 to 6
-move 1 from 3 to 2
-move 4 from 6 to 1
-move 5 from 1 to 4
-move 11 from 2 to 4
-move 2 from 8 to 2
-move 1 from 8 to 9
-move 27 from 2 to 5
-move 4 from 6 to 3
-move 3 from 2 to 4
-move 2 from 5 to 9
-move 1 from 5 to 7
-move 2 from 9 to 5
-move 14 from 4 to 7
-move 2 from 4 to 7
-move 3 from 4 to 8
-move 4 from 3 to 1
-move 4 from 1 to 8
-move 2 from 3 to 9
-move 2 from 9 to 3
-move 7 from 8 to 9
-move 1 from 3 to 8
-move 2 from 3 to 2
-move 25 from 5 to 9
-move 1 from 5 to 8
-move 1 from 8 to 7
-move 26 from 9 to 1
-move 23 from 1 to 5
-move 7 from 9 to 7
-move 1 from 9 to 8
-move 1 from 9 to 2
-move 5 from 7 to 1
-move 20 from 5 to 6
-move 1 from 7 to 6
-move 2 from 5 to 3
-move 1 from 8 to 6
-move 21 from 6 to 8
-move 1 from 6 to 4
-move 1 from 1 to 7
-move 2 from 1 to 6
-move 1 from 1 to 3
-move 1 from 2 to 5
-move 1 from 2 to 6
-move 2 from 7 to 6
-move 6 from 7 to 9
-move 3 from 1 to 2
-move 17 from 8 to 1
-move 1 from 4 to 1
-move 2 from 6 to 9
-move 3 from 8 to 9
-move 2 from 3 to 7
-move 2 from 9 to 8
-move 4 from 7 to 3
-move 4 from 3 to 4
-move 2 from 5 to 8
-move 4 from 8 to 4
-move 3 from 6 to 8
-move 18 from 1 to 5
-move 1 from 3 to 4
-move 3 from 2 to 4
-move 5 from 9 to 1
-move 10 from 7 to 5
-move 5 from 1 to 3
-move 5 from 3 to 5
-move 5 from 4 to 3
-move 2 from 4 to 2
-move 5 from 8 to 3
-move 25 from 5 to 2
-move 3 from 3 to 6
-move 1 from 1 to 3
-move 3 from 6 to 7
-move 1 from 4 to 2
-move 1 from 5 to 8
-move 2 from 4 to 9
-move 1 from 8 to 1
-move 20 from 2 to 7
-move 10 from 7 to 1
-move 1 from 1 to 7
-move 4 from 7 to 8
-move 5 from 5 to 4
-move 4 from 8 to 6
-move 1 from 1 to 3
-move 5 from 7 to 4
-move 2 from 1 to 5
-move 4 from 9 to 1
-move 3 from 2 to 5
-move 5 from 5 to 1
-move 1 from 9 to 1
-move 11 from 1 to 3
-move 1 from 6 to 2
-move 7 from 3 to 5
-move 11 from 3 to 7
-move 1 from 2 to 6
-move 7 from 7 to 8
-move 1 from 9 to 1
-move 2 from 3 to 1
-move 1 from 5 to 3
-move 4 from 1 to 6
-move 4 from 6 to 3
-move 9 from 4 to 5
-move 2 from 8 to 2
-move 4 from 6 to 9
-move 3 from 2 to 4
-move 1 from 8 to 6
--- a/06/06.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-
-const input::String = "sbpbwwrlwrwggscsfcsshsvhshphttzctztfflddvbvcbcvbcbnbrrstsspsvpvllncccqssqdssnsmshmshhtssbzzlplffzppddmhhwnhntnjtnjtnnqggjdgjdjrjffsdfsfbsffhtthwwfssqpspllcvcdvvfvfzfbzzgpglpgpmppfsfdfbfvvfjfsjjvqqbvqbvqbvvlvglvglvljvjzvvqcvqcqjcqqpddqbqcqrqmmvnvbnnfqnncznccqjcqqjzzwlltrrmmlwlllbjlblzlddfdmmscmsspfssqggbsbsjjdqdqgqgqbqdqrqlrrltttghthrtrwrdrnrfnfvftvtsvtvwtvwttvqtvtccqtqmqggwhhhlzhhrwwbwqwbbfrrmddwhdwdnwdwbdwwsswtwnnvvdggbbtwbbwllgffqpffpgpgmpmmjqqmpmffjgfgrffdzzspzptzzdszszbsbsbsvsbbhsbsbddnhhrqqcwwblbwlwnnthtsshmshmhgmgqgjqqpccfvcvbbbnllgmlgmmbnmnlmlzlffrrrgssmcmddnpdndtntrrqdqldldbbtppvddgndnwwctwccpbpffngnsgshggphggtssgngtnthtllzflzflzfzrfftgtstppghgnnpggrdgdnnswwccljlflwwgzgcgrrhssbwbllblnlvlddsffgrrnbbmsmmmhjmjvmjvmjmqqpdqppltlflmfmssqcqsqvsvsggpglplslggqtggmsmmmgffrccrvvsdvdvfddprdprrwjrjcjjmlmrmqmggqgdqdwdsdwwwgfwfddrcdcvcmmjbbmrrhlrrwcwvcclttwbwttgffnmnjmjdmmmlqmqrrlblplccdbcbwcbcpphpqpqlqrllqwwjsjgjbjqbbmcmzmrrqtrqqmcmmnjmjbbtnnbbjdjzzvbzvzjzdjzjrzzfzfbbmnmdnnzppmbpbhbdbvvqnqqnqrnrzrhhrddbqdqpqqwgwlglplglslhhpjpdjdjgddnppmvppjddczccgsccdsccbcvczccnbnmmsnsmmrwmwbmbbcpbbwbppzggdnnnzmnzzvrvcrvcvcrvrnrzzqzmzttjhhnffqggnqqwzwfzfwzwfwcwnccwgcwgcgqcgqcggzgwgfwgfffjttjddwswqqnttqwqsqhhcmchcscbbnwnlwlrlppqnnwjnjtntrtdtbbmzzrmzrzvrzvrzzwqwqllccnffvmmfmvmzzfttnnzttrbttdvvhdhzhzhvzzfsfszsvsttrqqdlldflfjjnqjjbhhqhzhcchppzsznntdntdddqqwjqjqmmgnnhrhjhnjnznwwdpplzzfzztbzzbmzmbbgjgtjtqjqpqhqgqhhtztpzpmzmjmhhjwwjsspbssvdsvsgvssghgvglgtltgllmhmtmhttfgglwgllpvpgpspzzhnnzcnzzldzdmzmlzzwtwhhlfhhvthhjdjsdsmddgzzsjjnznjnmjjgdgtdtzdtdvtddzwzgwwqvqccwrrrvddbtdbbshbhssnvsnvssswcwjcjlltvvltvvdsdqdsswlwttzfzhzjjgjsgjgttbccsvcscllbfbzzwwwznwwtzwzjzwjjgqjqrjrdjrddzsznsznzpzszhzzspzzbzrzhhsbspsqpqqqpddhdcdldttlccjrjsrsfftfdfrrtntpnpsnnwjnwnznpzzlqqlmqlmmcddlqqzssglsglssprmnvltqhslvqmvszjtvtwqjcdngjmftnhwvjdvtwwhtnsdmvjdspnhnlmjgnmwlspcvpdmlsrnbbzlmwwrslssmcbggmfvgzsnpnlnzdqsbhcfjdccrspnzfmhbvwstvccvqqjlwhpnlrrwszjnrtdfzwrwlzwvdvbzbvltdpfwrjlslmrctwvbbvdrctgtgwtwpjjghhvdsqhplfrsjqlgsrbfgwdjlzdpdljtvjmpwqqbghndqnvjhngtpnpvzfbtchncwdqjhmzjlpdggbdcqrfjlwvczvpspljqmpgtrsvwwhqncfvfrwbnvsfjqlsjdlrqzmlqjgcpghhgzfhjcglllnhtmchrrptbzhqnfntgqbfstrvpsqsvqvcvpgjnchbvmgtgzqfrqcjrvldzghdfrvllrtfcwnsmmgdrcbjmdqgbfwmpwhfjmnbqrbvqvnmjlqtsjqvhzpdsgbjpjngmzbgnznvjqprfvwzjrfrwfdqrtlcgqqlvrzwmqwjbdvprvpwvdcrfdrcttnmnvjfrsrrmjgfjdmpdpnfsrwnprtdpvdmdwssvjrqtlcvpgrqgqqqffvvssbmghzjrzrzlcrnfjtdbvwsjzfvcrsmgqbcrdrjwdwbltffwbgjwtgtdblmlhvhlcpgdmpcztmpmgjghqpwzwtpnmnmgnqqrrtwczgmgtdbgdqtpnlbnzhshsfzsmrztffrmlsgqcprbjpqwjlqgwvctpmpshgzbzsjgqhzvsrjfwplvjbvltrlfldvsmlppcmsfrbbctggmqmjnhppstzrcfjtdgfwrrnmlvjphwtlqtjqcntjtzvgjtwvthjfbgpwhlrzdqncmggvgthmgjvrbnzbndsldnlcgtcqbqdnnbnqhvtpfnrclttfwcpnqscjbzdvbqrrsbzpdfhjllbjwsltjpmdnbrrzvhvzzqnlbglsjrnjbqffnnzmldfvtvmldfsztrnpcjgblsdhzfzmfqzlfrtslglhfvszppptjnjqcdmjcwqmfzhnqbfhslwhvtjfvcftzsphvghvtjjswpwghnfngmzddbwwqddsphvhcrwtthsjfswfqbvdsqghmrspdldfqmchnnrcdvjsclcnlsncsplchvzrwqbtvvqlqspftrwmjcbgpzbsmnfccbzgnhqsfjgmmsqsscdscfjbrmmtjbsphhlrlsgbllrptqrcgnqchzfddjwlldsbpcnzfbspfpchclqfbbtjpmtmtjthcdvwhrtqbgmgldcgcnmmhtbnqpzzcwlrscbzcqjzgztwjrnbmsnqtcllznlctzrntftspmnvhtfwbljnmrwsstvbmwclqrfpmwvjphrwddzdwtlfcvzlvqdmzhnvslfnfjhvdndlgbvvzbztpwvqzbzsbtqpqfmgqfgpzctfrqfjwmsnmlfqbgrlmncntcbshjhdcbqnvznhtcgcmmhnsbwpzbvtqbntwgflhjgmvvfhdbwfqmnfjlzdvvnpmvjrdfdnrhpbtllhbtbswwvrbwjgnqpbgnfrjtvbczbpmrcbwdlhztzssnwshjmmcqchptrtchrqncdgdtmwrlnmmwqlzqswwwvpngvwcphgnzrhpprjnbldscvwlqdjwnhjrnscdwlnhnsbwgzjtgvzdgqcjcgvrdhntszhdnjsbbrfphlmdlldjdslbjnnsfbmcnvtlczmtnhrwblnbrdptcpmsbwqptgmwzsqnmmchwnnrvrlfsrglfzzqbnzmpdtnhhbmfqvsrsdsctvhqwfgbtvhbbrsrqmrvvplrnbfnbdmrvzpgctdtglndhcqnllvvcppgfbwjrpqcbghlqdbmpzwrqpmvwddqgthlmzmdsvzdfsmgzltbsvphctzgjsmqvgjlsbgnvmgprbcsfhgrtbwtnnrsqcwfzrhlgjcwcfrjhffrvrvtnpczvwvjnnhfdgcppnnjjpttptcbmdqvgdbhdmlqgcqsrnbcrbtcgzbvgmhbnwzsgnwzbhdqqmvtpssvlvsttgnmcclqnjcgjnvtdggrcwsgbpjljgzgtllsnfvfshtbbpwrjhzvzswlfdvhbpngvgddcmhbzqcvnjhfsqpnvvsdvdtmqlqpzcgsnwlflnqprbqnwdqchjvsptbtrvtzvhrmrvznfpzmcsgnqtdvghhzwrrwvqwrztvdbjjtfchpftdcbthpfdczwchpptwzdpswvbhppdphgvpfzhprpqtnprgfmdnqrbrdlclcmhrdfrcdhwpcqhnbwmhrrgnctpvsqmphcwwvlmslszhdz";
-
-function find_marker(s::String; n=4)::Int
-    i = n;
-    L = length(s)::Int;
-    while i <= L
-        dup = false;
-        for Ref = i:-1:(i-(n-2))
-            for Cmp = (Ref-1):-1:(i-(n-1))
-                if s[Ref] == s[Cmp]
-                    i += Cmp - (i-n);
-                    dup = true;
-                    break;  # To do: optimize
-                end
-            end
-        end
-        if !dup
-            return i;
-        end
-    end
-    return -1;
-end
-
-println(find_marker(input; n=4));
-println(find_marker(input; n=14));
--- a/07/07.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-const input::String = "07/input.txt"
-
-import Base: push!
-using ParserCombinator
-
-abstract type Entry end
-
-struct File <: Entry
-    name::String
-    size::Int
-end
-
-struct Dir <: Entry
-    name::String
-    children::Vector{Entry}
-end
-
-function filename(f::File)::String
-    f.name
-end
-
-function filesize(f::File)::Int
-    f.size
-end
-
-function filename(f::Dir)::String
-    f.name
-end
-function filesize(d::Dir)::Int
-    sum(filesize(f) for f in d.children)
-end
-
-function push!(d::Dir, e::Entry)
-    # Avoid duplication of entries
-    if !isnothing(findnext((==)(e), d.children, 1))
-        return;
-    end
-    push!(d.children, e::Entry);
-end
-
-function cd(d::Dir, s::String)::Entry
-    d.children[findnext(e -> filename(e) == s, d.children, 1)]
-end
-
-function count_dirs_belowsize(root::Dir; maxsize=100000)::Int
-    sizes = [filesize(e) for e in root.children];
-    mysize = sum(sizes; init=0);
-    subsizes = [count_dirs_belowsize(r) for r in root.children if isa(r, Dir)];
-    (mysize <= maxsize ? mysize : 0) + sum(subsizes; init=0)
-end
-
-# Parsing types
-
-abstract type TerminalLine end
-
-struct Cd <: TerminalLine
-    dir::String
-end
-
-struct Ls <: TerminalLine
-    contents::Vector{Entry}
-end
-
-# Parsers
-
-ParseFilename() = p"[a-z/\.]+" |> (x -> string(x[1]))
-ParseCd() = (E"cd " + ParseFilename()) |> (x -> Cd(x[1]))
-ParseLs() = (E"ls" + Eos()) |> (_ -> Ls([]))
-
-ParseCommandLine() = E"$ " + (ParseCd() | ParseLs()) + Eos()
-
-ParseLsEntry() = ((E"dir " + ParseFilename()) |> (d -> Dir(d[1], []))) | ((PInt() + E" " + ParseFilename()) |> (f -> File(f[2], f[1]))) + Eos()
-
-
-function build_filesystem(io::IO)::Entry
-    root = Dir("/", [])
-    current = root
-    path = []
-
-    pcl = ParseCommandLine()
-    ple = ParseLsEntry()
-
-    state = "shell";
-
-    for line in eachline(io)
-        parsed = false;
-        while !parsed
-            if state == "shell"
-                cmd = parse_one(line, pcl)[1]
-                parsed = true;
-                if isa(cmd, Cd)
-                    if (cmd::Cd).dir == "/"
-                        current = root;
-                        path = [];
-                    elseif (cmd::Cd).dir == ".."
-                        current = pop!(path);
-                    else
-                        push!(path, current);
-                        oc = current;
-                        current = cd(current, (cmd::Cd).dir);
-                    end
-                elseif isa(cmd, Ls)
-                    state = "ls";
-                else
-                    error("unknown type: ", line);
-                end
-            elseif state == "ls"
-                try
-                    e = parse_one(line, ple)[1]::Entry;
-                    push!(current, e);
-                    parsed = true;
-                catch exc
-                    state = "shell";
-                end
-            else
-                error("unknown state ", state);
-            end
-        end
-    end
-    root
-end
-
-function find_smallest_directory_larger_than(root::Entry, sz::Int)::Entry
-    best_dir = root;
-    best_difference = filesize(root) - sz;
-    for e in best_dir.children
-        if !isa(e, Dir)
-            continue;
-        end
-        fs = filesize(e);
-        if fs - sz >= 0 && fs - sz < best_difference
-            best_dir = e;
-            best_difference = fs - sz;
-        end
-
-        sub = find_smallest_directory_larger_than(e, sz);
-        fs = filesize(sub);
-        if fs - sz >= 0 && fs - sz < best_difference
-            best_dir = sub;
-            best_difference = fs - sz;
-        end
-    end
-    best_dir
-end
-
-function collect_all_dirs(root::Entry)::Vector{Entry}
-    queue = [root];
-    list = [root];
-    while length(queue) > 0
-        d = pop!(queue);
-        for e in d.children
-            if isa(e, Dir)
-                push!(queue, e)
-                push!(list, e);
-            end
-        end
-    end
-    list
-end
-
-open("07/input.txt"; read=true) do fh
-    root = build_filesystem(fh);
-    #println(root);
-    #println(count_dirs_belowsize(root));
-    #
-    total_size = filesize(root);
-    capacity = 70_000_000;
-    required_free = 30_000_000 - (capacity - total_size);
-    println("Using $total_size out of $capacity - need $required_free of additional free space");
-    sdlt = find_smallest_directory_larger_than(root, required_free);
-    println(sdlt.name, " ", filesize(sdlt));
-
-    # Serial algorithm:
-    by_filesize = [(d.name, filesize(d)) for d in collect_all_dirs(root)];
-    best = 1;
-    best_diff = by_filesize[1][2] - required_free;
-    for (i, (n, s)) in enumerate(by_filesize)
-        if (s-required_free) > 0 && (s-required_free) < best_diff
-            best = i;
-            best_diff = s - required_free;
-        end
-    end
-    println(by_filesize[best], " ", best_diff);
-end
--- a/07/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1013 +0,0 @@
-$ cd /
-$ ls
-dir jmtrrrp
-dir jssnn
-dir lbrmb
-11968 pcccp
-$ cd jmtrrrp
-$ ls
-77968 chq.jvb
-dir fmgsql
-$ cd fmgsql
-$ ls
-dir dbnsfp
-dir vvp
-$ cd dbnsfp
-$ ls
-51021 crlq.lrj
-186829 dhcrzvbr.wmn
-16232 fvhn.fqm
-54150 qpbqqj.rpg
-$ cd ..
-$ cd vvp
-$ ls
-179105 rrcsndz.tzp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd jssnn
-$ ls
-dir bphfqs
-dir dbnsfp
-dir pcccp
-dir snr
-dir zjbvwsnv
-$ cd bphfqs
-$ ls
-110077 dhcrzvbr.wmn
-$ cd ..
-$ cd dbnsfp
-$ ls
-dir hgvh
-dir jtqdcmsz
-154197 rrcsndz.tzp
-$ cd hgvh
-$ ls
-dir qjnbg
-$ cd qjnbg
-$ ls
-dir bqzfpr
-$ cd bqzfpr
-$ ls
-124394 wjsbsp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd jtqdcmsz
-$ ls
-275597 dbnsfp.fpg
-$ cd ..
-$ cd ..
-$ cd pcccp
-$ ls
-dir cnbd
-85621 cqzvwl
-dir dbnsfp
-114355 hbhp.cfv
-dir mcgq
-dir pcccp
-dir qpbqqj
-224038 rrcsndz.tzp
-dir zcsm
-27570 zjbvwsnv.fjt
-$ cd cnbd
-$ ls
-dir jrbz
-dir pphv
-$ cd jrbz
-$ ls
-dir dwvlwfq
-$ cd dwvlwfq
-$ ls
-32237 fwclr.rnb
-$ cd ..
-$ cd ..
-$ cd pphv
-$ ls
-180370 dhcrzvbr.wmn
-50154 dzvwdwl.gbt
-123965 mlsv.hlw
-163116 wnhtwr.mwl
-$ cd ..
-$ cd ..
-$ cd dbnsfp
-$ ls
-252181 btv.mpv
-dir hwncj
-dir pcccp
-$ cd hwncj
-$ ls
-51410 jbd.fcm
-$ cd ..
-$ cd pcccp
-$ ls
-258123 chq.jvb
-$ cd ..
-$ cd ..
-$ cd mcgq
-$ ls
-206506 qpbqqj.bbb
-$ cd ..
-$ cd pcccp
-$ ls
-193219 ddhtnql.hmb
-134114 hjbpzqzb.rwn
-108927 lznndn.nqd
-73241 ncdrv
-$ cd ..
-$ cd qpbqqj
-$ ls
-dir crdt
-dir tgchdnc
-$ cd crdt
-$ ls
-205710 chq.jvb
-$ cd ..
-$ cd tgchdnc
-$ ls
-dir bdw
-dir dpl
-dir jssnn
-dir pcccp
-dir plpzbm
-$ cd bdw
-$ ls
-211300 dbnsfp.tjm
-$ cd ..
-$ cd dpl
-$ ls
-287744 rsbjqwm
-$ cd ..
-$ cd jssnn
-$ ls
-dir jssnn
-$ cd jssnn
-$ ls
-9644 hmjhshg.vbv
-$ cd ..
-$ cd ..
-$ cd pcccp
-$ ls
-dir jssnn
-85888 pcccp.hdj
-dir qpbqqj
-dir rmscmwtv
-$ cd jssnn
-$ ls
-129698 crlq.lrj
-7499 dhcrzvbr.wmn
-283607 qpbqqj.djr
-234874 wqnrhll
-$ cd ..
-$ cd qpbqqj
-$ ls
-184229 qqpb.ftd
-$ cd ..
-$ cd rmscmwtv
-$ ls
-188048 dhcrzvbr.wmn
-dir jwtpgbnt
-$ cd jwtpgbnt
-$ ls
-209946 hgg
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd plpzbm
-$ ls
-32627 tlb.qmc
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd zcsm
-$ ls
-dir lczflft
-dir zjbvwsnv
-dir zmh
-$ cd lczflft
-$ ls
-40043 dzgnvlw.scr
-dir lrnb
-$ cd lrnb
-$ ls
-109881 bjpbs
-dir jssnn
-46901 npmw
-$ cd jssnn
-$ ls
-9216 sgrp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-214676 jssnn.hgn
-$ cd ..
-$ cd zmh
-$ ls
-dir jdt
-dir rggpltr
-$ cd jdt
-$ ls
-147387 jhhsv
-90052 jssnn.wns
-53105 qpbqqj.dzq
-$ cd ..
-$ cd rggpltr
-$ ls
-121454 dbnsfp.dzt
-dir gcc
-$ cd gcc
-$ ls
-dir zbqwl
-dir zjbvwsnv
-$ cd zbqwl
-$ ls
-260297 pcccp.jrw
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-248709 pcccp.tph
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd snr
-$ ls
-152569 chq.jvb
-1437 crlq.lrj
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-dir cqhb
-53235 ghhtl.bhv
-199640 npcfdw
-136346 qpbqqj.lmv
-dir zjbvwsnv
-$ cd cqhb
-$ ls
-24712 sqqf
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-dir gzqg
-dir hfbfvn
-dir srsphr
-dir vgvdcvc
-$ cd gzqg
-$ ls
-dir jjw
-$ cd jjw
-$ ls
-240052 zdcjjz.pmg
-$ cd ..
-$ cd ..
-$ cd hfbfvn
-$ ls
-278190 bfgndw.pvf
-$ cd ..
-$ cd srsphr
-$ ls
-42591 zjbvwsnv.hgh
-$ cd ..
-$ cd vgvdcvc
-$ ls
-120322 rrcsndz.tzp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd lbrmb
-$ ls
-dir bjhpdj
-42241 crlq.lrj
-dir dbnsfp
-244610 dhcrzvbr.wmn
-dir hppb
-dir mcnzs
-dir npntsr
-13625 tpjpcsgp.dlz
-219424 vvpbt.zvf
-dir zjbvwsnv
-191467 zjbvwsnv.htn
-$ cd bjhpdj
-$ ls
-dir bqjvst
-204722 dbnsfp
-dir dhltrqqq
-226082 dmdqcjp
-dir fcqwgzp
-dir jssnn
-6453 jssnn.ndh
-23799 jssnn.zqn
-dir nwglfhpl
-dir pcccp
-dir pdnj
-269246 shzqns.nws
-dir sjstqlcb
-dir zssln
-$ cd bqjvst
-$ ls
-202793 dbnsfp.pjj
-259783 jssnn
-dir rbvbhnvs
-30683 rvddnjmb.tlz
-dir tzhslnv
-$ cd rbvbhnvs
-$ ls
-86934 vrtrf.htt
-$ cd ..
-$ cd tzhslnv
-$ ls
-76278 mghcwdlr.tsc
-$ cd ..
-$ cd ..
-$ cd dhltrqqq
-$ ls
-dir mfd
-dir pcccp
-dir smmb
-251164 wsdnsgtt.lhr
-191876 zvr.bbz
-$ cd mfd
-$ ls
-51017 crlq.lrj
-99213 rjtbnnnq.hgd
-$ cd ..
-$ cd pcccp
-$ ls
-160487 dhcrzvbr.wmn
-dir nhdrnthj
-dir qpbqqj
-$ cd nhdrnthj
-$ ls
-181291 bbn.wtm
-186551 fnw.tnn
-23622 rrcsndz.tzp
-dir zjbvwsnv
-$ cd zjbvwsnv
-$ ls
-227547 dhcrzvbr.wmn
-$ cd ..
-$ cd ..
-$ cd qpbqqj
-$ ls
-212353 crlq.lrj
-170195 dhcrzvbr.wmn
-dir ttvp
-$ cd ttvp
-$ ls
-185994 tgjcfgjv
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd smmb
-$ ls
-dir dbnsfp
-85354 dbnsfp.zpn
-80665 dfmmjbm.rnr
-135989 dhcrzvbr.wmn
-93718 lrbzr.nfs
-dir mjpfnfns
-dir nsdpfnhb
-dir pmnssvd
-32270 qpbqqj.vtd
-$ cd dbnsfp
-$ ls
-31796 gzs.rgv
-64506 vbjncw.bpz
-181659 vjlfrdp.tqh
-$ cd ..
-$ cd mjpfnfns
-$ ls
-231611 chq.jvb
-17518 cmnlrzq.hvh
-144795 dbnsfp
-162194 jssnn.wjz
-29305 vdqnlw.fzf
-$ cd ..
-$ cd nsdpfnhb
-$ ls
-281844 chq.jvb
-$ cd ..
-$ cd pmnssvd
-$ ls
-165816 dfvl.czb
-144561 gbn
-150785 lnzdwrmb
-111214 rrcsndz.tzp
-164156 tzgdb.hht
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd fcqwgzp
-$ ls
-199161 dhcrzvbr.wmn
-34251 rrcsndz.tzp
-198345 vjlfrdp.tqh
-167001 zjbvwsnv.bsd
-$ cd ..
-$ cd jssnn
-$ ls
-dir ccblfvl
-103180 dhcrzvbr.wmn
-dir prw
-dir tzqfn
-dir zjbvwsnv
-166467 zjbvwsnv.tdt
-$ cd ccblfvl
-$ ls
-159752 crlq.lrj
-20805 jssnn.dvb
-243040 lct.zll
-27492 qbh
-27174 vjlfrdp.tqh
-dir zvfwq
-$ cd zvfwq
-$ ls
-135126 chq.jvb
-41664 gphw.vzd
-dir hmrdghbr
-dir jssnn
-dir qzzb
-dir tmdlcv
-$ cd hmrdghbr
-$ ls
-dir jvgpwrbs
-$ cd jvgpwrbs
-$ ls
-dir wzdv
-$ cd wzdv
-$ ls
-26834 qpbqqj.njf
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd jssnn
-$ ls
-90199 jqqmqddf.qnz
-$ cd ..
-$ cd qzzb
-$ ls
-dir mgpql
-dir src
-dir zvdgc
-$ cd mgpql
-$ ls
-141852 qpbqqj
-$ cd ..
-$ cd src
-$ ls
-204425 lqmcbndm.jrj
-75571 qsbrsv.jcm
-$ cd ..
-$ cd zvdgc
-$ ls
-268742 ffjmrmmz.lhg
-18385 rvmp.hjv
-$ cd ..
-$ cd ..
-$ cd tmdlcv
-$ ls
-182587 sfwvjrj.mzl
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd prw
-$ ls
-207429 dbnsfp.rqf
-dir ptgn
-dir pzgpqp
-252902 rbt
-169694 trg.rsh
-$ cd ptgn
-$ ls
-dir jssnn
-dir qpbqqj
-dir rpd
-$ cd jssnn
-$ ls
-189316 dbnsfp.bqc
-$ cd ..
-$ cd qpbqqj
-$ ls
-167937 zjbvwsnv.bhz
-$ cd ..
-$ cd rpd
-$ ls
-8775 crlq.lrj
-$ cd ..
-$ cd ..
-$ cd pzgpqp
-$ ls
-dir pcccp
-$ cd pcccp
-$ ls
-51496 pcccp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd tzqfn
-$ ls
-dir cbpfvdp
-285700 crlq.lrj
-7426 dbnsfp.fsd
-dir gdl
-141367 jssnn.hmw
-184482 sczphnp.vnc
-126288 vjlfrdp.tqh
-dir wndpdj
-$ cd cbpfvdp
-$ ls
-dir cvfr
-dir qpbqqj
-$ cd cvfr
-$ ls
-dir jfrnvts
-dir qpbqqj
-$ cd jfrnvts
-$ ls
-dir vwdn
-$ cd vwdn
-$ ls
-236936 vjlfrdp.tqh
-$ cd ..
-$ cd ..
-$ cd qpbqqj
-$ ls
-254275 bqd
-$ cd ..
-$ cd ..
-$ cd qpbqqj
-$ ls
-dir jssnn
-201960 qpbqqj
-$ cd jssnn
-$ ls
-131127 jssnn
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd gdl
-$ ls
-225146 hsgzmtp.wcs
-204436 jssnn.lhh
-64007 mjzjgfg.jsb
-$ cd ..
-$ cd wndpdj
-$ ls
-245412 bvcq
-211386 dbnsfp.tqd
-186962 fql.mww
-dir hlmhtfz
-117446 smvjvcn.lcp
-$ cd hlmhtfz
-$ ls
-150152 lrdhbq.rvm
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-179703 fvmbz
-87552 qtz.ccw
-129764 rrcsndz.tzp
-$ cd ..
-$ cd ..
-$ cd nwglfhpl
-$ ls
-66039 crlq.lrj
-dir cwq
-dir dlgrsw
-267814 frhlttn.nmd
-dir hmprt
-dir qpbqqj
-dir wnfzznfh
-$ cd cwq
-$ ls
-77655 cpjnwzh
-dir pcccp
-dir zjbvwsnv
-dir zzhjfmnr
-$ cd pcccp
-$ ls
-dir pcccp
-$ cd pcccp
-$ ls
-245309 bggzbrg.flf
-$ cd ..
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-196915 gnmfb.dzq
-dir ngqbdqp
-$ cd ngqbdqp
-$ ls
-355 rrcsndz.tzp
-$ cd ..
-$ cd ..
-$ cd zzhjfmnr
-$ ls
-dir dbnsfp
-$ cd dbnsfp
-$ ls
-223184 chq.jvb
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd dlgrsw
-$ ls
-181906 chq.jvb
-5636 dbnsfp
-219889 jbr.slc
-dir zrntbl
-$ cd zrntbl
-$ ls
-61864 brnpgpwt
-138980 qpbqqj
-$ cd ..
-$ cd ..
-$ cd hmprt
-$ ls
-90249 dbnsfp.mbd
-$ cd ..
-$ cd qpbqqj
-$ ls
-290377 crlq.lrj
-$ cd ..
-$ cd wnfzznfh
-$ ls
-83022 hclmps
-64095 zhm
-$ cd ..
-$ cd ..
-$ cd pcccp
-$ ls
-dir rdzntr
-dir rvccq
-$ cd rdzntr
-$ ls
-239028 rrcsndz.tzp
-$ cd ..
-$ cd rvccq
-$ ls
-22746 chq.jvb
-288752 jjvppq.swt
-dir msgwsnjq
-dir pggz
-228469 vjlfrdp.tqh
-$ cd msgwsnjq
-$ ls
-102522 lwgqc.mhv
-25239 ndm.llf
-$ cd ..
-$ cd pggz
-$ ls
-dir cnjqsqj
-$ cd cnjqsqj
-$ ls
-229407 shpnq
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd pdnj
-$ ls
-193069 rwnhgttz.pvp
-$ cd ..
-$ cd sjstqlcb
-$ ls
-263295 chq.jvb
-224091 jss.wtr
-$ cd ..
-$ cd zssln
-$ ls
-5859 ncdlcr.dll
-$ cd ..
-$ cd ..
-$ cd dbnsfp
-$ ls
-271252 dhcrzvbr.wmn
-$ cd ..
-$ cd hppb
-$ ls
-259968 jssnn
-81292 qpqqb.clj
-$ cd ..
-$ cd mcnzs
-$ ls
-170903 crlq.lrj
-59482 dhcrzvbr.wmn
-dir dqzwzbgm
-dir gnrztn
-286736 jssnn.jcm
-32791 phqsgl
-dir pzjnrwt
-197323 vjlfrdp.tqh
-dir wvnwbpct
-$ cd dqzwzbgm
-$ ls
-78575 qpbqqj
-251546 qpbqqj.slb
-$ cd ..
-$ cd gnrztn
-$ ls
-158603 hdnwmd.rhj
-dir nbfdtwzr
-178239 ptnchzpg
-40517 rrcsndz.tzp
-dir smvb
-198007 vjlfrdp.tqh
-$ cd nbfdtwzr
-$ ls
-200354 crlq.lrj
-$ cd ..
-$ cd smvb
-$ ls
-163921 zjbvwsnv.brz
-$ cd ..
-$ cd ..
-$ cd pzjnrwt
-$ ls
-33891 lwrll
-259646 pcccp.sfn
-106835 pqfzthjq
-189673 rrcsndz.tzp
-$ cd ..
-$ cd wvnwbpct
-$ ls
-234188 dhcrzvbr.wmn
-dir gmtpsgv
-86379 jssnn
-146663 sfpmdbbd.jvt
-25795 vjlfrdp.tqh
-$ cd gmtpsgv
-$ ls
-18642 chq.jvb
-3046 cznlwtw
-26335 ddgpngrc
-116455 vnnls.hsg
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd npntsr
-$ ls
-dir cccjdcvb
-206657 chq.jvb
-280518 crlq.lrj
-dir dbnsfp
-dir jphnn
-dir jssnn
-dir mpl
-195193 rrcsndz.tzp
-dir rztc
-dir znwp
-$ cd cccjdcvb
-$ ls
-192965 mcr.sfq
-$ cd ..
-$ cd dbnsfp
-$ ls
-dir gfns
-173317 jssnn.tjq
-dir mgr
-68817 mvwcwfcr.zmz
-dir pqfht
-108571 swfl.dtj
-10398 tvvvv
-dir vzg
-174361 zjbvwsnv
-$ cd gfns
-$ ls
-203999 zjbvwsnv.hfg
-$ cd ..
-$ cd mgr
-$ ls
-dir zjbvwsnv
-$ cd zjbvwsnv
-$ ls
-26871 tqlgcf.jrn
-$ cd ..
-$ cd ..
-$ cd pqfht
-$ ls
-199590 clpvscl.rlm
-dir dwlhv
-dir vhzfzhrb
-$ cd dwlhv
-$ ls
-130761 qpbqqj
-242752 rrcsndz.tzp
-$ cd ..
-$ cd vhzfzhrb
-$ ls
-dir njdgcbvm
-$ cd njdgcbvm
-$ ls
-dir snjfqg
-$ cd snjfqg
-$ ls
-dir qpwh
-$ cd qpwh
-$ ls
-153353 qsjpj
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd vzg
-$ ls
-dir pcccp
-$ cd pcccp
-$ ls
-dir jfbtl
-$ cd jfbtl
-$ ls
-209199 dbnsfp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd jphnn
-$ ls
-52305 crlq.lrj
-193480 gmms.whz
-59354 nmq.dww
-64638 qpbqqj
-47072 rrcsndz.tzp
-$ cd ..
-$ cd jssnn
-$ ls
-69168 crlq.lrj
-1549 dhcrzvbr.wmn
-219596 hdmczg.lmm
-108063 jssnn
-24327 vjlfrdp.tqh
-dir zjbvwsnv
-$ cd zjbvwsnv
-$ ls
-189952 chq.jvb
-$ cd ..
-$ cd ..
-$ cd mpl
-$ ls
-144856 bqrrzm
-249487 crlq.lrj
-dir ffqgpgfg
-93632 flqwtn.nsz
-dir mwpcqr
-195910 pdqwn.lcg
-$ cd ffqgpgfg
-$ ls
-66459 dbnsfp
-200500 lcmt.zmz
-207093 qpbqqj
-77042 vjlfrdp.tqh
-57109 wwzv.hbn
-$ cd ..
-$ cd mwpcqr
-$ ls
-dir zjbvwsnv
-$ cd zjbvwsnv
-$ ls
-166393 vjlfrdp.tqh
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd rztc
-$ ls
-57788 chq.jvb
-$ cd ..
-$ cd znwp
-$ ls
-164627 chq.jvb
-$ cd ..
-$ cd ..
-$ cd zjbvwsnv
-$ ls
-dir dgrrl
-71529 jssnn
-198617 pcccp.qqh
-dir phggn
-56842 zjbvwsnv.vqd
-$ cd dgrrl
-$ ls
-dir czm
-dir fhhlbdlz
-dir gstjw
-dir qpbqqj
-dir stgb
-$ cd czm
-$ ls
-dir jssnn
-$ cd jssnn
-$ ls
-162335 chq.jvb
-30099 mfdgdw
-96389 pcdsd.wmw
-251423 tmz.lcb
-205979 vpltdt.gtv
-$ cd ..
-$ cd ..
-$ cd fhhlbdlz
-$ ls
-dir qpbqqj
-dir vdjs
-dir zgz
-$ cd qpbqqj
-$ ls
-285561 chq.jvb
-263924 lbqcfdrs
-138854 pcccp.dtn
-$ cd ..
-$ cd vdjs
-$ ls
-32688 chq.jvb
-223233 tbn.blt
-$ cd ..
-$ cd zgz
-$ ls
-92804 bqltmv.wzb
-$ cd ..
-$ cd ..
-$ cd gstjw
-$ ls
-151784 fvfszzzn.cbh
-$ cd ..
-$ cd qpbqqj
-$ ls
-dir blztqf
-dir plgnh
-$ cd blztqf
-$ ls
-195097 wlvmtz
-$ cd ..
-$ cd plgnh
-$ ls
-dir dbnsfp
-246221 dhcrzvbr.wmn
-271121 jhwmmzls.mhw
-170162 pcccp.dpp
-37872 qpbqqj
-$ cd dbnsfp
-$ ls
-dir dhpnr
-$ cd dhpnr
-$ ls
-152837 pcccp
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd stgb
-$ ls
-248436 vjlfrdp.tqh
-$ cd ..
-$ cd ..
-$ cd phggn
-$ ls
-284602 dhcrzvbr.wmn
-dir lctr
-dir rjmc
-66651 rrcsndz.tzp
-117525 vth.fgw
-156877 wcqnjzbq.dgf
-7803 zpsrzclh.bzw
-$ cd lctr
-$ ls
-212339 jssnn.whp
-dir jzhcqb
-99974 pcccp.zhs
-111354 pmc
-104899 vjlfrdp.tqh
-93496 zhwmbw
-$ cd jzhcqb
-$ ls
-dir zjbvwsnv
-$ cd zjbvwsnv
-$ ls
-146807 rbrg
-$ cd ..
-$ cd ..
-$ cd ..
-$ cd rjmc
-$ ls
-dir fvbmsc
-139747 glwmr.lrg
-dir gvnnz
-102023 tbj.qmz
-dir vsztsjfh
-$ cd fvbmsc
-$ ls
-136838 vpvbz.qtw
-$ cd ..
-$ cd gvnnz
-$ ls
-95498 zjbvwsnv
-$ cd ..
-$ cd vsztsjfh
-$ ls
-215479 ffwlcrwb
--- a/07/small.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-$ cd /
-$ ls
-dir a
-14848514 b.txt
-8504156 c.dat
-dir d
-$ cd a
-$ ls
-dir e
-29116 f
-2557 g
-62596 h.lst
-$ cd e
-$ ls
-584 i
-$ cd ..
-$ cd ..
-$ cd d
-$ ls
-4060174 j
-8033020 d.log
-5626152 d.ext
-7214296 k
--- a/08/08.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-
-const input = "08/input.txt"
-
-const short = "30373
-25512
-65332
-33549
-35390";
-
-function parse_trees(lines::Vector{S})::Matrix{Int} where {S <: AbstractString}
-    m = zeros(length(lines), length(lines[1]));
-    for (i, line) in enumerate(lines)
-        for (j, c) in enumerate(line)
-            m[i,j] = parse(Int, c);
-        end
-    end
-    m
-end
-
-function visibility(row_or_col::AbstractVector{Int})::Vector{Bool}
-    v = zeros(Bool, length(row_or_col));
-    highest = row_or_col[begin];
-    v[begin] = true;
-    for i in eachindex(row_or_col)
-        if row_or_col[i] > highest
-            v[i] = true;
-            highest = row_or_col[i];
-        end
-    end
-    v
-end
-
-function is_visible(m::Matrix{Int})::Matrix{Bool}
-    rows, cols = size(m);
-    v = zeros(Bool, size(m));
-
-    # Row-wise
-    for row in 1:rows
-        v_forward = @views visibility(m[row,:]);
-        v_backward = @views visibility(m[row,end:-1:begin]);
-        reverse!(v_backward);
-        v[row,:] .= v_forward .| v_backward;
-    end
-    # Col-wise
-    for col in 1:cols
-        v_down = @views visibility(m[:,col]);
-        v_up = @views visibility(m[end:-1:begin,col]);
-        reverse!(v_up);
-        v[:,col] .|= v_down .| v_up;
-    end
-    
-    v
-end
-
-function find_scenic_distance(v::AbstractVector{Int})::Int
-    ref = v[1];
-    for i = 2:length(v)
-        if v[i] >= ref
-            return i-1;
-        end
-    end
-    return length(v)-1;
-end
-
-function scenic_score(m::Matrix{Int}, row::Int, col::Int)::Int
-    v = m[row, col];
-
-    l = find_scenic_distance(@view m[row, col:-1:begin]);
-    r = find_scenic_distance(@view m[row, col:end]);
-    u = find_scenic_distance(@view m[row:-1:begin, col]);
-    d = find_scenic_distance(@view m[row:end, col]);
-    l*r*u*d
-end
-
-function scenic_scores(m::Matrix{Int})::Matrix{Int}
-    s = zeros(Int, size(m));
-    for ix in CartesianIndices(size(m))
-        s[ix] = scenic_score(m, Tuple(ix)...);
-    end
-    s
-end
-
-println("Real challenge, part 1:");
-inp_lines = readlines(input);
-trees = parse_trees(inp_lines);
-println(sum(is_visible(trees)));
-
-println("Part two:");
-ss = scenic_scores(trees);
-println("max scenic score: ", maximum(ss));
--- a/08/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-230302102312303431324124303141114045300001501242156105363242032123135210143324224140132332112100221
-322200120140130323143433402101444233512140224062422011111403231052521053542252401012232443102111032
-220300201042003221454531141345330151415344324656555610153343240503352304331551230452141112120303320
-131301034134041313145104311104431531104002136262204021050462633364005504230105333250310334430012231
-021000431324243205221240551231546346005546113055526350502461501303260444304552521404504240012202100
-130032042140100501120530551053341401664420533042546256013026351632616214431331333233341222140143402
-102213021202104044154525451632332223320015014365014110000262152226451306654102512123512023131343201
-331321033401405043214153225511265312435604105124767542760400104362304616510410004451235001241134031
-234010022341252215202325124644011146300614531262461555623242615510132104506502155353245030411321214
-304102101231325220244422554336626240225366453655233535214545356712401516453566460554521045401410034
-124222310241022025221634021203456261377536264451547554432421672616632511164231351545110100421124041
-231432431351552412035636562534314116212363155763515352233177566413166344310511112324524355103343213
-103031123324141030040550165506212465546735652123674755314542271633361443500442335114204031255241224
-320113443131100311503426244335257671411253247761166615472155473411374661621210160254602143000503002
-003031503150544521324165216521624371212157515435232724117746343274255223574322040541222535240125320
-431234101124435354234422257673575575175341283683836588272273446224536761435621240216142511140302323
-123130200251405600130545412766211145442246588283778878426386645127335561311156623533260243441410122
-432402514341626355125037245134531317588423262388855625822687585244364351651321623121561560010312113
-312341305215255100304471152277172523637784345263433358277226635245516164123212336452605424200110430
-001434330142034560665237211325533756327872855833882354736845633764265764254723135136216531341302425
-345110412256633232261137637156368637757634446735753883783375577533786454271246611655350133245255344
-130515311233246602623742771612278266785844368233445235428485736334867477631346361563230603123034134
-330040046512436325746335744443684727248746257893478978476233834562664674872164576161101306065422041
-222154026412500467311716243862854643768585738339383839693837627262625554423155651645532206206134414
-542550455123342216235327358832483365754856794969568679863575688486863754828773355515541016335040545
-404234533623052522751165344644483278684968464647937735374953694986883822877673474565215510426220344
-314254353400344713147333655472357537587356967673598874457668767889935746887521663427411521635661241
-250301522140303127537224263455464893375697787574446387685355687386368545878447447117247625662212301
-531245634640354662654558667774728435789865389774334746464789766764944468568554351264634206163162541
-254210565205047575772722425336239545866857335764867899689375964484886366575237326255114412442436305
-254440240052645344117878758858477694934868449869846797495773435673485582766622343237654674230614650
-302350056253421457757382352837655457348549979584868566587675763536549455773244366226575120110432202
-524251410101643732555863746673768898357598988876769465556757759865678788677845447537546514520246465
-412424366507365464723435562846447777556788564867748886999988659539789863738827284322243654235650222
-302260630341726247764652638469957786688964699758599945666799457875988357894464748565724572166261234
-215150213244237121847528247786444449998976749466844877974565875546766745893426378444445742710223525
-424160233533557213425484474439489658786978977985856797555685676569553489768586885887425626363046446
-153322066741372433344452464455559968984567799888687677756697744545783483874576867684647332571001005
-145420124453223247785888737894569596698676567955697655669665679864796955354676474465373675660155614
-033506450161333145373824444348436889577445897969987595896979686466678689467597644746532527513131131
-225012522655144432763537973395798658496758867787886779885975689947696977368784268458336146373115143
-216342537614133655675625959443677654855666875698895757965779667678777945996749485327555574145424460
-166106344353256563624325443477776845578965867968867569996565856754694668864655545773383227234335414
-150522031675635233237668486584959896545865765899786958699768689485564988376498275457676373151605464
-412336103615667832572493349365459748765865988788966796676798558958658889874394465442751254315016610
-352326617457732528434753466738454444568858687988678798897989789856878957499594873552874152661460523
-062415331267566426437243673895878674897896558788889897878987955994767455333837536424584567627336053
-411350266636525852438469567638886987958577976996868967687585597767547999698594634538245463464543005
-052464462614766832722735867947598567878869668679877788879769878876988899643845375267672315514353000
-543545564473648376567477376798669977686956967668898889969875757785956549649485643782434576251353131
-634033674455736672452884665689654778778759896979877869977686568577555776433947564287374612267436364
-620541245674573376723897469464969646966776677799787978979857977798869788359344972235473531452736105
-602620347126374653254296764775476547797557857869988876878957998886476566934646536357683276776151421
-453313013613244386884696349435758974966876787969887886879899685595858499393337785854825724737215563
-633162016753461244685737989459664898569667899679799786798979988797998958559548885735471347141136630
-000101426742225562735894769979656676989556887676998666978968879767489645833678358457422477754521142
-620262606411662643533249376858748847498879757666997687879595676878844467633967768755461265735510400
-360023137544654575733228376896988578467698566656988978959969695576685749457685864437734765717026064
-453004005155344764583728835857979544659758957678779579869558958494954483997436423583442547122611144
-542364512554772785834745874957646879945679759867877799887755596454644564849589474263221373377352410
-002404034225236156254239388474876685554666797767767967895789558759867549659597464467365225556245635
-245410135477125426663788797639838547747878866579559887665897566567957973945395387477415314463463430
-134134265157751574644752634743354666668958565798799857969998998868959355953856752485414215452524346
-134233063522723113742886693543696949958945798696986777765986578999899884698774475872617234240653423
-244361001066345154366465584498936779955869489578987799745999756687935697875536775754117227145563503
-424615513054521426726444456756894679964484855474988695686689467459399699543485425832215323565610231
-010511022361177421578425884488933866869996559974758675556944646898573447548734866775441423552334113
-455000614233131572534883424588896457684489858997764475858957676964979965647378323342574224433221410
-554234433657562455545554335673953366894875796478846544767476975987878676385863745315342113644542314
-334234343615275457652768335759749448996379787584585465788795884334949898848654742611353314261636503
-333304555356366151638427333872998755488366686597689567687856687846596683534345663212543346305030250
-221202454261633375664542356764698437549939857548989949987335436749598666277762261737227146546505534
-240412550420563537276688628732843367868467736695759997434973759746799657483248636225432651522613045
-234101415413036337546543888388563596433499988836578844689689497975764628525732325317653041241353030
-431410263125326725415234754275746658476797893535668937455785755994425345326575247342241464251000421
-235305105630506142127546572374764553754685586586673543349859396362874755756655416517334460144522501
-053230360255455453432625173284836864837934635996948769536785973725832747476731215716516416145320150
-220341023145561653434447455522778482225563875986777563368797985846552555226462623761223514365411344
-555505021215644010564473315638562438843876455985785666379866472746877227331266714741141010601131000
-453335252144616255521312353556677472322787423527747647554222386736627248134362414253412412531431213
-042151015320560413551651234262565787675225582872838475557456742335545484137617276444245016450453552
-014404334344615462565743465273746656366752555484464325685467246827267515345457117051354205241444340
-213041551013263163616741653367152326275633684378845888827238722532735171772265542620411543050510551
-224455113205603560061536164734146772822552432636277537568582283454552565546556622004610432104440414
-120034300413036442405642132721761733145582724757284464865848374626544672733422446132110450322334043
-321102323253550034451665134657546626247721386824348475375862731112516436572563504423615532222151203
-423413023253053651012440232734663275166577433646527244777525111735773767313620631626060044333201413
-310311122105544263022025236566616265144255413423733523634375771573412213343520014446112203251501244
-242112304444105230054262221514232727536351532732445557376642241447573270443566533260102401044113312
-300401122201443130504625604224103567247721576334262357161547725313757534624304442441502400005401420
-312140241542522534423315456561105236441214136262754317657256235334116150340065011324403154142414212
-144233324321121441233255150514400352347655162673141155544742475145632635002103305025150134340421444
-111103103110050242122311312046534446626061741554364774752533752234163656421540312341011215100222430
-303431234002202314522440214134041163045124514037641775350115015005306206502562310105314100032000400
-022101131200322543535350013343206260166164021153334624135541245000601615213233143310354543221432032
-233233001110344441512334010360062644015111403065346201116113310635016323603102000435213440203331333
-221234200414024043305553013402501300310163441031202131631042043410330561032554522352320341422042103
-321123401142123425525550311314256215506650120142506242614512364236453401432552531430304012423410223
-122333244113420243051112411113522042223653563261365250113056645225530145055223432541231304233333203
--- a/09/09.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-
-const test_input::String = "R 4
-U 4
-L 3
-D 1
-R 4
-D 1
-L 5
-R 2";
-
-const test_input2::String = "R 5
-U 8
-L 8
-D 3
-R 17
-D 10
-L 25
-U 20";
-
-@enum Direction begin
-    U
-    D
-    L
-    R
-end
-
-function to_direction(c::Char)::Direction
-    if c == 'U'
-        U
-    elseif c == 'D'
-        D
-    elseif c == 'L'
-        L
-    elseif c == 'R'
-        R
-    end
-end
-
-struct Step
-    direction::Direction
-    n::Int
-end
-
-function parse_input(lines::Iter)::Vector{Step} where {Iter}
-    v = Vector{Step}();
-    for l in lines
-        a, b = split(l, ' ');
-        push!(v, Step(to_direction(a[1]), parse(Int, b)));
-    end
-    v
-end
-
-function wheretogo(H::Tuple{Int,Int}, T::Tuple{Int,Int})::Vector{Direction}
-    # This might have a more elegant solution...
-    if H == T
-        []
-    elseif H[1]==T[1]
-        if abs(H[2]-T[2]) < 2
-            []
-        else
-            (H[2] > T[2] ? [U] : [D])
-        end
-    elseif H[2]==T[2]
-        if abs(H[1]-T[1]) < 2
-            []
-        else
-            (H[1] < T[1] ? [L] : [R])
-        end
-    elseif abs(H[1]-T[1]) + abs(H[2]-T[2]) == 3  # diagonal
-        if abs(H[1]-T[1]) > abs(H[2]-T[2])
-            snd = (H[2]-T[2]) > 0 ? U : D;
-            (H[1]-T[1]) > 0 ? ([R, snd]) : ([L, snd])
-        else
-            snd = (H[1]-T[1]) > 0 ? R : L;
-            (H[2]-T[2]) > 0 ? ([U, snd]) : ([D, snd])
-        end
-    elseif abs(H[1]-T[1])==abs(H[2]-T[2]) && abs(H[1]-T[1]) > 1
-        [(H[1]>T[1] ? R : L), (H[2]>T[2] ? U : D)]
-    else
-        if abs(H[1]-T[1])+abs(H[2]-T[2]) == 2
-            []
-        else
-            error("unhandled case: ", H, T)
-        end
-    end
-end
-
-function apply(p::Tuple{Int,Int}, dir::Direction)::Tuple{Int,Int}
-    if dir == U
-        p .+ (0,1)
-    elseif dir == D
-        p .+ (0,-1)
-    elseif dir == L
-        p .+ (-1,0)
-    else
-        p .+ (1,0)
-    end
-end
-
-function process1(v::Vector{Step}; ntails=1)::Int
-    H = (0, 0);
-    T = [(0,0) for i in 1:ntails];
-    visited = Set{Tuple{Int,Int}}([H])
-
-    for step in v
-        for i = 1:step.n
-            H = apply(H, step.direction);
-            # Tail follow
-            pred = H
-            for (i,t) in enumerate(T)
-                wtg = wheretogo(pred, t);
-                for w in wtg::Vector{Direction}
-                    T[i] = apply(T[i], w);
-                end
-                pred = T[i];
-            end
-            push!(visited, pred);
-        end
-    end
-    length(visited)
-end
-
-println("test input (should be 13):");
-println(process1(parse_input(split(test_input, '\n'))));
-println("part 1:");
-open("09/input.txt"; read=true) do fh
-    @time println(process1(parse_input(eachline(fh))));
-end
-
-println("part 2:");
-println(process1(parse_input(split(test_input2, '\n')); ntails=9));
-open("09/input.txt"; read=true) do fh
-    @time println(process1(parse_input(eachline(fh)); ntails=9));
-end
--- a/09/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2000 +0,0 @@
-R 1
-D 1
-L 1
-D 1
-L 2
-U 2
-D 2
-R 1
-D 1
-L 2
-R 1
-L 2
-R 2
-L 1
-R 2
-D 1
-R 1
-D 2
-U 1
-R 1
-D 2
-R 2
-L 1
-D 1
-R 2
-D 2
-R 1
-L 2
-D 1
-L 2
-D 2
-R 2
-D 2
-L 1
-D 1
-L 1
-D 1
-R 2
-L 2
-R 2
-D 2
-R 2
-D 2
-R 2
-L 2
-R 2
-U 1
-R 1
-D 2
-R 1
-L 1
-U 1
-L 2
-U 1
-D 1
-R 1
-U 1
-R 2
-D 2
-U 2
-D 2
-R 1
-L 1
-U 2
-L 2
-D 2
-L 1
-R 2
-D 1
-R 1
-L 2
-U 2
-R 1
-D 1
-U 2
-L 1
-U 2
-L 1
-R 2
-D 2
-R 1
-D 2
-R 1
-D 1
-R 1
-D 1
-L 2
-D 2
-R 2
-D 2
-R 1
-D 1
-R 2
-L 1
-U 2
-R 2
-D 1
-L 2
-U 1
-D 2
-L 2
-D 2
-L 2
-D 1
-R 1
-L 1
-U 2
-L 2
-D 1
-L 2
-U 1
-L 3
-D 1
-R 1
-U 3
-L 2
-U 1
-D 3
-L 1
-D 2
-R 1
-L 3
-D 2
-L 2
-D 1
-L 1
-R 2
-L 3
-D 2
-L 1
-U 3
-L 1
-R 3
-U 1
-R 3
-U 3
-D 1
-L 2
-U 2
-D 2
-U 3
-D 3
-L 1
-U 3
-D 3
-L 3
-R 1
-D 1
-U 2
-R 1
-U 3
-L 3
-D 2
-L 3
-D 1
-R 2
-U 1
-D 2
-L 3
-D 2
-U 2
-R 1
-L 3
-R 2
-L 2
-U 2
-R 2
-L 1
-D 1
-U 3
-D 1
-R 2
-L 1
-U 1
-R 1
-L 1
-D 2
-L 1
-D 1
-L 1
-D 3
-U 3
-D 3
-R 3
-D 2
-L 1
-R 1
-L 1
-D 3
-L 2
-D 1
-R 1
-D 3
-U 3
-L 2
-D 1
-U 1
-D 1
-U 3
-R 2
-L 1
-D 3
-U 3
-D 3
-U 2
-L 1
-R 1
-U 1
-D 3
-R 2
-U 1
-L 2
-U 1
-L 2
-U 2
-D 1
-L 3
-U 1
-R 1
-L 2
-U 1
-D 2
-L 1
-D 4
-L 3
-D 4
-R 2
-D 2
-L 3
-U 2
-L 3
-D 1
-L 4
-R 2
-D 1
-U 4
-L 3
-D 1
-R 1
-D 4
-R 4
-U 3
-D 3
-L 3
-D 3
-U 1
-R 4
-L 2
-D 1
-R 3
-L 4
-D 1
-R 2
-L 4
-U 3
-L 4
-R 1
-L 3
-D 1
-U 4
-L 4
-R 3
-U 4
-D 3
-U 2
-R 3
-D 1
-R 3
-L 3
-D 2
-U 4
-R 3
-U 4
-L 4
-R 4
-L 2
-R 2
-D 3
-L 2
-U 1
-L 4
-U 3
-R 3
-L 4
-U 1
-L 1
-U 1
-D 2
-R 1
-U 1
-L 3
-R 4
-L 2
-D 4
-R 3
-L 2
-R 1
-L 4
-R 1
-D 2
-R 4
-L 3
-U 3
-L 3
-D 1
-R 2
-L 4
-D 2
-R 3
-U 2
-D 3
-R 2
-U 4
-L 1
-U 2
-D 2
-L 1
-D 4
-R 3
-L 3
-R 4
-D 1
-U 2
-R 2
-D 1
-L 3
-U 2
-L 3
-R 1
-D 1
-R 4
-L 4
-R 1
-U 3
-R 4
-L 3
-D 3
-L 4
-R 4
-D 5
-R 2
-U 5
-L 1
-D 5
-L 5
-R 1
-L 5
-U 5
-L 3
-D 3
-L 2
-D 1
-L 1
-U 1
-L 1
-D 2
-L 3
-U 2
-D 3
-L 4
-R 5
-U 2
-L 3
-D 3
-R 4
-U 3
-D 5
-U 1
-R 3
-L 3
-D 1
-U 2
-L 3
-R 5
-D 2
-R 2
-U 4
-L 2
-R 4
-D 5
-R 2
-U 2
-D 5
-L 3
-R 2
-D 2
-L 1
-U 2
-R 1
-D 2
-U 1
-L 2
-U 5
-R 1
-U 4
-D 1
-R 4
-U 4
-R 3
-D 1
-U 2
-L 5
-U 1
-L 3
-D 1
-U 5
-D 5
-U 1
-L 3
-D 1
-R 2
-L 4
-R 4
-L 2
-U 2
-R 5
-U 1
-R 5
-L 1
-D 1
-R 3
-D 2
-R 4
-L 5
-D 3
-L 3
-U 5
-R 2
-D 5
-L 1
-U 2
-D 2
-U 4
-R 4
-L 4
-U 1
-D 1
-U 4
-R 4
-D 3
-L 4
-R 2
-D 3
-R 5
-U 4
-L 4
-R 4
-L 2
-U 4
-R 4
-D 1
-R 3
-D 6
-U 6
-D 5
-L 4
-R 2
-D 5
-R 5
-D 3
-R 3
-U 3
-D 3
-U 2
-L 2
-R 6
-L 6
-D 1
-L 4
-R 6
-D 5
-L 2
-R 4
-U 2
-L 5
-R 6
-U 6
-D 1
-U 3
-D 3
-R 1
-L 4
-D 2
-U 1
-L 2
-R 1
-D 3
-U 5
-R 1
-D 2
-U 5
-D 5
-R 3
-U 2
-D 4
-U 2
-R 5
-U 4
-R 2
-L 4
-U 5
-L 3
-D 1
-R 3
-U 3
-L 1
-U 1
-L 2
-R 5
-U 2
-D 4
-R 1
-D 5
-L 6
-R 6
-U 2
-D 4
-R 4
-D 4
-L 6
-D 3
-U 1
-L 4
-U 5
-R 3
-D 3
-R 6
-D 3
-R 6
-D 1
-L 3
-R 4
-D 5
-R 4
-D 6
-R 3
-U 6
-R 4
-U 1
-D 4
-L 2
-D 4
-L 2
-U 2
-R 4
-D 4
-L 1
-D 4
-U 4
-D 6
-U 3
-D 1
-L 2
-D 5
-R 2
-D 2
-L 5
-R 4
-L 5
-R 5
-U 6
-L 1
-R 3
-U 5
-D 1
-U 2
-R 2
-D 4
-R 4
-D 6
-R 4
-L 4
-D 2
-R 6
-L 1
-D 1
-U 3
-R 1
-D 4
-L 1
-D 3
-U 5
-R 2
-U 2
-D 6
-L 5
-U 4
-L 5
-R 3
-U 7
-R 2
-D 1
-R 6
-D 6
-U 6
-R 5
-D 5
-R 6
-D 6
-R 6
-D 5
-U 5
-D 7
-L 4
-U 3
-D 3
-U 2
-L 2
-U 4
-D 1
-R 7
-U 4
-L 1
-D 4
-L 3
-R 6
-L 1
-R 2
-L 4
-R 5
-U 6
-D 6
-U 2
-R 5
-U 4
-L 5
-U 3
-D 1
-L 6
-R 2
-D 2
-L 3
-U 5
-R 6
-U 7
-R 1
-L 7
-D 5
-U 5
-D 2
-R 4
-U 2
-L 7
-R 4
-D 7
-U 4
-D 3
-R 2
-D 3
-L 3
-U 6
-R 2
-L 6
-D 2
-R 6
-L 3
-R 4
-U 1
-D 3
-U 2
-L 4
-D 6
-U 7
-D 4
-L 3
-R 1
-U 6
-L 3
-R 3
-U 7
-R 7
-U 6
-L 1
-U 8
-L 1
-D 8
-L 6
-R 3
-L 7
-D 5
-U 8
-R 5
-L 4
-U 8
-L 3
-D 2
-U 1
-R 8
-D 8
-R 7
-U 1
-D 2
-R 6
-L 8
-D 5
-L 6
-U 1
-R 2
-U 6
-L 3
-D 6
-U 2
-R 2
-D 1
-U 4
-L 8
-D 8
-R 1
-L 2
-R 2
-D 7
-U 5
-D 8
-L 1
-R 7
-L 8
-D 2
-R 8
-D 7
-U 3
-R 3
-U 3
-D 1
-L 2
-U 6
-D 7
-U 8
-R 6
-D 6
-R 5
-U 7
-R 8
-L 1
-U 7
-D 2
-R 6
-U 7
-R 3
-D 3
-R 3
-U 4
-D 8
-L 7
-R 5
-U 1
-L 6
-R 8
-D 6
-R 4
-L 4
-D 1
-U 5
-L 6
-U 1
-D 8
-U 2
-R 4
-L 2
-R 8
-D 1
-R 1
-L 4
-R 7
-U 7
-D 8
-R 8
-L 6
-U 7
-L 4
-D 2
-R 2
-U 5
-D 1
-R 5
-L 6
-U 8
-L 1
-R 7
-D 8
-L 3
-D 2
-U 3
-D 3
-L 1
-R 3
-L 7
-D 6
-R 4
-D 1
-U 8
-L 3
-D 6
-L 7
-U 5
-R 6
-D 2
-L 4
-R 9
-D 2
-R 4
-D 6
-R 5
-L 7
-R 5
-U 7
-R 1
-L 5
-U 6
-R 4
-D 8
-U 5
-L 4
-U 1
-D 8
-U 9
-D 4
-U 7
-L 4
-R 8
-D 4
-R 4
-D 8
-R 1
-D 3
-R 5
-D 7
-U 8
-D 2
-R 2
-U 1
-L 1
-U 2
-L 9
-R 9
-D 1
-U 1
-D 8
-R 3
-L 8
-D 7
-U 9
-R 6
-L 4
-U 8
-D 4
-U 2
-L 3
-D 8
-L 2
-R 5
-U 4
-D 6
-U 6
-L 8
-R 7
-D 2
-R 3
-L 8
-U 9
-R 2
-U 4
-L 9
-R 5
-D 5
-R 4
-D 6
-R 3
-D 3
-R 8
-D 3
-R 4
-D 1
-U 2
-D 6
-R 4
-D 7
-U 5
-D 2
-R 6
-D 3
-U 3
-R 4
-U 5
-L 3
-U 5
-L 8
-D 3
-L 8
-D 5
-R 4
-L 8
-R 5
-U 8
-R 10
-D 2
-U 10
-R 1
-D 1
-L 4
-D 9
-L 6
-U 2
-R 3
-D 2
-L 6
-R 2
-L 10
-D 2
-L 10
-U 3
-L 2
-D 8
-U 10
-R 5
-L 1
-U 8
-R 9
-D 8
-U 2
-R 4
-U 3
-D 2
-U 4
-D 2
-R 3
-L 2
-U 4
-D 1
-U 9
-R 2
-U 1
-R 3
-D 3
-L 3
-R 2
-D 1
-U 8
-D 1
-L 5
-R 4
-L 8
-D 3
-L 1
-U 10
-R 9
-D 9
-U 9
-D 1
-R 6
-L 6
-U 6
-L 1
-D 5
-L 4
-U 8
-L 10
-U 9
-R 9
-D 5
-U 4
-D 7
-R 5
-U 10
-D 5
-U 1
-R 5
-L 7
-D 9
-R 5
-L 3
-U 2
-D 6
-R 4
-D 7
-U 4
-R 8
-L 5
-R 8
-L 9
-R 8
-D 1
-R 1
-L 9
-D 7
-L 10
-D 6
-R 8
-U 4
-D 4
-R 7
-L 9
-D 9
-R 9
-L 1
-R 6
-L 7
-R 10
-L 1
-U 9
-D 11
-R 4
-D 4
-U 5
-R 8
-U 9
-L 8
-D 8
-L 10
-U 10
-L 4
-D 1
-L 3
-U 7
-D 11
-U 4
-L 7
-R 2
-U 9
-D 4
-R 4
-U 1
-L 5
-U 10
-R 4
-D 3
-L 9
-R 2
-L 3
-U 5
-D 6
-U 2
-R 7
-D 7
-R 4
-L 8
-U 5
-R 1
-U 4
-D 3
-U 5
-R 9
-D 2
-R 4
-D 8
-U 9
-R 7
-U 5
-D 3
-R 6
-L 7
-U 7
-R 10
-L 3
-U 10
-L 8
-R 11
-L 3
-U 10
-R 5
-D 1
-U 7
-R 6
-U 9
-L 3
-R 9
-L 4
-R 9
-L 5
-R 9
-D 5
-U 8
-R 7
-L 7
-R 4
-L 9
-R 9
-D 7
-R 2
-L 3
-U 1
-L 1
-D 11
-U 3
-D 5
-R 3
-U 11
-L 1
-U 7
-R 8
-D 8
-U 7
-D 7
-R 6
-D 3
-R 8
-L 9
-U 10
-D 10
-L 1
-D 9
-L 1
-R 5
-D 6
-U 5
-L 1
-R 10
-L 1
-U 7
-D 11
-R 8
-U 11
-L 6
-R 4
-U 7
-R 3
-L 8
-D 8
-L 12
-U 3
-D 12
-L 6
-R 1
-U 8
-R 3
-U 4
-L 3
-D 10
-L 9
-D 6
-L 12
-R 11
-D 4
-U 4
-L 12
-R 1
-U 1
-D 10
-L 11
-R 3
-D 4
-R 4
-U 4
-D 3
-U 10
-R 9
-U 9
-L 1
-U 10
-D 11
-U 4
-D 3
-L 10
-R 5
-D 8
-R 5
-U 6
-R 12
-L 10
-U 10
-D 2
-L 6
-U 5
-D 3
-R 2
-D 3
-U 7
-D 1
-L 5
-U 9
-D 3
-U 10
-L 10
-U 4
-L 12
-R 11
-D 2
-L 10
-U 6
-L 4
-D 5
-R 3
-L 4
-D 8
-U 7
-R 12
-D 1
-U 5
-L 2
-D 7
-R 3
-U 1
-L 10
-R 9
-L 7
-R 8
-U 9
-R 9
-U 1
-L 7
-D 6
-L 1
-R 11
-L 9
-U 12
-R 8
-U 3
-R 5
-U 5
-L 12
-R 7
-L 8
-R 11
-L 4
-R 10
-D 2
-L 4
-U 12
-R 5
-D 1
-L 12
-D 1
-L 5
-D 3
-U 8
-L 5
-U 5
-R 7
-D 1
-L 3
-D 9
-L 12
-R 5
-D 12
-U 6
-L 7
-D 6
-L 5
-U 6
-R 7
-U 5
-D 8
-R 11
-D 12
-R 10
-L 11
-R 6
-L 13
-D 3
-L 2
-U 4
-D 12
-U 8
-D 6
-R 2
-D 2
-R 13
-U 1
-D 6
-R 8
-D 12
-L 8
-R 4
-L 7
-R 8
-D 9
-U 3
-L 1
-U 3
-L 10
-R 12
-U 13
-R 7
-U 1
-D 13
-U 6
-L 13
-D 11
-U 8
-L 10
-D 13
-R 11
-L 8
-D 5
-U 11
-R 1
-D 9
-L 4
-D 12
-R 13
-L 11
-D 7
-L 9
-U 8
-L 13
-D 11
-L 10
-R 4
-U 4
-D 4
-L 5
-D 7
-L 12
-U 10
-R 3
-L 10
-U 2
-L 2
-R 8
-L 6
-U 11
-L 4
-D 4
-U 9
-L 1
-R 12
-D 12
-R 13
-D 8
-R 8
-L 12
-U 5
-D 8
-L 7
-D 13
-U 12
-D 12
-R 10
-U 10
-R 13
-D 9
-R 3
-U 13
-L 12
-R 6
-U 14
-D 11
-R 14
-L 2
-R 5
-U 6
-R 10
-U 6
-L 3
-R 8
-U 7
-L 3
-D 4
-R 13
-L 10
-D 5
-U 10
-R 13
-L 6
-R 6
-L 1
-D 4
-U 10
-R 14
-U 7
-L 11
-R 14
-D 11
-R 8
-D 2
-U 13
-L 5
-R 10
-D 6
-U 7
-D 7
-L 6
-U 11
-L 4
-D 11
-L 9
-R 6
-L 5
-U 14
-R 2
-D 1
-U 12
-L 3
-U 3
-D 2
-U 3
-L 7
-U 10
-D 2
-R 9
-L 8
-U 10
-D 4
-R 7
-U 4
-L 8
-R 3
-L 6
-D 2
-R 11
-L 2
-D 12
-U 14
-L 1
-R 1
-U 12
-R 3
-L 14
-U 9
-D 7
-L 3
-U 8
-R 9
-L 4
-U 7
-D 4
-R 5
-D 7
-R 11
-L 13
-R 3
-D 10
-R 11
-U 6
-L 4
-D 9
-R 4
-U 5
-D 9
-R 13
-D 6
-R 11
-L 1
-D 1
-R 13
-U 4
-L 9
-U 14
-L 9
-R 2
-D 2
-L 7
-D 13
-L 11
-D 8
-R 4
-L 7
-R 4
-U 12
-D 5
-R 13
-D 14
-R 7
-U 6
-R 2
-U 13
-L 7
-U 14
-R 11
-U 15
-R 8
-U 7
-D 7
-L 5
-U 2
-D 13
-U 11
-L 12
-R 6
-D 13
-L 6
-U 8
-L 3
-R 15
-L 13
-D 1
-U 2
-L 14
-D 8
-L 4
-U 6
-R 11
-D 11
-R 2
-U 13
-L 13
-R 2
-U 15
-R 3
-D 4
-L 7
-R 7
-D 7
-R 7
-L 13
-R 10
-U 8
-R 13
-L 2
-U 13
-D 8
-U 15
-L 4
-D 13
-R 13
-U 8
-R 3
-L 11
-R 12
-U 2
-L 13
-U 1
-L 9
-U 11
-D 14
-R 12
-D 6
-U 6
-D 12
-U 8
-R 3
-U 4
-R 8
-U 2
-D 5
-L 12
-U 14
-D 4
-R 1
-U 10
-L 10
-R 6
-D 13
-U 11
-D 11
-U 11
-R 14
-D 15
-L 11
-U 14
-D 7
-L 12
-D 3
-L 14
-U 7
-R 1
-U 5
-L 1
-R 15
-U 13
-D 7
-R 9
-L 15
-U 15
-L 15
-D 7
-R 15
-D 3
-U 5
-L 8
-R 13
-L 15
-D 8
-L 15
-D 12
-L 5
-D 14
-U 16
-R 11
-L 14
-R 6
-L 10
-U 11
-R 8
-U 16
-L 6
-U 9
-L 13
-D 14
-R 7
-D 10
-L 15
-D 1
-L 10
-D 1
-R 2
-U 15
-L 9
-U 6
-D 3
-L 8
-D 13
-U 16
-D 12
-R 2
-L 1
-D 8
-L 15
-R 14
-D 8
-L 9
-U 12
-R 3
-U 15
-D 10
-U 13
-R 8
-L 15
-D 9
-R 8
-L 9
-U 2
-R 7
-L 11
-R 3
-D 13
-U 16
-L 9
-U 6
-L 7
-U 4
-L 16
-U 16
-L 12
-U 9
-R 8
-D 13
-L 2
-R 15
-D 7
-U 15
-D 16
-R 12
-L 12
-U 8
-L 8
-D 3
-R 16
-L 3
-U 13
-R 1
-L 5
-R 10
-U 13
-D 7
-R 3
-D 10
-L 2
-R 1
-U 4
-L 13
-U 15
-R 4
-D 1
-R 2
-L 5
-D 3
-L 1
-R 4
-L 1
-U 1
-D 7
-R 9
-L 12
-R 13
-D 5
-R 5
-D 9
-L 15
-R 17
-D 4
-R 2
-U 1
-D 1
-R 3
-L 15
-D 10
-L 8
-U 16
-L 14
-U 12
-R 5
-L 13
-D 10
-L 15
-D 12
-U 4
-D 8
-R 9
-L 17
-D 17
-U 3
-D 2
-L 14
-D 12
-L 5
-D 9
-L 3
-R 10
-U 1
-R 9
-U 16
-L 14
-R 13
-L 11
-R 4
-U 2
-L 10
-D 6
-R 5
-D 17
-L 15
-R 12
-U 15
-L 9
-U 9
-D 3
-R 8
-U 6
-R 8
-U 9
-D 14
-R 7
-U 1
-L 3
-R 3
-D 2
-U 4
-R 5
-L 17
-D 16
-U 13
-D 5
-U 6
-R 2
-U 5
-D 7
-U 11
-R 6
-L 17
-R 4
-L 14
-D 3
-U 15
-L 5
-R 4
-U 1
-D 16
-L 16
-U 10
-L 10
-D 17
-R 6
-D 2
-U 10
-L 10
-D 12
-R 15
-L 4
-R 11
-L 17
-U 15
-L 8
-U 8
-L 16
-D 6
-L 7
-U 17
-L 14
-D 6
-L 5
-R 14
-U 5
-D 1
-U 2
-D 17
-R 14
-L 1
-R 4
-D 7
-L 8
-U 7
-D 6
-L 16
-U 5
-D 7
-R 7
-D 17
-L 16
-R 1
-D 5
-U 17
-L 2
-U 7
-L 16
-U 15
-L 17
-D 3
-L 2
-R 7
-L 11
-R 1
-L 16
-U 2
-L 1
-R 18
-U 5
-L 9
-U 4
-D 8
-U 4
-L 18
-D 17
-L 14
-D 2
-R 1
-U 13
-L 9
-R 14
-D 14
-U 12
-D 14
-L 2
-U 10
-D 11
-R 10
-L 9
-U 7
-D 12
-L 4
-D 2
-R 17
-D 1
-U 15
-R 14
-D 16
-L 1
-R 11
-U 9
-R 8
-U 6
-D 7
-U 7
-L 2
-D 10
-U 9
-D 9
-L 11
-D 11
-L 14
-U 16
-D 11
-L 17
-R 5
-L 13
-U 16
-R 16
-U 18
-D 1
-R 1
-U 13
-R 6
-L 7
-U 11
-D 12
-L 8
-U 17
-D 11
-U 8
-L 14
-U 17
-L 4
-U 18
-D 18
-R 8
-D 13
-L 10
-U 3
-R 9
-L 14
-R 7
-U 14
-R 14
-L 9
-U 5
-R 4
-D 13
-U 10
-D 1
-R 10
-D 4
-R 3
-U 14
-D 10
-U 12
-L 11
-U 9
-L 16
-R 5
-L 14
-D 4
-U 11
-L 2
-R 10
-U 8
-D 9
-L 2
-R 16
-L 1
-R 12
-U 7
-D 11
-U 18
-D 4
-R 8
-U 18
-D 5
-R 15
-U 16
-L 2
-D 15
-U 5
-D 10
-U 18
-L 7
-U 4
-R 2
-U 17
-L 2
-R 3
-D 2
-L 2
-U 3
-R 10
-L 8
-U 4
-L 18
-U 6
-D 11
-R 13
-D 9
-U 10
-L 16
-R 15
-L 4
-D 1
-L 5
-D 7
-U 18
-L 5
-R 7
-L 15
-U 4
-L 6
-U 19
-D 19
-L 2
-R 2
-L 19
-D 9
-L 14
-U 18
-D 12
-R 19
-U 15
-L 16
-U 9
-L 11
-R 5
-L 14
-R 16
-U 19
-D 7
-U 8
-R 6
-U 14
-R 17
-D 9
-L 5
-U 3
-D 9
-U 8
-L 4
-U 12
-D 12
-R 13
-U 3
-R 18
-U 5
-L 12
-U 4
-L 1
-D 14
-R 5
-L 19
-U 17
-R 18
-D 11
-L 4
-U 18
-L 9
--- a/10/10.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-
-const test_input = "10/test_input.txt";
-const input = "10/input.txt";
-
-@enum OpType begin
-    Noop
-    Addx
-end
-
-struct Op
-    type::OpType
-    arg::Int
-end
-
-function parse_line(s::S)::Op where {S<:AbstractString}
-    p = split(s, ' ');
-    if length(p) == 1
-        Op(Noop, 0)
-    else
-        Op(Addx, parse(Int, p[2]))
-    end
-end
-
-function parse_input(io::Iter)::Vector{Op} where {Iter}
-    map(parse_line, eachline(io))
-end
-
-function check_register(interest::Vector{Int}, cycle::Int, reg::Int)::Int
-    if length(interest) == 0
-        return 0;
-    end
-    if cycle == interest[begin]
-        popfirst!(interest);
-        cycle * reg
-    else
-        0
-    end
-end
-
-function evaluate(v::Vector{Op})::Int
-    interest = [20, 60, 100, 140, 180, 220];
-    reg = 1;
-    i = 1;
-    cc = 0;
-    acc = 0;
-    L = length(v);
-    for i = 1:L
-        op = v[i];
-        cc += 1;
-        acc += check_register(interest, cc, reg);
-        if op.type == Noop
-            # pass
-        elseif op.type == Addx
-            # first cycle;
-
-            # second cycle;
-            cc += 1;
-            acc += check_register(interest, cc, reg);
-            # done.
-            reg += op.arg;
-        end
-    end
-    acc
-end
-
-function draw_pixel(crt::Matrix{Bool}, cycle::Int, reg::Int)
-    row, col = (div(cycle, 40)), ((cycle)%40);
-    reg_ = (reg)%40;
-    if abs((col)-reg_) < 2
-        crt[row+1, col+1] = true;
-    end
-end
-
-function draw_crt(v::Vector{Op})::Matrix{Bool}
-    crt = zeros(Bool, 6, 40);
-    cc = 0;
-    reg = 1;
-    L = length(v);
-    for i = 1:L
-        op = v[i];
-        cc += 1;
-        draw_pixel(crt, cc, reg);
-        if op.type == Noop
-            continue
-        elseif op.type == Addx
-            # first cycle;
-
-            # second cycle;
-            cc += 1;
-            # done.
-            reg += op.arg;
-            draw_pixel(crt, cc, reg);
-        end
-    end
-    crt
-end
-
-println("part 1:");
-println("test:");
-open(test_input; read=true) do fh
-    println(evaluate(parse_input(fh)))
-end
-println("input:");
-open(input; read=true) do fh
-    println(evaluate(parse_input(fh)))
-end
-
-println("part 2:");
-println("test:");
-open(test_input; read=true) do fh
-    m = (draw_crt(parse_input(fh)));
-    for r in eachrow(m)
-        println(r);
-    end
-end
-println("input:");
-open(input; read=true) do fh
-    m = (draw_crt(parse_input(fh)));
-    for r in eachrow(m)
-        println(r);
-    end
-end
--- a/10/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-noop
-addx 5
-addx -2
-noop
-noop
-addx 7
-addx 15
-addx -14
-addx 2
-addx 7
-noop
-addx -2
-noop
-addx 3
-addx 4
-noop
-noop
-addx 5
-noop
-noop
-addx 1
-addx 2
-addx 5
-addx -40
-noop
-addx 5
-addx 2
-addx 15
-noop
-addx -10
-addx 3
-noop
-addx 2
-addx -15
-addx 20
-addx -2
-addx 2
-addx 5
-addx 3
-addx -2
-noop
-noop
-noop
-addx 5
-addx 2
-addx 5
-addx -38
-addx 3
-noop
-addx 2
-addx 5
-noop
-noop
-addx -2
-addx 5
-addx 2
-addx -2
-noop
-addx 7
-noop
-addx 10
-addx -5
-noop
-noop
-noop
-addx -15
-addx 22
-addx 3
-noop
-noop
-addx 2
-addx -37
-noop
-noop
-addx 13
-addx -10
-noop
-addx -5
-addx 10
-addx 5
-addx 2
-addx -6
-addx 11
-addx -2
-addx 2
-addx 5
-addx 3
-noop
-addx 3
-addx -2
-noop
-addx 6
-addx -22
-addx 23
-addx -38
-noop
-addx 7
-noop
-addx 5
-noop
-noop
-noop
-addx 9
-addx -8
-addx 2
-addx 7
-noop
-noop
-addx 2
-addx -4
-addx 5
-addx 5
-addx 2
-addx -26
-addx 31
-noop
-addx 3
-noop
-addx -40
-addx 7
-noop
-noop
-noop
-noop
-addx 2
-addx 4
-noop
-addx -1
-addx 5
-noop
-addx 1
-noop
-addx 2
-addx 5
-addx 2
-noop
-noop
-noop
-addx 5
-addx 1
-noop
-addx 4
-addx 3
-noop
-addx -24
-noop
--- a/10/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-addx 15
-addx -11
-addx 6
-addx -3
-addx 5
-addx -1
-addx -8
-addx 13
-addx 4
-noop
-addx -1
-addx 5
-addx -1
-addx 5
-addx -1
-addx 5
-addx -1
-addx 5
-addx -1
-addx -35
-addx 1
-addx 24
-addx -19
-addx 1
-addx 16
-addx -11
-noop
-noop
-addx 21
-addx -15
-noop
-noop
-addx -3
-addx 9
-addx 1
-addx -3
-addx 8
-addx 1
-addx 5
-noop
-noop
-noop
-noop
-noop
-addx -36
-noop
-addx 1
-addx 7
-noop
-noop
-noop
-addx 2
-addx 6
-noop
-noop
-noop
-noop
-noop
-addx 1
-noop
-noop
-addx 7
-addx 1
-noop
-addx -13
-addx 13
-addx 7
-noop
-addx 1
-addx -33
-noop
-noop
-noop
-addx 2
-noop
-noop
-noop
-addx 8
-noop
-addx -1
-addx 2
-addx 1
-noop
-addx 17
-addx -9
-addx 1
-addx 1
-addx -3
-addx 11
-noop
-noop
-addx 1
-noop
-addx 1
-noop
-noop
-addx -13
-addx -19
-addx 1
-addx 3
-addx 26
-addx -30
-addx 12
-addx -1
-addx 3
-addx 1
-noop
-noop
-noop
-addx -9
-addx 18
-addx 1
-addx 2
-noop
-noop
-addx 9
-noop
-noop
-noop
-addx -1
-addx 2
-addx -37
-addx 1
-addx 3
-noop
-addx 15
-addx -21
-addx 22
-addx -6
-addx 1
-noop
-addx 2
-addx 1
-noop
-addx -10
-noop
-noop
-addx 20
-addx 1
-addx 2
-addx 2
-addx -6
-addx -11
-noop
-noop
-noop
--- a/11/11.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-
-const test_input = "11/test_input.txt";
-
-struct Monkey
-    items::Vector{Int}
-    operation::Function
-    test::Function
-    iftrue::Int
-    iffalse::Int
-end
-
-function test_init_monkeys()::Vector{Monkey}
-    # Manual parsing is easier for small numbers of monkeys.
-    [Monkey([79, 98], o -> o*19, i -> i%23 == 0, 2, 3),
-    Monkey([54, 65, 75, 74], o -> o+6, i -> i%19 == 0, 2, 0),
-    Monkey([79, 60, 97], o -> o*o, i -> i%13 == 0, 1, 3),
-    Monkey([74], o -> o+3, i -> i%17 == 0, 0, 1)]
-end
-
-function test_monkeys()::Vector{Monkey}
-    [Monkey([72,97], o->o*13, i->i%19==0, 5, 6),
-     Monkey([55, 70, 90, 74, 95], o->o*o, i->i%7==0, 5, 0),
-     Monkey([74, 97, 66, 57], o->o+6, i->i%17==0, 1, 0),
-     Monkey([86, 54, 53], o->o+2, i->i%13==0, 1, 2),
-     Monkey([50, 65, 78, 50, 62, 99], o->o+3, i->i%11==0, 3, 7),
-     Monkey([90], o->o+4, i->i%2==0, 4, 6),
-     Monkey([88, 92, 63, 94, 96, 82, 53, 53], o->o+8, i->i%5==0, 4, 7),
-     Monkey([70, 60, 71, 69, 77, 70, 98], o->o*7, i->i%3==0, 2, 3)]
-end
-
-function engine(init::Vector{Monkey}; rounds=20)::Vector{Monkey}
-    activity = zeros(Int, length(init));
-    for r = 1:rounds
-        #@show r
-        for (i,m) in enumerate(init)
-            #@show i
-            while length(m.items) > 0
-                activity[i] += 1;
-                it = pop!(m.items);
-                it_ = m.operation(it);
-                it__ = round(Int, it_%(19*7*17*13*11*2*5*3));
-                t = m.test(it__);
-                #println("Inspect item of worry level $it\nNew worry level is $it_\nWorry level div. by 3 is $it__\nThrow item to $(t ? m.iftrue+1 : m.iffalse+1)");
-                if t
-                    @assert m.iftrue+1 != i
-                    push!(init[m.iftrue+1].items, it__);
-                else
-                    @assert m.iffalse+1 != i
-                    push!(init[m.iffalse+1].items, it__);
-                end
-            end
-        end
-        if r % 1000 == 0 || r == 20
-            println(r, " ", activity);
-        end
-    end
-    println(activity, " ", prod(sort(activity)[end-1:end]));
-    init
-end
-
-engine(test_init_monkeys(); rounds=10000);
--- a/11/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-Monkey 0:
-  Starting items: 72, 97
-  Operation: new = old * 13
-  Test: divisible by 19
-    If true: throw to monkey 5
-    If false: throw to monkey 6
-
-Monkey 1:
-  Starting items: 55, 70, 90, 74, 95
-  Operation: new = old * old
-  Test: divisible by 7
-    If true: throw to monkey 5
-    If false: throw to monkey 0
-
-Monkey 2:
-  Starting items: 74, 97, 66, 57
-  Operation: new = old + 6
-  Test: divisible by 17
-    If true: throw to monkey 1
-    If false: throw to monkey 0
-
-Monkey 3:
-  Starting items: 86, 54, 53
-  Operation: new = old + 2
-  Test: divisible by 13
-    If true: throw to monkey 1
-    If false: throw to monkey 2
-
-Monkey 4:
-  Starting items: 50, 65, 78, 50, 62, 99
-  Operation: new = old + 3
-  Test: divisible by 11
-    If true: throw to monkey 3
-    If false: throw to monkey 7
-
-Monkey 5:
-  Starting items: 90
-  Operation: new = old + 4
-  Test: divisible by 2
-    If true: throw to monkey 4
-    If false: throw to monkey 6
-
-Monkey 6:
-  Starting items: 88, 92, 63, 94, 96, 82, 53, 53
-  Operation: new = old + 8
-  Test: divisible by 5
-    If true: throw to monkey 4
-    If false: throw to monkey 7
-
-Monkey 7:
-  Starting items: 70, 60, 71, 69, 77, 70, 98
-  Operation: new = old * 7
-  Test: divisible by 3
-    If true: throw to monkey 2
-    If false: throw to monkey 3
-
--- a/11/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-Monkey 0:
-  Starting items: 79, 98
-  Operation: new = old * 19
-  Test: divisible by 23
-    If true: throw to monkey 2
-    If false: throw to monkey 3
-
-Monkey 1:
-  Starting items: 54, 65, 75, 74
-  Operation: new = old + 6
-  Test: divisible by 19
-    If true: throw to monkey 2
-    If false: throw to monkey 0
-
-Monkey 2:
-  Starting items: 79, 60, 97
-  Operation: new = old * old
-  Test: divisible by 13
-    If true: throw to monkey 1
-    If false: throw to monkey 3
-
-Monkey 3:
-  Starting items: 74
-  Operation: new = old + 3
-  Test: divisible by 17
-    If true: throw to monkey 0
-    If false: throw to monkey 1
--- a/12/12.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-
-import DataStructures: PriorityQueue, enqueue!, dequeue!;
-
-const test_input = "12/test_input.txt";
-const input = "12/input.txt";
-
-const START = -1;
-const END = -2;
-
-const MAX_DIFF = 1;
-
-function read_map(fh::IOStream)::Matrix{Int}
-    lines = readlines(fh);
-    m = zeros(Int, length(lines), length(lines[1]));
-    for (i, line) in enumerate(lines)
-        for (j, char) in enumerate(line)
-            m[i,j] = char - 'a';
-            if char == 'E'
-                m[i,j] = END;
-            elseif char == 'S'
-                m[i,j] = START;
-            end
-        end
-    end
-    m
-end
-
-function find_start_end(m::Matrix{Int})::Tuple{CartesianIndex, CartesianIndex}
-    findnext((==)(START), m, CartesianIndex((1,1))), findnext((==)(END), m, CartesianIndex((1,1)))
-end
-
-function reconstruct_path(parents::Matrix{CartesianIndex{2}}, start::CartesianIndex, endd::CartesianIndex)::Vector{CartesianIndex}
-    v = Vector{CartesianIndex}();
-    current = endd;
-    while current != start 
-        push!(v, current);
-        current = parents[(current)];
-    end
-    reverse!(v);
-    v
-end
-
-function find_path(m::Matrix{Int}; start::Union{Nothing, CartesianIndex}=nothing)::Vector{CartesianIndex}
-    s, e = find_start_end(m);
-    if !isnothing(start)
-        s = start;
-    end
-
-    current_best = zeros(Int, size(m)) .+ 10000;
-    parents = [CartesianIndex((-1,-1)) for i = 1:size(m, 1), j = 1:size(m, 2)];
-    top = PriorityQueue{Tuple{CartesianIndex,Int}, Int}();
-    enqueue!(top, (s, 0), 0);
-
-    valid(x) = x[1] > 0 && x[1] <= size(m, 1) && x[2] > 0 && x[2] <= size(m, 2);
-
-    while length(top) > 0
-        (cb, dist) = dequeue!(top);
-        for mov in [(0,1),(0,-1),(1,0),(-1,0)]
-            nb = cb + CartesianIndex(mov);
-            if !valid(nb)
-                continue
-            end
-            if m[nb] == END && m[cb] >= 24
-                parents[nb] = cb;
-                return reconstruct_path(parents, s, nb)
-            elseif m[nb] == END || (m[nb]-m[cb]) > 1
-                continue;
-            end
-            if current_best[nb] > dist + 1
-                current_best[nb] = dist + 1;
-                parents[nb] = cb;
-                enqueue!(top, (nb, dist + 1), dist + 1);
-            end
-        end
-    end
-    []
-end
-
-function find_any_shortest_path(m::Matrix{Int})::Vector{Int}
-    positions = findall(x -> x == START || x == 0, m);
-    lengths = [length(find_path(m; start=p)) for p in positions];
-    sort!(lengths);
-    lengths
-end
-
-open(input; read=true) do fh
-    m = read_map(fh);
-    for c in eachrow(m)
-        println(c);
-    end
-    @time p = find_path(m);
-    println("PART 1: Path $p with length $(length(p))");
-
-    println("PART 2: All path lengths are $(find_any_shortest_path(m))");
-end
--- a/12/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-abacccaaaacccccccccccaaaaaacccccaaaaaaccccaaacccccccccccccccccccccccccccccccccccccccccccaaaaa
-abaaccaaaacccccccccccaaaaaaccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccaaaaa
-abaaccaaaacccccccccccaaaaacccccaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccaaaaa
-abccccccccccccccccccccaaaaacccaaaaaaaaaaaaaaaacccccccccccccccccccccccccccaaaccccccccccccaaaaa
-abccccccccccccccccccccaacaacccaaaaaaaaccaaaaaccccccccccccccccccccccccccccaaaccccccccccccaccaa
-abcccccccccccccaacccaaaccccccaaaaaaaaaccaaaaaccccccccccccccccccccccccccccccacccccccccccccccca
-abcccccccccccaaaaaaccaaaccacccccaaaaaaacccccccccccccccccccccccccciiiicccccccddddddccccccccccc
-abcccccccccccaaaaaaccaaaaaaaccccaaaaaacccccaacccccccaaaccccccccciiiiiiiicccdddddddddacaaccccc
-abccccccccccccaaaaaaaaaaaaacccccaaaaaaacaaaacccccccaaaacccccccchhiiiiiiiiicddddddddddaaaccccc
-abcccccccccccaaaaaaaaaaaaaacccccccaaacccaaaaaacccccaaaaccccccchhhipppppiiiijjjjjjjddddaaccccc
-abcccccccccccaaaaaaaaaaaaaaccccccccccccccaaaaaccccccaaaccccccchhhpppppppiijjjjjjjjjddeeaccccc
-abcccccccccccccccccaaaaaaaacccccccccccccaaaaaccccccccccccccccchhppppppppppjjqqqjjjjjeeeaacccc
-abccccccccccccccccccaaaaaaaacccccccccccccccaacccccccccccccccchhhpppuuuupppqqqqqqqjjjeeeaacccc
-abcccccccccccccccccccaacccacccccccccccccccccccccccccccccccccchhhopuuuuuuppqqqqqqqjjjeeecccccc
-abacccccccccccccaaacaaaccccccccccccccccccccccccccccaaccccccchhhhoouuuuuuuqvvvvvqqqjkeeecccccc
-abaccccccccccccaaaaaacccccaaccccccccccccccccccccccaaaccccccchhhooouuuxxxuvvvvvvqqqkkeeecccccc
-abaccccccccccccaaaaaacccaaaaaaccccccccccccccccccaaaaaaaaccchhhhooouuxxxxuvyyyvvqqqkkeeecccccc
-abcccccccccccccaaaaacccaaaaaaaccccccccccccccccccaaaaaaaaccjjhooooouuxxxxyyyyyvvqqqkkeeecccccc
-abccccccccccccccaaaaaacaaaaaaaccccccccaaaccccccccaaaaaaccjjjooootuuuxxxxyyyyyvvqqkkkeeecccccc
-abccccccccccccccaaaaaaaaaaaaacccccccccaaaacccccccaaaaaacjjjooootttuxxxxxyyyyvvrrrkkkeeecccccc
-SbccccccccccccccccccaaaaaaaaacccccccccaaaacccccccaaaaaacjjjoootttxxxEzzzzyyvvvrrrkkkfffcccccc
-abcccccccccccaaacccccaaaaaaacaaaccccccaaaccccccccaaccaacjjjoootttxxxxxyyyyyyvvvrrkkkfffcccccc
-abcccccccccaaaaaacccaaaaaacccaaacacccaacccccccccccccccccjjjoootttxxxxyxyyyyyywvvrrkkkfffccccc
-abcccccccccaaaaaacccaaaaaaaaaaaaaaaccaaacaaacccccaacccccjjjnnnttttxxxxyyyyyyywwwrrkkkfffccccc
-abcaacacccccaaaaacccaaacaaaaaaaaaaaccaaaaaaacccccaacaaacjjjnnnntttttxxyywwwwwwwwrrrlkfffccccc
-abcaaaaccccaaaaacccccccccaacaaaaaaccccaaaaaacccccaaaaacccjjjnnnnnttttwwywwwwwwwrrrrllfffccccc
-abaaaaaccccaaaaaccccccaaaaaccaaaaacaaaaaaaaccccaaaaaaccccjjjjinnnntttwwwwwsssrrrrrllllffccccc
-abaaaaaaccccccccccccccaaaaacaaaaaacaaaaaaaaacccaaaaaaacccciiiiinnnntswwwwssssrrrrrlllfffccccc
-abacaaaaccccccccccccccaaaaaacaaccccaaaaaaaaaaccccaaaaaaccccciiiinnnssswwsssssllllllllfffccccc
-abccaaccccccccccccccccaaaaaaccccccccccaaacaaaccccaaccaacccccciiiinnsssssssmmllllllllfffaacccc
-abccccccccccccccccccccaaaaaaccccccccccaaaccccccccaaccccccccccciiinnmsssssmmmmlllllgggffaacccc
-abcccccccccccccccaccccccaaacccccccccccaaccccccccccccccccccccccciiimmmsssmmmmmgggggggggaaacccc
-abcccccccccaaaaaaaaccccccccccccccccccccccccccccaaaaaccccccccccciiimmmmmmmmmgggggggggaaacccccc
-abccccccccccaaaaaaccccccccccccccccccaacccccccccaaaaacccccccccccciiimmmmmmmhhggggcaaaaaaaccccc
-abccccccccccaaaaaacccccccccccccccccaacccccccccaaaaaacccccccccccciihhmmmmhhhhgccccccccaacccccc
-abccccaacaaaaaaaaaaccccccccccccccccaaaccccccccaaaaaaccccccccccccchhhhhhhhhhhaaccccccccccccccc
-abccccaaaaaaaaaaaaaaccccccccccaaccaaaaccccccccaaaaaacccaaacccccccchhhhhhhhaaaaccccccccccccccc
-abcccaaaaaaaaaaaaaaaccccccccaaaaaacaaaacacaccccaaaccccaaaacccccccccchhhhccccaaccccccccccaaaca
-abcccaaaaaacacaaacccccccccccaaaaaaaaaaaaaaacccccccccccaaaacccccccccccaaaccccccccccccccccaaaaa
-abcccccaaaacccaaaccccccccccaaaaaaaaaaaaaaaaccccccccccccaaacccccccccccaaacccccccccccccccccaaaa
-abcccccaacccccaacccccccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaa
--- a/12/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-Sabqponm
-abcryxxl
-accszExk
-acctuvwj
-abdefghi
--- a/13/13.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-using ParserCombinator
-
-List = Delayed()
-IntOrList() = PInt64() | List
-ListElement() = (IntOrList() + Repeat(E",", 0, 1))
-List.matcher = (E"[" + Repeat(ListElement()) + E"]") |> identity
-
-const Element = Union{Int,Vector};
-const IOL = IntOrList();
-
-function any_to_elem(v::Any)::Element
-    if isa(v, Vector)
-        [any_to_elem(e) for e in v]::Vector
-    elseif isa(v, Int)
-        v::Int
-    end
-end
-
-function compare_lists(a::Element, b::Element)::Int
-    if isa(a, Int) && isa(b, Int)
-        a < b ? -1 : (a == b ? 0 : 1)
-    elseif isa(a, Vector) && isa(b, Vector)
-        for (i, (x,y)) in enumerate(zip(a::Vector, b::Vector))
-            c = compare_lists(x, y);
-            if c != 0
-                return c;
-            end
-        end
-        return compare_lists(length(a), length(b));
-    else
-        if isa(a, Int)
-            a = [a];
-        elseif isa(b, Int)
-            b = [b];
-        else
-            error("unknown types: $a vs $b");
-        end
-        return compare_lists(a, b);
-    end
-end
-
-function sort_lists!(e::Vector{Element})
-    sort!(e; lt=(a, b) -> compare_lists(a, b) < 0)
-end
-
-function parse_list(s::String)::Element
-    r = parse_one(s, IOL);
-    any_to_elem(r[1])
-end
-
-function run_file(f::String)
-    open(f; read=true) do fh
-        v = Int[];
-        m1, m2 = parse_list("[[2]]"), parse_list("[[6]]");
-        lists = Element[m1, m2];
-        i = 1;
-        while !eof(fh)
-            l1 = readline(fh);
-            l2 = readline(fh);
-            _sp = readline(fh);
-            a, b = parse_list(l1), parse_list(l2);
-            push!(lists, a, b);
-            if compare_lists(a, b) < 0
-                push!(v, i);
-            end
-            i += 1
-        end
-        @show (v, sum(v))
-
-        sort_lists!(lists);
-        for (i, l) in enumerate(lists)
-            println(i, "  ", l);
-        end
-
-        i, j = findfirst((==)(m1), lists), findfirst((==)(m2), lists);
-        @show (i, j, i*j);
-    end
-end
-
-println("PART 1 TEST");
-@time run_file("13/test_input.txt");
-println("PART 1 INPUT");
-@time run_file("13/input.txt");
--- a/13/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-[[[],[],8,3],[10]]
-[[[[7],[0,4,6,1]],[[2,1,5,3,6],[]],[3,[10,9,1],2,[10,6,10],7],2,7],[5,[3],7,10,[8,[4,7,1,7,8],[],1,[8,6]]],[5,7,[[5,5,7,2,10],[8,7,10,4,7],[9,4,9,9,1]],[[8],8,5,[7,3,4,6,1],1]]]
-
-[[[5,5,[0,7,6,6,0]],[],0,9],[[[0,7,3,10,5],5],7],[10,[],1,[],5]]
-[[4],[2,[10,[5,7,8,7,0]],[4,8,[1,2],[5]],3,9],[[[3,3,3,5,4],5,[],7,[7,3,10,4,0]],9,[3]],[2,0,6,[9,5],8],[[4,[9,8,6],[],5],3,[7,7,[3,3,6],7,[9,4,0,10,6]],10,[]]]
-
-[[2],[3,[[],[1]],[],[0,[10,7]]],[[]],[7,[6],8,[9,0],[2]]]
-[[[[],7,8]]]
-
-[[],[[],8,5],[4,9,[[8,4,7,6,9],[4]],3,[[0,3,4,3,1]]],[3,5,[[0,6,4],5,[1,5,6],6,[8,7,1,7]]],[1]]
-[[8]]
-
-[[],[[3,3,[7,0,9],1],3],[[[10,7,6],8,0,0],10],[[3,4],[0,10,[1,6,1,5,1],[]]],[[[10,10],[9,7,3]],2]]
-[[10,0,4,[1,1,[4,10,5,7],10]],[[],[3,5,[5,5],[],[1,0,4,9]],0],[[]]]
-
-[[[[10,7,1],0],[7,[4,9,3],[0],[]],[],8],[[[6,3,2],[4,6,0]],[4,2,[0,2]]],[[],1,6,2,[2,[10,10,4,9],0,[7,1,0,7,6]]],[9,3]]
-[[[[4,4,2,2],[5,0]]],[5]]
-
-[[],[[5,6,[],[7]]],[7]]
-[[10,6,9],[[9,4],[5,4,4,[2,2,8],5],10,[[]],9],[]]
-
-[[[],[2,6,[],[4],[0,5,6,7,4]],4,9,3],[],[[[6],7,9],[],9],[[[1,5,0,4],4,[2,9,3,3,7]],1],[10,2,2,[[0,6,8,4],[9,3,8,5],3,5,3]]]
-[[],[3],[[[],[],[10,1,2],[],[1]],0,9,[]]]
-
-[[0,[6,[10,0,0,4],[6,6]],[],7,[8,[2,6,8,6,10],5,7,0]]]
-[[[6,[7,6,9]],8,[4,1,[4,7,2]]],[[],8],[[2,[0],0,8],1,8,[6,4,1,[3,3],6],[[9,8,4,1],[5,7],9]],[[[3],5],2,5],[9,[[8],3]]]
-
-[[],[2,[4,[6,2,10,7,7],[]]],[7,[7,[1,7]],[[9,2,8,10,8]]],[5,[[0,10,10]],[1],1,[[],10,0,[]]]]
-[[[[1],[7,10]],5,9,[[],[1,8,7],0,[2],6]],[],[[7,[],6,[],6],[[1],8,0],[[3,0],[0,7],[2,0,3,6],[9,6,0]],[[0,1,7]]],[0,[7,[1],1],4,10]]
-
-[[7,7,[[],[7]],1,[0,10]],[10,4,8,6,5],[7],[[[2,4,8,7]],[[10,1,6],[6],[5,5,6,8],7,[0,5,2,3,4]]]]
-[[[8],[[4,7],[8,10,0,10,8]],0,8,3],[[9],[8],[[1,2],5,0,[7,0],[1,3,10,8]],[0,4,[3,10,0]],[10,[],[]]]]
-
-[[],[8,[9],9,3,7]]
-[[6,8,[5,4,[],[8],3]],[],[8,[4,[9,3,7,1],[7,1,9,5,7],[7,4,5],2],[9]]]
-
-[[[[0,7],1,2,[7],10]],[6,7,6,[[3,7,2,7],[10]],[2,[9,9,5,7],[0,4,4],[5,8,2]]],[2,2,8,2],[[]]]
-[[],[10,[[0,10,1],7,0,9],6],[[4,6,[1,7,9],7,[5,3]]],[2,[[10,10],[8,0,3,8,2],[6]],2,7],[[6,3,4,1,[4,7,7,2]],0,[[1,3]],[[0,9,3,6],0,[5,6,6,0],10]]]
-
-[[[3],0],[1,1,4]]
-[[6,[8,[2,5,2],[6],2],[1,8]],[3,3,7,[[2,10,1,5],[]],1],[[9,[8,6,7,3],[9,9,6]]],[[[],[9],9,6,2],1,[8,10,2],[],3]]
-
-[[[[1],[3],7,[8,0,7],6],3],[],[8]]
-[[6,7,[4,[8,2,1,5],8]]]
-
-[[8,[[],9,[4,6]]],[9,[10,[8,7,4,1,2],[3,3,2,10,7]]],[4,[[4,5,2],8,3,[3,4,10,5]],10,10,[[1,10,4,10]]],[[8],[[5],[6,1,0],2,10,2],3]]
-[[[10,5],[[0],[7,9,3],[2,7,5,2]],[7,10,[8],6],[[6,6,4,5,9],[3],4]]]
-
-[[3,6],[1,[],3,9,[]]]
-[[9,[],6,[],[[3,8],[6],7]],[[],[0,9,5,[9,1,9]]],[[9,10,[8,3,7]]]]
-
-[[],[1]]
-[[0,[],[5,[],5],[[]],2],[5,7,9],[1]]
-
-[[[[9,9,2,9],[0,6,4,5,2],[8,2,2]],[0,7,4]],[5,9,[0]],[[10,[9,5,10,4],5,0]]]
-[[[[9,6]],[],[[9],10,7,4,[9,0]],5]]
-
-[[[[7,2,1,6,6],9,[1,7,8],8],[5,[3,8,8]],[[5,0],[2,1],[3,0],5,[7,7]],[[],[4,6],[4,6,5,4]]]]
-[[7,7]]
-
-[[9,1,[[5,10,6,7],[4,6,5,10,1]],[[4,7,9],5,[6]]],[4,[2,[2,2,5,3]]],[[3,[4]],[],2]]
-[[7,[0,8,0,[10,8,10]],[1],5]]
-
-[[3,6,6,5],[8,[[4,5,6],5,[8,3,0,1],[10,5,2],[5,0,7]],[],4,[[0],[]]],[2,[4,[6,5,6,9,0],[],[3,0,2,9,8],[10,4,9,5,1]],7],[[[7,3,5,2,7],[2,2,5,6,9],[6],0],[8,8,7,[2,1,3,9]]]]
-[[[8,7,[7,4,8]],[]],[],[],[],[2,[[1,8,5,0]]]]
-
-[3,3,5,9]
-[3,3,5,9,6]
-
-[[],[[[],[3,4,0],9,[],1],0,2,[0,[5,2,6,8],[9,4,8,8]]],[[[10,6],[5,6,4,3],[],5,[4]]],[0],[]]
-[[[5,9,7],2,[[2,0,7],[2]],10],[[[9,6],[3],4,[],[9]],0,[[9,5]]],[1,[[10,4,6,9],5,3],1,[10,[9,7,0],[8]]],[[0,[9,7,5,10,4]],0,0,2],[[[]],7,2]]
-
-[[[1,6,2,5,4],7,[8,8,9,9,[6]],[[],7,[],[10]]],[[[1,0,0,5,5],8,5],[[],1]]]
-[[5],[],[[[7,4,8],9,8],2],[10]]
-
-[[10,1],[[[0]],[]],[[5,[9,1,0],[],8,4],1]]
-[[[[10,0],6,[8,6,7],1,2]],[[[7,3,8],[],[],3,[4,0,6]],[10,[6],9],[[9,1],[],[5,1,3],[],2]],[[1,[2,8,6,6],[6,9],[3,8],[4,10,8]]]]
-
-[[[4,10,8,6],5],[8,[[3,4],[2,0,1,10,9],6,[4,10,10,8]],[9,[2,9,7]],[7,[0,9,6,1,0],6,5]],[]]
-[[3,[[1,10,1,1,8],8,[7,6,0],[6,10,5,3],[2,3,2,2,6]]],[]]
-
-[[[],[[1,6,3,8,9],[7,0,2,4,3],[4,5,3,6],3,[2,2,10,9,0]],3]]
-[[],[[[8,8,10],[10,2,7,8],[1,0,7,4],[2,8,8,2],9],8,10,10,1],[[[3,2,6],[0,2,9,9,10]],[6,[],4,0,[5,4]],[[4,1],0,[],3,5],7,2],[]]
-
-[[[0,[7,1,6,4],[2,3,4]],[],[]],[[1,[8,4,2,9],8,9],6,[8,10]],[5,[[3,10]],5,[]]]
-[[0,10,[],1],[],[4,8],[],[]]
-
-[[[5,3,[0,10,1,1],[],[]]],[6,8,[]],[4,2,[2,0,[1],1]],[],[[[4,8,0],[0,7,9,8,6]],[[0,0],[9,10,3]],[[2,4,2],0,2,10],6,[5,[4],[4,2],[2,4,4,0,10]]]]
-[[[[1,9],[10,2,9,2,3],[8,7,4,8,4]],2,[7],[[0,1,5,2],5,5,10,10]],[[1,10,4]],[5,[],[[3,1,3,6],[7,1,9,1],[0,3,8],6,3]]]
-
-[[2,[]],[[[9,0],[3,9,6,10,9],3,3,5]]]
-[[[0,1,[3,9],9]],[[7,[1,10,3,3,3],2,5],2,8],[10,10,[[0,3,8,0],10,[2,4,0,4],3],[[2,6,4,3,1],4,[8,9],[]],[[],[1,5]]]]
-
-[[[],9]]
-[[],[0,5],[[4,8,[10],3,[8,9,4,4,4]]]]
-
-[[[6,[3,1,1,4]]],[0,[9,[9],6],[[],9,[],0,[6]]],[8,[0,9],[2,10],9],[[8,[1,10],[9,0],[6],9],[4,[],[10,10]],[[4,2,8,8,10]]],[[7,[4],[3,8,0,3,0]],1,[8,[2,8,5,2],[0]],[10,[2,0,2,4,6],2],[1]]]
-[[[7,[],5,[8,8,10]],4,[1]],[[7,10,0],3,[7,[3,10],[3,8,5,0,7]]],[6,[[2,5],8,10,[2,8,5,1],[4,7,2,4,0]],2]]
-
-[[4,0,10,1,[[1,6],2,9,10]],[[[3],[3,0,8,9,7],[5,6]],[[4,2,10,8],[1,9,10,6],6],6,[[5],4,[],[],1]]]
-[[4,[],[8,3],9],[[],[0,8,[6,9,6],[10,6]],4]]
-
-[[5,9],[1,5,6]]
-[[3,[8,[0,5,7,4,2],[4,4],[7,10,3,1]],0,4],[[7,[0,8,6]],[[3],[7,9],[],[3,6,4]],2,4]]
-
-[[10,[]]]
-[[],[7,[[0],[10,4,0,1]],3,[[7,0],[1,3],8,[6,0,3,1],1],[10,5,10,9,[]]],[3,6,4,5,3]]
-
-[[],[[[2,8,1,9,8],[7,0,1,10],[9,0,4,7,6],5],4,[]],[]]
-[[0,5,5],[2],[[]],[7,[[1,0],[4,9],5]]]
-
-[[10,5],[],[4,[],3,0],[3,3,9,[]],[]]
-[[],[[[8],[1],7],4,2,[1]],[1,10,5,[2,3]],[[8],[[5,6,6,3,0],[2,1]],3],[2,7,[10,[],[0]]]]
-
-[[[3,5,[5],[8,8,3,7],9]],[],[0,[],0,3,7],[1]]
-[[2],[[[9,9],[0,7],8,[]],5]]
-
-[[4,8,6],[[5,10],[[2],8,[],4],[[10,7,6,5,10],[3,8,7],[3,1,0,2],[8,8,7,1,5],8]],[6,8,0,[[8],4,[1,0,0],2],[[2,7,6,10,1]]],[1,[0,5]],[2,[],[],4,[[4,5,9],[5],4,[1,1,9]]]]
-[[[4,8,4,[5,0,8],10],0,[[10,2]],4,0],[[5],4,5,[[2],[5,6],[1,2],5,6]],[[[3,5,2,8],[7]],[3,[6],[1,4,6,5],[3,0,6,8,2]],9,2,7]]
-
-[[],[],[7,2],[[]]]
-[[6,[[8,6,4,9,0]]],[[5,[9,6,2,4],[],2],5,7,[[1],10,[0],[8,5,4]]]]
-
-[[],[[[7,8,4,9]],[2,[10,5]]]]
-[[0,2,2],[[[8,6,0,9],[],6,8,[6,1,5]],4,4]]
-
-[[7,7,[4,[2,7,6,8,4],[5,9],8,[6]],[1,1,0,2],1]]
-[[[6,1],[],[]],[[5,9,[0]],[[2,7,6],4,[5,10,1,5],[],7]],[[2,[9,0,9,10]]],[6]]
-
-[[3,[3,3,6,[8,0],[6,4]],2,0,[[5,0,4,1],1,[0,7,6,6,7]]]]
-[[],[5]]
-
-[[[[1,10,1,5],[2,1,0,4,10],[4]],[[0,6,3],[4,1,6],9,7],[[7],[5,6,8],5,4,[10]],1,[0,[9,4],9]]]
-[[],[3,[],5],[]]
-
-[[],[[],[3,5,0,7],[1],2,10],[3,[],0,[[9,0],[0,0,2,5,9],[1,6,2,6]]]]
-[[5,[7,7,[1]],[[],3,[2,8,7],[3,9,6]]],[0,[[7,10,1,3,8],5,[5,4,3,1,9],[2]],2,[[5,10]]]]
-
-[[[[10,3,8],8,3,2,[7]],2,[[5,5,2,4],7],6],[7,0,[6,[4,9,9,5],[3,1,6,2,6],5],[1,4,2,9],[8,8,[10,4,10,9],[3],[2]]],[]]
-[[],[[4,6,[7,6]],[],[]],[[[],0,2,[7,4,0,9],[4]],[],0],[]]
-
-[[5,6,[10,[8,10],[],10,[10,0]],[1,[8,4,6,2]]],[],[[[8,10,10,1]],[],[4,[10,9,7],10]],[[],[[1,10,4,0],[]],[6,9,[4,2,4],7,0],[7,[4],[8,0,7,8,4],[3,5,5,3]]]]
-[[[],[[10,0,3,2]],7]]
-
-[[[[],1,[8,5,9]],2,[[1],[9,3,1,2,2],5,2,[]],9,[3,[],[2,1,7],8,[0,1]]],[[[1,6,1,6,5],[2,10,2,1,7],[0,6,0,4,2]],[],3],[8,10],[[[10,2,7],2,7,[]],5],[[6,1],[8,[],[3],[4]],6,8]]
-[[[],10,6,7,[4,9,[9],6]],[[]],[[],[6],8,0],[[[10],[8,8,3,8],8],[7,[]],[]]]
-
-[[[[10,0,8,1],[7,6,6],[6,9,9,0,10],[7,4,3]],[[9,10,3,4]]],[[1,[0,3]]],[5,1,2,[9,[],[0,4,10,10]],9],[[9]],[7,6,8,0]]
-[[[[4],3,2,[]],[9,[],4,6,[5,1]],2,[]],[[6,[6,10],[],[],[6,6,10]],7,[5,7],[[9],4,[6,10,0,3],[]]],[[2,[1,8]],3,[9,[0,6,10]],[],3]]
-
-[[7],[7,[[7,8],[0,7,1,4]]],[10],[10]]
-[[],[],[[[9,3,4,2],[4,5],1,[8,0,7,8,4]],6]]
-
-[[[4,[],[0,0,3,6],2],9,[],7,0],[[],9,[],[],[0,0,1,1,[5,5]]],[3,10,[8],2,[5,[],5,[2,3],5]],[[[10,4,9],[10,9,10,0],[4,7],[10,2]],3,[0,2],10,1]]
-[[[],6,[],[2,5]],[[[7],[6,6],0,5],[4,4,[8],2,[0]],8,[4],1],[],[8,1,9,[10,[9,7,2,0]],[]],[10]]
-
-[[8,[],2],[[[3,9,5,9,2],[2,3,10,6]],[5,[6,5,10,1],[7,9],[2,10,3,7,10],[4,0,9]],9,0],[1,[[7,6,1,4]],10,9],[],[[[3,8,7,7,6],[2,9,4,5],[10,1,5]],3,[6,8]]]
-[[5]]
-
-[[8,0,3],[[[],[2,5,7],3,7,[5,10]],[8,5],0],[7,[[3],[9],0,9],[],[[],8]]]
-[[8,[4,[2,6],2]],[],[[[5,3,7,8,6],[2,9],2,[],[9,4,8]],5],[9,[[7,10,3,10,1]],10,9,0],[[3,7,[0,5],3,3],0]]
-
-[[],[],[1]]
-[[[2,[9,8,0,1,7]],[9,10]],[10,[[],[9,5],10],7,2,1]]
-
-[[4,[7,8,7,[5,5,1,1],0]],[[1,[9],[0,3,0,8],[5,2],1],1],[[[4,5,3],[3,10,3]],5,5,[[8,0]]],[[[],5,[0],3,7]],[[2,[5,4,1,3],[0,7,4,10,2],1,7]]]
-[[0,[[4,0,8,0]],[[2,2,9,4,2],[],[5,4,3,1],6]],[],[8,8,10,10,3],[[2]],[[9,4,10]]]
-
-[[5,[2,0],10],[9,7,[[],8,[8,1,2]]],[[],[[5,10,7,4],[3,1],[7]],7],[7,8,10,2],[[],[]]]
-[[[7,2],10,2]]
-
-[[1],[[5,2],[[10,3,3,8,7],[],2,5]],[],[[[7,4,8],0,[1],8,6]]]
-[[7,10,[9,[0,5],0,[8],0],4,[[6],0]],[],[],[[0,2,[7,4,9]],[3,6,8,[1]],10]]
-
-[[[6,3],[[7],[1,6,3,5],3,[]],[[10,1,1,5],3,[]]],[[[3,4,6,0],[1],[1,10,4]],[],5]]
-[[],[[],[5],[[]],3,6]]
-
-[[4,[1,0],[[10,2],4,[6,1,0],[4,4,3]],[[10,9,4],4,4,[1,9],[7,0,0]],[]],[[8,3,[8,10],4]],[[1,[],0,9,4],3,5,[]]]
-[[[[7,10,0],8],5,[4]],[],[[6,[10],[6,10,7,5,9],7]],[]]
-
-[[],[2,7,[5,[5,7],[3,8,4,3,7],[]]]]
-[[],[7,9]]
-
-[[3,[],[[5,9,7,2,3]],3,3],[[],9,[4,[7,6,9,5,8],7],9,2],[],[[7,[8,9,7,5],3,[5,2,5,9,1],[7,4,3,10]]]]
-[[[[8,5,6,0,0],[9,7],9],[[1],3,1,4,0]]]
-
-[[2],[0,1,0,4,[10,[1,8,7,5],[2,9,3],5]],[0]]
-[[],[[[9,2,9,0,0],[2,9,1,9],[8,4,4]],[[6,5,8],0,[0]],[10,8,[9,9,4,6],8]]]
-
-[[[4]],[5,[9,[6],[0,2],[],0],[[3,4],[3,6],[7,3]],[[9,7,4,7,6],[8,4,1],[8]],[]],[],[6,2,[[5],9,10],8,0]]
-[[7],[5]]
-
-[[5],[[[8,4,7,2,8],[8,7,3],6,[],6],1,[5,[6,5]],7,7],[[10],[],7,[8],[0]]]
-[[[]],[6],[[],8,7,[3],[4]]]
-
-[]
-[[],[[[6,8,0,8],[],8],[[5,1],7,8],1,10,[8]],[3,5,[[9,6,3]]],[[2],3,[[4,9],3,6,2,[1,0,8,5,4]],7]]
-
-[[[8,[7,9,7,4],4],3,[7]],[[[10,2]],4,4,[4,[7,4],[4],1],5]]
-[[[],[[8,3,5,2,7]],[[],5],[],[9,2]],[5,[5,5,[5]],[]],[0,9,9,[]],[[5,4]],[]]
-
-[[0,1,[1],10,4],[[[10,1,8]],9,0],[3,[0,2],0],[9,0,10],[]]
-[[[[2,1,0,0,4],[],0]],[],[0]]
-
-[[7,7,10,[]],[3,[],[[6,10,7,4],0,9,[0]],[[10,2,7,6],[9],8,4,[3,5,6,0]]]]
-[[],[4,[9,6,6,[0,3,1]]]]
-
-[[0,4,[[0,8,6,4],4,7,10],[8,[10],2,8],2],[6,[[6,3,6]],4,10],[2,6],[],[[],[[2,7,1,1],[10,4,7,1],[6,10,4,0]],6]]
-[[[2]],[[[9,4,5,2],5,7,[],[]]],[10,8],[3,8,[6,[0,10,10,0,2]],[[5,6,6,10],7]]]
-
-[[8,[[7,6],[8,1,7]],[],5,2]]
-[[6,7,[2,7,[7,1,8,5,1],1,5],9]]
-
-[[1,[],1],[],[7,[[2,10],8,[8],[10,1,9,4,10],[1,9,5]],[[9,4,9],[2,2,1,3,4],0,[8,3]],7]]
-[[[4,[10,9,9,2],3,9,4],[1,10,4,8,4],6,4],[7,1,[3,3,9]]]
-
-[[[[2],[6,7,4,1],[9,3],1,[5,0,9,4]]],[[[2,5,0,0,1],[3,3],[9,1],9,1],9]]
-[[],[[1,[3,6,7,4,10],[7,2,6,0,6],[7],6],5,5],[[[5]],2],[[[3,9,4,9,4]]]]
-
-[[[3,[3,0,9],9],[[10,9,1,8]],[6,8,[6,7,5,10,4]]],[[[],2,[],[9,3,8],8],[5,0,2,[],[0,9,4,3]],[[],1,8,1,0],[]],[[[4,7,8,6,2],6,9,[1]]],[4]]
-[[[[],8,10,[6,6]],0,0,[10,[],[0,2,8,3,7],[7,5]],[[0,4,0],3,10,2]],[4,[],0,[],6],[[[7,8,0],[7,5,7],[10,4,3],[1,5,2],9]]]
-
-[[],[[[6,10],7,1,0,[]],[[9],[8,9,9,10,8],0,8],2]]
-[[10,0,4,[[0,2,10],[9,2,4,7,7],[5],[9]],[[3,2],[2,9,10],[3]]],[2,1],[10,[5,[2,8,2,4],6,4],4]]
-
-[[8,[[4],[2,9,10,6],0,4,6],[[7,5,3,0],[9],4,[7,5,10,10]],[]],[]]
-[[[[]],1,[[],[10,7,2,1],[6]],6]]
-
-[[[[1,6,7,3],3],[1,[7,0,6],7,4,[7]],[2,5],0],[[],[[4,5,3,4],5],[7]]]
-[[5],[[],[],5,[[8,3,3]],[[],3,8,9]],[[0,[0,2,9],[2]],[[8],4],[[0,3]],[[6,4,4,3,2]],[[0],[],[0,9,10,1],8,8]],[2,[[],[7,7,0]],[[5,7],[8,2,8,1,5]],[[9,2,6],[1,5,9,1]]],[[[2],[]],[8,7,5,[2]],[[2,1,8,1],5,4,6,[0,5,6]]]]
-
-[[],[1,6,10,1],[[8,9,[3,8]],10,7,[[0,8,6,7,10],[7],[1,0],2],9],[[[4,1,0,10],1,4,[8]],0,[4,10,9]],[8]]
-[[[[4,8,9,3],6],5,[],5],[]]
-
-[[[10]],[[],8],[[[6],7,9,[6,6],10],[8,4]]]
-[[8,5,3,[],2],[8,[8,[0,0],5]]]
-
-[[[1,0,[],[8,8,3,2],0],2,2,[10,[7],[2],7]],[10]]
-[[1],[0,[[6,7],[1,10,7,6],[1,8,7,4],10,5],5],[[4,0,[7,0],[8,3,8,6]],[[2,4,10,8,6],3],8,[]],[[4,[9],[7,4,10],[4]],[3,[6,6],[],5],9,[]],[[[6],[2,1,1,3,5],[2,9,3]],6,[[1],[5,7,5]],[[4,3],[8,2,6,4,6],0,5,[5,8]]]]
-
-[[],[[6,[1,0,0,9],1,6],[[4,9],0,1,7,[2,2,10,7,3]],1]]
-[[],[[[4],1,10],[],4,[[9,4],0],[[9],[10,1,10],10,2]],[8,7]]
-
-[[[],7,[[8,4,9,2],[2],4,9]],[[[0],5,[],10,[]],[3,[1,9,9,2],[9,10,0,0]],[7,9,[8,7],2],[9]],[9,[[9,4,6,8,10],8]],[[[0],5],10]]
-[[7],[0,6,[[6],[],3,[3,8,6,2,8],6]],[9,6,0]]
-
-[[[[4,4,7],[6,7,2,2],[]],1,[[],7,0]],[[5],[2,2,[3]],[6,2,4,[]],[[3,8],1,[8,6,0,10,5],[8,10,6,1]],3],[8]]
-[[0],[[10,[],[10,4,7,3,10]],[[5,9],7,5,8],9],[9,0,5,1],[]]
-
-[[0,0,[[6,10,1,5],[8,0,4],10,[10,9,1,5]]],[[4,[2,1,1,5,4],[5],[]]],[3,7,0,[],10]]
-[[3],[4,5],[6,[4,5,[]],5,4]]
-
-[[[[6],6],10],[]]
-[[[],7,[[4,3],[7,3],1],[4,[7,6,6,3,9],[2,2,0,8],2]],[1,5,[[5]],[[0,2,5,2]]],[[[4,8,10,0,3],[6,1,8,1,4]]],[],[1,[[],[],2]]]
-
-[[9,[]],[7,[[3,0,2],[],10,6,[10,7,8,4,6]]]]
-[[7,6]]
-
-[[8],[2],[6,1],[6,[4],[],[4,8,[5,2],5]]]
-[[],[[[1,9,0,1]],3,5,[6,[3,4,3],5,[6,3,7],[2]]],[5,[[3],0],5,[],5],[7,[[9],10],4,9],[]]
-
-[[[9,[8,5,4,8]]],[3,[7,[6],3],2,[5]],[[[1,8],[6,6,5]],6]]
-[[2,[[2]]],[10,6,3],[[[10,4],0],[],[5],[],[0,[10],[1],[1,2,7]]]]
-
-[[[[],[],6,[10]],[],7],[3,[10,9,2,[]]],[5,[[10,10,2,7,0],6,[]],[8,[0,7]],[[0],1,[9,10],4,2],[]],[]]
-[[[9,[5,4,6,9,5],[10]],[[5,9],0,6,5,10],[5,[2],[4,9,4,9,0],[5,4],[0,1,3,6]],3,[[3,9,7],[6,10,0,0]]],[[7,8,10]]]
-
-[[[3,[4,0,0,9,8]],2,0,[6,[5,7]]],[[9],[],4,0],[6,2,[9],[10,[5,4,9,10],6,4]],[9],[6,6,[[7],[6]],[[8,0],5,10]]]
-[[],[8,1,0],[5],[9,5,[6,[6,10,6]]],[]]
-
-[[8,7,[5,1,[4,1,3],[8,1,0,8,2]],3,0],[[[0,1,3,1,1],[9,7,2,4],4,6,4]],[10,5,7,4]]
-[[7,[]]]
-
-[[0,7],[],[],[0,2],[0,2,[5,5,[4,6,3,10,0],0],[[5,1],[8,0],[5,7,5,0],2,4],[8,[],[10,2,3,4,8]]]]
-[[[8],[2,10,6],9,2,[5,[],5,[6,0,4,5,7],5]],[7,1]]
-
-[[[],[[9,7,1,3],[6,3,2,7,6]],[7,[6,9,5,0,9],3],5,[]],[],[[[3],[0,7,1,7]],[0,[10,6,2,10,4],[5,8,0,6,7],0,[]],6,9],[[[4,6,0,0,2],7,[9,7,7,7,0],8],6,[[],[0,3]],8],[[9,[1,10],2],4,[[0,4,10],[4,7,8]],[[2,0,0,9,8],[4,2,9],[5,10],1,[8,4]],3]]
-[[]]
-
-[[[[6]],4,8,[],6]]
-[[],[1,9,[[],9,[10,7,10,9,9],6,[0,10,1,4]]],[3,[8],2,9],[5,[4,7],[4,[8]],5,6],[[0],[10],[]]]
-
-[[[[5,1,10,5],[2,10,6],1,0,1],[[1],3,[],2,7],4,4,6]]
-[[3,[[7,3,0,6],7,[1,4,5]],[[4,7],[0,6,10,2,9],[],[4,2,1,9,7]],[9,10,[10],1,9],[]],[8,[],[3]],[[[3,2,6,1,0],4,[4,9],[3,1],3],[],[[0,4],[4,2]]]]
-
-[[7,5,1,10],[2],[]]
-[[],[[],7,[],9,[[0,9,4],[8,0]]]]
-
-[[3,9,0],[[[9,0,7,4],[1,6],9],10,[3],9,[0,[4,7,4]]]]
-[[5,3,[1,[8],0,9],1],[[[8],8,8,8,[6,7]],4,0,[4,0,9,[3,8,8,8],10]],[[[],7,[8,8,1,5]],8,3,4]]
-
-[[[9,[8],[10,3,10],7],4,3,6,[8]],[[]],[8,[10,10,[]],[4,[6,9,3,10,6],8,10,2]]]
-[[[[3],[5,0,9],[],2,[4,1]],[7,8,3],[10,[1,4]],[[0,7],[6,4],7,[10,0,0,1]]],[[[5,2],1,[10],10,[3,5,6]],[[],[0,6,2],[0,10,0,1,3]],[[],[1,7]],[1]],[],[],[9,[7],2,[[4,5,4,0],[8,1,1]]]]
-
-[[[],3],[3,[],4],[5,4,6,[]]]
-[[2,[8,2,[4]],5,[5,[9,1],[10,6,10]],9],[10,[5,8,[],[5],[]]],[[],1,[1,[7,6,5,0,4],[6],[5,5,10,5,2]],0]]
-
-[3,9,10,6,3]
-[3,9,10,6]
-
-[[1]]
-[[[[],[],[10,8,6]]]]
-
-[[[5],[10,[3,10,4,1],7],5,[3],[]]]
-[[],[[7],[[7,8,5],[6,10,4],9,[0,10,6]]],[[[8]],[5,[],[2],[6,5,0]],[[10,1],10,[],[9,1]],[5,4,[4],[],10],[5,[7],[10],[2,10]]]]
-
-[[2,9,[[9,7],[],[4,6,3],[0,6,10,2,10]],[[6,1,1,1,4]]],[10,4]]
-[[[],[6,8,1]],[[[7]],5,6,[0,2,2,6],[]],[3],[[4],4,5],[1,[[9,10],[1,5],4,[6,7]],0,6]]
-
-[[[7,9],5],[2,[5,9,7,[7,2,9]],[9,[8,7]]],[3,[[],10,4,[7],3]],[1,[[],5,0],5],[[],[[],5,0,4],2]]
-[[[[4,3,0,10,3],[6,1,10],4,8],[8,[],[8,0],10,[]]],[],[1,9,4],[10,8,[5,[9,8]],3]]
-
-[[6,8,[[1,4,10],0,7,[10,5,10]],[[10,8,9]]],[9,[9]],[9,[3,1,[],[1,1],8],7]]
-[[],[5,8],[7,[7],[[3,6,2],6,0,[2,7],[6]],[10,[2,10,8,6],[2],[],[8,10,10,3,4]],[[8,5,8,8,10],7,1,[10,10,8],[3,5,4,3,3]]],[[[],5,10,[1]],4]]
-
-[[4],[10,6]]
-[[0,10,4,[9,10]],[],[1,8],[9,7,[2,[5,4],[10],[7,1]],0]]
-
-[[[],[5,[4,10,2],4,[10,8,10]],[]],[],[4,[4,6]],[[],[2]]]
-[[1,5,[[4,2,5],[],[1,9,4,7],[10,6,2,3]],[[9,2,0]],0]]
-
-[[2,[8,7,[9,0,0,9],[0,8]]],[],[[3,6],[[1,8,0,5,6],5,2],0,6]]
-[[[3],[[1,6,1,10,0],[7],[9,2,0,5,9],[1,10,5,8],[8,6,2,6,5]],5,1],[]]
-
-[[[1],8,3,7,10]]
-[[[[1],[9,2,0,6],6,[5,4,7],[1,9,4]],7,0,[]],[2,4],[[9,9,[10,5,5],6],3,0,[[1,8],[],10,0],10]]
-
-[[10,4,[8,[3,6,1,1],7,10],[],[[2,6,6]]]]
-[[2,4],[[[2,0,8],[2,0,6,8,3]]],[[[5,1],9,[0,4,6,4,4],8,1],[1],9,[],5],[6,4,[[1,5,7],3],[[9]]],[]]
-
-[[],[[[],4,[9,2,9]],[[4,6,3,6]],[1,8,2],7],[[[3,1,5,5],[]],9,6],[0,4,1,6,0]]
-[[[[0,10,1],[2]],2]]
-
-[[[3],[[],4],1,8,2],[[2,[6,10,1,8,0]],0,[8,[],[10,9,7],[]],2],[[[4,4,2,6],[],7],3,8,10,3],[]]
-[[1,[6,3,[8,6,4,4],7],[7,8,[3]],1,2]]
-
-[[2,[0,8],9],[[[0,3,0,4,8],[2],[10,4,1,4]],[],[5],8,5],[0,[6],10,2,[1]]]
-[[9,10,2,[[0,7,5,0],2,[2,10,9,8]],[[6]]]]
-
-[[[4,3]]]
-[[[[8,9,3,3],[],[10,1,3,1,8],8,7]]]
-
-[[[9,[0,1,7,3,4],9,9],[],[8]],[[0,[9],[3,6,3,0],7],[9,4,0,[8,1,2,8],8],[2,8,[4,5]],[8,0,[9,9,7]]],[[0,[8,6,7,7,4],2],[7,[1,2,7],[7]],9,[[4,3,4,2],[1,7,3,1],9],[7,[5],[9,5,10]]],[]]
-[[8,[0,[3,0],4],6,[[8,6,5,3],[4,7],0]],[[3,[7,0,7,2,6]],[[0,0],[],[0,5,0,9,8]]],[]]
-
-[[4,7,[7],6,[8,[]]],[]]
-[[],[[9,[10]],[10]],[9,1,5,[0,7],[9,6,[6,0,4],[10]]],[[[4],[1,0],1],9,3],[[[9],1,[],[7,0],2],3,[[5,10,9],0,3,[7,9,10,5,0],6],[6,3,[],6,[3,3,6]],[[9],[2,1,7]]]]
-
-[[[[0,5,8,5],[5,5,6,3,6],[]]],[5,4,[],[],[[6,4,3,4]]],[[[9,3],[]]],[]]
-[[[7,[3,6,3,8,2]],6,7,9],[6]]
-
-[[5,[[1],[7,4,10,4],4,[8,3,0,2],[]],5,[9,[8,2,10,4,3],5,6,3],6],[[],[3,7,[5,1,2,1]]],[[[2,3,8,5],[0,4,4],10],2,[[1,4,2],5,8,2,3]]]
-[[[[8,6,8,2],[1,8,4,4],7,[5,4,10,7,4]],[[7,2,5]]],[3,10,[6,[1],[]]],[6,[],3],[[[7,0,0],9,4,3]],[0,[1,[],8],7,3]]
-
-[[[1,6,[7,1,3]],[[8],[8,8,9,1,1]],[[6,6,1,3],[2]]],[[],8,[],3],[],[6],[6]]
-[[[[],[],7],[[9,8,7],3],4]]
-
-[[],[9]]
-[[10,[[10,9,9,1,9]],[[5,5,7,0,4]],9,1],[],[[],5,[6,[3],[1],[1,8],[6,3,3,6]],2],[[[3,1,4,3,2]]],[3,[2,[10]]]]
-
-[[1],[[[0,0,10],[9,1,1,1,4],[7,0,5,3],[2,2],8],[[0,4,6,9,5],8],[6,[6,8],7,[],[8,0,6]],[],[[],7]]]
-[[],[[[6,1,9,8,5]],[[1,0,1,4],2,[],3]],[0,2,0,[[8,5,7,4,6],[5],4,[6,5,6,2,0]],10],[6,7]]
-
-[[[],3,6,[4,1,[5,0,5,3],[3,0],5],[1,1,2]],[3,2,[[1,3,7,9],[5]],6],[6,[],5,2],[3]]
-[[[[0,4,5,0],9,3,10,3],[[4,3,4,9,10],[6,1],[8,10,10,4,3],0]]]
-
-[[3,6,4,7],[5,8,0,[[0,6]]],[],[]]
-[[[[],[3,1,0,7,2],3,[10,3,0,2,8]],3],[0,9,0],[[[8,8,0,9,0],[6,0,5]],[[3,4,9],7]],[],[0]]
-
-[[],[[0,1,[4,1,4,2],[6,5,3],[]],1,[9,3,[10,4,5,0,4]],[[5,7],2],[[8,7]]],[8,4,9]]
-[[8,[7,[10],[2,8,10,9,3],[6,5],3]],[5,5,[[3],[]],6,[1,0,7,8]],[7,[6,5]],[],[10,5,4,[2,0,4,[6,10,4,4],[3,3]],8]]
-
-[[[6],[10,[0,2,5,10,9],2],[[],[0],9,[1,0,5,8]]],[3,[[4],[3],3,[1,4,2,0,0],[]],[[8,3,6,10,7],1],[2,2,5,[6],[0,7]]]]
-[[7],[1,3,[1,2,2],2,3],[5]]
-
-[[[[]],0,[[4,6,4]],0],[],[3,[],[1],[10]],[[1,[2,5]],[[7],[6,10,6,6,6],6],[[0,8,5],[4,0,9]]]]
-[[5,8,2,[0,3]],[6,[[6,4],[7,10,9,10,3],2],2,6],[1,[9,[6,4,1,2],8,[10,2,5,9,8],[]],[]],[],[[[8,2,3],9,[5,6,3,3],4,[4,10]],7]]
-
-[[8,[2,0],[10],2,3],[[3]],[[9,[10,9,9,5,7],2],[[],9,[6,8,5]],[10],8,[]]]
-[[7,10,[2,[0,6,4,0,5]],[4]],[[],[],4],[7,[5,10,2,[0,7,3,9,7]],[[7,2,1,3,5],[7,5,3,1,6],3]],[[[1],6]]]
-
-[[],[[7,[],[5,7]],1,7]]
-[[7,5,4,9],[[5],[[8,2],[1,5],3,4,1],[7,10,4,[],0]]]
-
-[[[8,6,[6,3]]],[9,[],[[5,6,0]],[2,[1,10,10,6]]]]
-[[0,0,[[1,1,10,1,3],2,[7,0,6],3]],[],[0,2],[[3],3,5]]
-
-[[[4,7,[10]],[1,4]],[[2,[4,1,6,0,4]],2,[[],[]],9],[6],[[],[9],7,5],[9,10,[7,[6,0,5,1,3]],2,[]]]
-[[4,[],[[5,4],[6,2,3,4],8,[4,3],7],[9,3,3,0],[[],1,6,2,9]]]
-
-[[5],[6,[]],[]]
-[[],[[1,5,[7,0],[2,7,6,1],10]],[]]
-
-[[5,10,3]]
-[[[7,1],[1,[7,5,9,7]],[0,[7,1,7,9,1],[9,2,9,9,1],5,[9]],[[]],[]],[0,[[9,0,3],[3],1,[1],1],9,[10,6,[],[10,9,1,10,10],[2,2,8]]],[[1,7,4],6]]
-
-[[],[]]
-[[[[6,3,9],[5,5,8,10,4],[7,4,9,1,3]],1,6],[[[8,2,4,5],[],[1,7,7]],0]]
-
-[[0,10,[[4,0],4]],[9,[],[4,9,[10,5,8]],7],[10,[]]]
-[[],[[],7]]
-
-[[[6,5],2,8,7,[[6,2,10,1],1,[2,5,10,7],1,[2,10,7,5]]],[6,9,8],[4,[],[[1,8]],1,[7,[1,0,6,8],[8]]],[[],6,1,[7,[],0,[6,7,8,10,5]]],[[],[],[7,9,[5,10,6,3],[2,10,3],8],7,[9,[0,10],[8,2,6,0,1],[10,1]]]]
-[[[9,[0,9,10,7,4]],6,[6,[8,5,9,6,8],[4,10,6],4,[]],[4,9,7,2,7]],[4],[[],[[4,2,5]],[4,[7],[9,5,8,7,7],[],[10,9,6]]],[10,[],10,[4]],[6,1,3,[[2,1],[1,9,7,3],5,[2,3,5,4,9],6],1]]
-
-[[6],[8,5,[4,[1,10]]]]
-[[1,7,5,9],[],[],[0,9,1],[0,[2,6,10,[10,7,3,5,3]]]]
-
-[[3],[1],[]]
-[[0],[8,[[6,7,6],3,7,[4,5,6,10,1],0]],[[[4],[6,0],0,[8],[8,1]],[[1],4,8]],[8]]
-
-[[[[2,3],5],[[4,2,4,10,3],[4,0,9,4,2],4],[2,[1,5,2,6,7],8,[0,5,1,4,8]],[[3,6,7,10],[6,7,4,7],[9,4,10]],[[9],[4,2]]],[]]
-[[[7,8,[8,2,10,2],[],[2]],3,9,0,1],[[[5]],0,7,[[7],2]],[[2,[],[8,5,4,1],9],5,6,[[1,2,8,0],4],[]],[2,[9,[],[10,10],8,[]],1]]
-
-[[],[],[[[5],[9],5,7],5,[]],[[3,[1,2,6,3],9,[3,2,7],0]],[[[5,9],5,[8,1,7]],[1,1,[7,7,8,10]]]]
-[[[[10,0],[0,7,2]],3,[0,3,2,[7,1,9]],[[10],0,[5]],[[2,8,0,5],[7,3],4,10]],[9,[[]],[[],[1,4,4],7,[0,1,6,7,2],[6,9,0,4,4]],[9,[9]],[6,[4,5,0,8],1,[8,3,1,10],[9]]],[7,[[]],[5,[1,9,6]]]]
-
-[[4]]
-[[5],[[2,[10,7,10,9,10],0]]]
-
-[[[],[[1,8,6,1,6],[3,2,1],2,[10,3,7,1,4],0],3,[3]],[9]]
-[[],[],[[8],[[],5,[1,8,7],9,1],[[7,1,2,4,3],7,[5,7,1,6,6],8,2],10],[4,[6,[8,8,6,7]],1,[[],[5,10,3,2,7]]],[1,[],[1,[0],7,[9,0]]]]
-
-[[8],[2,[[9,2,9,9,10],[3,5,3,4]]],[10,[[10,7,10,0]],10,[[2,6],[4,9,6],[3,4,5,0,2],[]],7]]
-[[4],[3],[],[10]]
-
-[[[[0],7,[1,1,10,2,0]],2,[[10,5,10]]],[[[6],[4,4,6]],[3,[]],9,[[8,3,3],[6],[9,5,7,7],8],10],[]]
-[[6],[[[3,10]],[]],[8,10,[],9]]
-
-[[5,5,[],9]]
-[[[[5,6,6,3]],2,[[4],0,7,2]],[[],[[10,5],[],[5],[8,1,0,3,2],3],[[7,3,0],5,0,4,[9,1]]]]
-
-[[],[[2],7,4],[2,9,10],[[[],[7,4,4,7,3]],[]]]
-[[9],[]]
-
-[[[10,5,4,1,8],7,[5],[8]]]
-[[0,10,[]],[],[0,6,[7,[4],[],[9]]],[4]]
-
-[[[8],[10],9,9]]
-[[3,[[1,0,5,1,5]]]]
-
-[[[4,5,10],[7,[10,3,1],[2,6],10],[[6,0,8,9,6],4,[]],[]],[9,[],10]]
-[[],[7],[10,10,[6]],[[[2,4],[6,2,2],0],6],[[[2,3,0,0,2],[6,5,7,2],2,4],6,6]]
-
-[[1],[[]],[[[9,1,9,5],[6],[9,3,5,2,6],9,[]],6,[],[[2],9,[8,3,1,3,1],[3,10,6]],[[0,9,1,8,2]]]]
-[[[8],[[7],[7],5],5,5],[4,[[5,9,10],[]],[[4,7,5,1]],[[10,1,7]],4],[5,[[4,8,4],7,0],[2],[],[8,0,[5,8],[8,5,7,2,8],4]]]
-
-[[[0,[3,3,10],[],[0,9],5]],[[4,[],[7,2,5],[0,7],[0,10]]],[],[[[1,8]],[[9,7]],5,[[9,1,0,1],5,5,5,[10]],[[9,4,6,6],4,4,[2,6,9,4,7]]],[4]]
-[[[[10,8,4,0],[9,10,1]],[],[],[[9,8,4,6],2,9],4],[[2,[6,7,8],10,[],[10,4,3,9]],[5,[9]],5,[6,[10],[7,3,6]],[]],[],[[[5,7],[9,7,7,6,9],[9,10,5],8],[[],3,[0,5,0]],3,6,6],[9,[7]]]
--- a/13/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-[1,1,3,1,1]
-[1,1,5,1,1]
-
-[[1],[2,3,4]]
-[[1],4]
-
-[9]
-[[8,7,6]]
-
-[[4,4],4,4]
-[[4,4],4,4,4]
-
-[7,7,7,7]
-[7,7,7]
-
-[]
-[3]
-
-[[[]]]
-[[]]
-
-[1,[2,[3,[4,[5,6,7]]]],8,9]
-[1,[2,[3,[4,[5,6,0]]]],8,9]
--- a/14/14.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-
-mutable struct PS
-    s::String
-    pos::Int
-end
-
-function initialize(s::String)::PS
-    PS(s, 1)
-end
-
-function parse_coord(ps::PS)::Tuple{Int,Int}
-    e = findfirst((==)(','), ps.s[ps.pos:end])
-    x = parse(Int, ps.s[ps.pos:ps.pos+e-2]);
-    ps.pos = ps.pos + e;
-    e = something(findfirst((==)(' '), ps.s[ps.pos:end]), length(ps.s)-ps.pos+2);
-    y = parse(Int, ps.s[ps.pos:ps.pos+e-2]);
-    ps.pos = ps.pos + e - 1;
-    (x, y)
-end
-
-function parse_sep(ps::PS)::Bool
-    if ps.pos >= length(ps.s)
-        false
-    else
-        @assert ps.s[ps.pos:ps.pos+3] == " -> "
-        ps.pos += 4;
-        true
-    end
-end
-
-function parse_coords(ps::PS)::Vector{Tuple{Int,Int}}
-    poss = Vector{Tuple{Int,Int}}();
-    while true
-        push!(poss, parse_coord(ps));
-        if !parse_sep(ps)
-            break
-        end
-    end
-    poss
-end
-
-function parse_all_coords(fh::IOStream)::Vector{Vector{Tuple{Int,Int}}}
-    vs = Vector{Vector{Tuple{Int,Int}}}();
-    for l in eachline(fh)
-        push!(vs, parse_coords(initialize(l)));
-    end
-    vs
-end
-
-const EMPTY = 0;
-const ROCK = 1;
-const SAND = 2;
-
-function run_matrix_2(v::Vector{Vector{Tuple{Int,Int}}})
-    SAND_POINT = (500,0)
-    minx = min(SAND_POINT[1], minimum(minimum(t[1] for t in vv) for vv in v));
-    maxx = max(SAND_POINT[1], maximum(maximum(t[1] for t in vv) for vv in v));
-    miny = min(SAND_POINT[2], minimum(minimum(t[2] for t in vv) for vv in v));
-    maxy = max(SAND_POINT[2], maximum(maximum(t[2] for t in vv) for vv in v));
-
-    maxx += div((maxy-miny)+1, 1);
-    minx -= div((maxy-miny)+1, 1);
-
-    m = zeros(Int8, maxx-minx+1, maxy-miny+1+2);
-    m[begin:end, end] .= ROCK;
-
-    for line in v
-        last = line[1];
-        for p in @view line[2:end]
-            a, b = CartesianIndex(last .- (minx-1, miny-1)), CartesianIndex(p .- (minx-1, miny-1));
-            @assert abs(last[1]-p[1]) == 0 || abs(last[2]-p[2]) == 0
-            if a > b
-                a, b = b, a;
-            end
-            m[a:b] .= ROCK;
-            last = p;
-        end
-    end
-
-
-    show_cave(m);
-
-    # part 2
-    println(" === PART 2 === ");
-    pos0 = SAND_POINT .- (minx-1, miny-1);
-    down, left, right = (0,1), (-1,1), (1,1);
-    X, Y = size(m);
-    isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
-
-    count = 0;
-    pos = pos0;
-    while true
-        if m[CartesianIndex(pos .+ down)] == EMPTY
-            pos = pos .+ down;
-            continue;
-        elseif m[CartesianIndex(pos .+ left)] == EMPTY
-            pos = pos .+ left;
-            continue
-        elseif m[CartesianIndex(pos .+ right)] == EMPTY
-            pos = pos .+ right;
-            continue;
-        else
-            count += 1;
-            if pos == pos0
-                break;
-            end
-            m[CartesianIndex(pos)] = SAND;
-            println(" ==== $count ==== ");
-            pos = pos0;
-            continue;
-        end
-    end
-    show_cave(m);
-    @show count;
-end
-
-function run_matrix(v::Vector{Vector{Tuple{Int,Int}}})
-    # Not very efficient...
-    SAND_POINT = (500,0)
-    minx = min(SAND_POINT[1], minimum(minimum(t[1] for t in vv) for vv in v));
-    maxx = max(SAND_POINT[1], maximum(maximum(t[1] for t in vv) for vv in v));
-    miny = min(SAND_POINT[2], minimum(minimum(t[2] for t in vv) for vv in v));
-    maxy = max(SAND_POINT[2], maximum(maximum(t[2] for t in vv) for vv in v));
-
-    m = zeros(Int8, maxx-minx+1, maxy-miny+1);
-
-    for line in v
-        last = line[1];
-        for p in @view line[2:end]
-            a, b = CartesianIndex(last .- (minx-1, miny-1)), CartesianIndex(p .- (minx-1, miny-1));
-            @assert abs(last[1]-p[1]) == 0 || abs(last[2]-p[2]) == 0
-            if a > b
-                a, b = b, a;
-            end
-            m[a:b] .= ROCK;
-            last = p;
-        end
-    end
-
-    M0 = copy(m);
-    down, left, right = (0,1), (-1,1), (1,1);
-    X, Y = size(m);
-    isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
-
-    count = 0;
-    pos0 = SAND_POINT .- (minx-1, miny-1);
-    pos = pos0;
-    while true
-        if !isvalid(pos .+ down)
-            break;
-        elseif m[CartesianIndex(pos .+ down)] == EMPTY
-            pos = pos .+ down;
-            continue;
-        elseif !isvalid(pos .+ left)
-            break;
-        elseif m[CartesianIndex(pos .+ left)] == EMPTY
-            pos = pos .+ left;
-            continue
-        elseif !isvalid(pos .+ right)
-            break;
-        elseif m[CartesianIndex(pos .+ right)] == EMPTY
-            pos = pos .+ right;
-            continue;
-        else
-            count += 1;
-            m[CartesianIndex(pos)] = SAND;
-            println(" ==== $count ==== ");
-            pos = pos0;
-            continue;
-        end
-    end
-    show_cave(m);
-    @show count;
-end
-
-function show_cave(m::Matrix{Int8})
-    for r in eachrow(m')
-        println(r);
-    end
-end
-
-open("14/test_input.txt"; read=true) do fh
-    ac = (parse_all_coords(fh));
-    run_matrix(ac);
-    run_matrix_2(ac);
-end
--- a/14/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-506,104 -> 511,104
-504,96 -> 509,96
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-499,35 -> 504,35
-511,23 -> 516,23
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-503,38 -> 508,38
-520,104 -> 525,104
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-499,28 -> 499,29 -> 513,29 -> 513,28
-504,23 -> 509,23
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-499,28 -> 499,29 -> 513,29 -> 513,28
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-508,98 -> 513,98
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-507,20 -> 512,20
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-510,127 -> 514,127
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-492,104 -> 497,104
-492,35 -> 497,35
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-528,127 -> 532,127
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-516,127 -> 520,127
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-495,32 -> 500,32
-493,14 -> 505,14 -> 505,13
-522,127 -> 526,127
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-493,14 -> 505,14 -> 505,13
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-525,125 -> 529,125
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-513,104 -> 518,104
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-519,121 -> 523,121
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-495,102 -> 500,102
-500,20 -> 505,20
-490,42 -> 504,42 -> 504,41
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-509,102 -> 514,102
-513,125 -> 517,125
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-490,42 -> 504,42 -> 504,41
-498,100 -> 503,100
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-489,38 -> 494,38
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-496,38 -> 501,38
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-519,125 -> 523,125
-501,154 -> 501,155 -> 507,155
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-499,104 -> 504,104
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-501,154 -> 501,155 -> 507,155
-503,17 -> 508,17
-516,123 -> 520,123
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-505,100 -> 510,100
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
-506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
-516,102 -> 521,102
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-522,123 -> 526,123
-485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-499,28 -> 499,29 -> 513,29 -> 513,28
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-512,100 -> 517,100
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-497,23 -> 502,23
-524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
-489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-501,98 -> 506,98
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
-502,102 -> 507,102
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
-487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
--- a/14/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-498,4 -> 498,6 -> 496,6
-503,4 -> 502,4 -> 502,9 -> 494,9
--- a/15/15.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-
-using ParserCombinator
-
-const Line = E"Sensor at x=" + PInt64() + E", y=" + PInt64() + E": closest beacon is at x=" + PInt64() + E", y=" + PInt64() + Eos();
-
-struct Point
-    x::Int
-    y::Int
-end
-
-function distance(p::Point, q::Point)::Int
-    abs(p.x-q.x) + abs(p.y-q.y)
-end
-
-struct Beacon
-    sensor::Point
-    beacon::Point
-    dist::Int
-end
-
-function parse_line(s::String)::Beacon
-    es = parse_one(s, Line);
-    p, q = Point(es[1]::Int, es[2]::Int), Point(es[3]::Int, es[4]::Int)
-    Beacon(p, q, distance(p, q))
-end
-
-function parse_lines(f::String)::Vector{Beacon}
-    v = Vector{Beacon}();
-    open(f; read=true) do fh
-        for l in eachline(fh)
-            push!(v, parse_line(l));
-        end
-    end
-    v
-end
-
-function point_is_within_closest(p::Point, b::Beacon)::Bool
-    distance(p, b.sensor) <= b.dist && p != b.beacon
-end
-
-function point_is_beacon(p::Point, bs::Vector{Beacon})::Bool
-    any(b -> b.beacon == p, bs)
-end
-
-function point_is_covered(p::Point, bs::Vector{Beacon}; ignorebeacon=false)::Bool
-    any(b -> point_is_within_closest(p, b), bs)
-end
-
-function n_covered_points(bs::Vector{Beacon}, y::Int)::Int
-    minx = minimum(min(b.sensor.x, b.beacon.x)-b.dist for b in bs);
-    maxx = maximum(max(b.sensor.x, b.beacon.x)+b.dist for b in bs);
-
-    count = sum(point_is_covered(Point(x, y), bs) for x = minx:maxx);
-    count
-end
-
-function find_distress_beacon(bs::Vector{Beacon}, minc=0, maxc=20)::Set{Point}
-    # Check borders of sensor's coverage area - as there is only one point to check,
-    # it must be directly outside a sensor's coverage area.
-    v = Set{Point}();
-    isvalid(p) = p.x >= minc && p.x <= maxc && p.y >= minc && p.y <= maxc;
-    for b in bs
-        @show b
-        for x = b.sensor.x-b.dist:b.sensor.x+b.dist
-            for dir = [-1, 1]
-                y = dir*b.sensor.y + abs(b.dist - abs(b.sensor.x-x));
-                p = Point(x+sign(x-b.sensor.x), y);
-                if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
-                    push!(v, p);
-                    continue;
-                end
-                if x == b.sensor.x
-                    p = Point(x, y+dir);
-                    if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
-                        push!(v, p);
-                        continue;
-                    end
-                end
-            end
-        end
-    end
-    v
-end
-
-function tuning_frequency(p::Point)::Int
-    p.x*4000000+p.y
-end
-
-bs = parse_lines("15/input.txt");
-println(n_covered_points(bs, 2000000));
-db = find_distress_beacon(bs, 0, 4000000);
-@show (db, map(tuning_frequency, collect(db)))
-
-bs = parse_lines("15/test_input.txt");
-println(n_covered_points(bs, 10));
-db = find_distress_beacon(bs);
-@show (db, map(tuning_frequency, collect(db)))
--- a/15/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-Sensor at x=3391837, y=2528277: closest beacon is at x=3448416, y=2478759
-Sensor at x=399473, y=1167503: closest beacon is at x=1188862, y=2000000
-Sensor at x=3769110, y=2896086: closest beacon is at x=4076658, y=2478123
-Sensor at x=900438, y=3835648: closest beacon is at x=-435606, y=3506717
-Sensor at x=2913762, y=3937542: closest beacon is at x=2964244, y=3612685
-Sensor at x=3646459, y=3446878: closest beacon is at x=3264675, y=3635510
-Sensor at x=1182092, y=2135147: closest beacon is at x=1188862, y=2000000
-Sensor at x=3213897, y=2710772: closest beacon is at x=3448416, y=2478759
-Sensor at x=3242113, y=3984214: closest beacon is at x=3264675, y=3635510
-Sensor at x=2809237, y=3782833: closest beacon is at x=2872059, y=3592616
-Sensor at x=2962421, y=37354: closest beacon is at x=3358601, y=-1111474
-Sensor at x=3456740, y=2458922: closest beacon is at x=3448416, y=2478759
-Sensor at x=1799203, y=3569221: closest beacon is at x=2872059, y=3592616
-Sensor at x=3907873, y=3898376: closest beacon is at x=3264675, y=3635510
-Sensor at x=3481951, y=2453964: closest beacon is at x=3448416, y=2478759
-Sensor at x=1120077, y=2963237: closest beacon is at x=1188862, y=2000000
-Sensor at x=2901181, y=3029961: closest beacon is at x=2872059, y=3592616
-Sensor at x=3111105, y=3361570: closest beacon is at x=2964244, y=3612685
-Sensor at x=2533601, y=3956413: closest beacon is at x=2872059, y=3592616
-Sensor at x=108898, y=2275290: closest beacon is at x=1188862, y=2000000
-Sensor at x=3501591, y=2414995: closest beacon is at x=3448416, y=2478759
-Sensor at x=3035657, y=3700769: closest beacon is at x=2964244, y=3612685
-Sensor at x=1286795, y=298997: closest beacon is at x=308571, y=-434280
-Sensor at x=200812, y=3470019: closest beacon is at x=-435606, y=3506717
-Sensor at x=2550124, y=1556776: closest beacon is at x=1188862, y=2000000
-Sensor at x=3955070, y=601908: closest beacon is at x=4076658, y=2478123
-Sensor at x=3565419, y=2355172: closest beacon is at x=3448416, y=2478759
--- a/15/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Sensor at x=2, y=18: closest beacon is at x=-2, y=15
-Sensor at x=9, y=16: closest beacon is at x=10, y=16
-Sensor at x=13, y=2: closest beacon is at x=15, y=3
-Sensor at x=12, y=14: closest beacon is at x=10, y=16
-Sensor at x=10, y=20: closest beacon is at x=10, y=16
-Sensor at x=14, y=17: closest beacon is at x=10, y=16
-Sensor at x=8, y=7: closest beacon is at x=2, y=10
-Sensor at x=2, y=0: closest beacon is at x=2, y=10
-Sensor at x=0, y=11: closest beacon is at x=2, y=10
-Sensor at x=20, y=14: closest beacon is at x=25, y=17
-Sensor at x=17, y=20: closest beacon is at x=21, y=22
-Sensor at x=16, y=7: closest beacon is at x=15, y=3
-Sensor at x=14, y=3: closest beacon is at x=15, y=3
-Sensor at x=20, y=1: closest beacon is at x=15, y=3
--- a/16/16.jl	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-
-using ParserCombinator
-
-const PValveList = (E"s " + Repeat(p"[A-Z]{2}" + Repeat(E", ", 0, 1)) + Eos()) | (E" " + p"[A-Z]{2}" + Eos());
-const PValveSpec = E"Valve " + p"[A-Z]{2}" + E" has flow rate=" + PInt64() + P"; tunnels? leads? to valve" + PValveList;
-
-struct ValveSpec
-    name::String
-    flowrate::Int
-    tunnels::Vector{String}
-end
-
-function parse_valve_line(s::String)::ValveSpec
-    vs = parse_one(s, PValveSpec);
-    ValveSpec(String(vs[1]), vs[2]::Int, [String(s) for s in vs[3:end]])
-end
-
-struct Peer
-    valve::ValveSpec
-    dist::Int
-end
-
-struct Node
-    valve::ValveSpec
-    routes::Dict{String, Peer}
-end
-
-function build_graph(lines::IOStream)::Dict{String,Node}
-    l = [Node(parse_valve_line(s), Dict()) for s in eachline(lines)];
-    Dict(n.valve.name => n for n in l)
-end
-
-function update_connections(neigh::Node, dist::Int, mine::Dict{String, Peer})::Int
-    count = 0;
-    for (s, p) = mine
-        if s == neigh.valve.name
-            continue
-        end
-        if !(s in keys(neigh.routes)) || neigh.routes[s].dist > p.dist+dist
-            pp = Peer(p.valve, p.dist+dist);
-            neigh.routes[s] = pp;
-            count += 1;
-        end
-    end
-    count
-end
-
-function populate_graph(g::Dict{String,Node})
-    for (id, valve) in g
-        for neigh in valve.valve.tunnels
-            # Insert neighbors with distance = 1.
-            valve.routes[neigh] = Peer(g[neigh].valve, 1);
-        end
-    end
-
-    count = 1;
-    # While information propagates through the graph, keep updating.
-    while count > 0
-        count = 0;
-        for (id, node) = g
-            for (id2, node2) = node.routes
-                if id == id2
-                    continue
-                end
-                count += update_connections(g[id2], node2.dist, node.routes);
-            end
-        end
-        @show count
-    end
-end
-
-# Sort key
-"""Return the total flow expected for node `node`, assuming it is opened at `time`, and the best path from it
-is followed (this works recursively).
-"""
-function expected_total_flow(time::Int, node::Node, g::Dict{String,Node}, opened::Vector{String}=[]; level=-1)::Tuple{String,Int,Int}
-    if level == 0
-        return ("", -1, -1);
-    end
-    if in(node.valve.name, opened)
-        return ("", -1, -1);
-    end
-    self = (30 - time - 1) * node.valve.flowrate;
-    push!(opened, node.valve.name);
-    opts = [(vn, p.dist, expected_total_flow(time+1+p.dist, g[vn], g, opened; level=level-1)[3]) for (vn, p) in node.routes if p.valve.flowrate > 0];
-    pop!(opened);
-    _, bestix = findmax(t -> t[3], opts);
-    (opts[bestix][1], opts[bestix][2], opts[bestix][3]+self)
-end
-
-"""
-Starting at AA, check which node is best by exploring all possible paths up to a certain depth,
-visiting nodes by preference.
-"""
-function trace_best_path(g::Dict{String,Node}; init="AA")
-    opened = String[];
-    active_pressure_relief = 0;
-    pressure_relieved = 0;
-    time = 0;
-    last = init;
-    while length(g) > length(opened)
-        @show (time, last, opened)
-        next, dist, score = expected_total_flow(time, g[last], g, opened; level=7);
-        @show (next, dist, score);
-
-        if in(next, opened)
-            break;
-        end
-
-        pressure_relieved += (dist+1) * active_pressure_relief;
-        println("Relieving $(dist+1) x $active_pressure_relief...");
-        active_pressure_relief += g[next].valve.flowrate;
-
-        push!(opened, last);
-        last = next;
-        time += dist + 1;
-    end
-    pressure_relieved += (30 - time) * active_pressure_relief;
-    println("Relieving $(30-time) x $active_pressure_relief...");
-    println("Total relief: $pressure_relieved");
-end
-
-function print_graph(g::Dict{String,Node})
-    for (id, n) = g
-        println("=== $id === ");
-        println(" flowrate: $(n.valve.flowrate)");
-        println(" neighbors:");
-        for (id2, neigh) = n.routes
-            println("   $id2 => $(neigh.dist)");
-        end
-    end
-end
-
-open("16/test_input.txt"; read=true) do fh
-    g = build_graph(fh);
-    populate_graph(g);
-    @time trace_best_path(g);
-end
-
-open("16/input.txt"; read=true) do fh
-    g = build_graph(fh);
-    @time populate_graph(g);
-    @time trace_best_path(g);
-end
--- a/16/input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-Valve JZ has flow rate=0; tunnels lead to valves IR, LY
-Valve KD has flow rate=0; tunnels lead to valves NJ, ZS
-Valve VW has flow rate=0; tunnels lead to valves IT, VH
-Valve HS has flow rate=0; tunnels lead to valves OC, PN
-Valve EU has flow rate=19; tunnel leads to valve GQ
-Valve XF has flow rate=0; tunnels lead to valves WL, QD
-Valve DD has flow rate=8; tunnels lead to valves GQ, YY, JV, SK
-Valve TA has flow rate=0; tunnels lead to valves NJ, VJ
-Valve IR has flow rate=9; tunnels lead to valves JZ, WI, VJ, GC, WG
-Valve SS has flow rate=17; tunnels lead to valves SI, IZ, RK, WI
-Valve SG has flow rate=0; tunnels lead to valves NV, NJ
-Valve IT has flow rate=0; tunnels lead to valves LL, VW
-Valve CP has flow rate=24; tunnels lead to valves HN, ZK, EJ
-Valve SK has flow rate=0; tunnels lead to valves LL, DD
-Valve IS has flow rate=0; tunnels lead to valves AA, LL
-Valve HN has flow rate=0; tunnels lead to valves FF, CP
-Valve VH has flow rate=10; tunnels lead to valves QO, VW, RV, PN
-Valve JV has flow rate=0; tunnels lead to valves DD, RK
-Valve ZS has flow rate=0; tunnels lead to valves KD, LL
-Valve UC has flow rate=25; tunnels lead to valves JD, IV
-Valve WI has flow rate=0; tunnels lead to valves SS, IR
-Valve UR has flow rate=0; tunnels lead to valves QD, LY
-Valve GC has flow rate=0; tunnels lead to valves AA, IR
-Valve YY has flow rate=0; tunnels lead to valves DD, AA
-Valve IV has flow rate=0; tunnels lead to valves ZK, UC
-Valve BM has flow rate=0; tunnels lead to valves SA, WL
-Valve JD has flow rate=0; tunnels lead to valves IZ, UC
-Valve WL has flow rate=12; tunnels lead to valves EF, BM, EJ, XF
-Valve AA has flow rate=0; tunnels lead to valves NV, YY, GC, IS, QO
-Valve WG has flow rate=0; tunnels lead to valves LL, IR
-Valve GQ has flow rate=0; tunnels lead to valves EU, DD
-Valve SI has flow rate=0; tunnels lead to valves SS, NJ
-Valve KH has flow rate=13; tunnels lead to valves SA, ON
-Valve PC has flow rate=22; tunnel leads to valve ON
-Valve QD has flow rate=14; tunnels lead to valves XF, UR
-Valve IZ has flow rate=0; tunnels lead to valves SS, JD
-Valve QO has flow rate=0; tunnels lead to valves AA, VH
-Valve SA has flow rate=0; tunnels lead to valves BM, KH
-Valve NV has flow rate=0; tunnels lead to valves AA, SG
-Valve ZK has flow rate=0; tunnels lead to valves CP, IV
-Valve ON has flow rate=0; tunnels lead to valves PC, KH
-Valve PN has flow rate=0; tunnels lead to valves HS, VH
-Valve RV has flow rate=0; tunnels lead to valves NJ, VH
-Valve RK has flow rate=0; tunnels lead to valves SS, JV
-Valve OC has flow rate=18; tunnel leads to valve HS
-Valve EF has flow rate=0; tunnels lead to valves LY, WL
-Valve VJ has flow rate=0; tunnels lead to valves TA, IR
-Valve LL has flow rate=5; tunnels lead to valves ZS, IT, SK, IS, WG
-Valve FF has flow rate=0; tunnels lead to valves HN, LY
-Valve LY has flow rate=21; tunnels lead to valves EF, FF, UR, JZ
-Valve EJ has flow rate=0; tunnels lead to valves WL, CP
-Valve NJ has flow rate=6; tunnels lead to valves RV, KD, SG, SI, TA
--- a/16/test_input.txt	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
-Valve BB has flow rate=13; tunnels lead to valves CC, AA
-Valve CC has flow rate=2; tunnels lead to valves DD, BB
-Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
-Valve EE has flow rate=3; tunnels lead to valves FF, DD
-Valve FF has flow rate=0; tunnels lead to valves EE, GG
-Valve GG has flow rate=0; tunnels lead to valves FF, HH
-Valve HH has flow rate=22; tunnel leads to valve GG
-Valve II has flow rate=0; tunnels lead to valves AA, JJ
-Valve JJ has flow rate=21; tunnel leads to valve II
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/01/01.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,40 @@
+
+const input = "01/input.txt"
+
+function count_calories(data::Vector{Vector{Int}})::Int
+    reduced = [sum(v) for v in data];
+    maximum(reduced)
+end
+
+function top_three(data::Vector{Vector{Int}})::Int
+    reduced = [sum(v) for v in data];
+    sort!(reduced);
+    sum(reduced[end-2:end])
+end
+
+function parse_input(filehandle::IO)::Vector{Vector{Int}}
+    input = Vector{Vector{Int}}();
+    while true
+        current = Vector{Int}();
+        while true
+            line = readline(filehandle);
+            if isempty(line)
+                break;
+            end
+            push!(current, parse(Int, line));
+        end
+        if length(current) == 0
+            break
+        end
+        push!(input, current);
+    end
+    input
+end
+
+function run_01(f::String)::Tuple{Int,Int}
+    input = open(f; read=true) do fh
+        parse_input(fh)
+    end;
+    count_calories(input), top_three(input)
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/01/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,2264 @@
+17034
+
+13495
+7368
+13905
+
+68034
+
+7796
+10348
+5088
+8836
+
+15061
+1842
+7047
+
+2477
+6629
+7998
+4235
+6505
+2875
+6059
+9423
+5315
+
+4054
+6388
+5278
+4163
+10438
+10821
+2650
+
+6424
+2420
+10363
+4275
+1876
+6357
+6364
+
+5123
+1271
+3991
+2792
+2513
+4890
+2900
+7820
+6020
+4612
+3109
+
+9072
+18898
+13848
+11609
+
+1793
+1434
+2288
+4573
+5087
+7366
+3233
+3052
+5754
+1418
+6255
+
+5372
+2497
+2289
+6782
+4154
+5081
+5984
+3164
+4111
+2951
+6928
+1798
+6525
+
+19803
+23713
+7818
+
+7662
+2324
+8206
+5409
+8225
+5513
+2664
+3870
+1428
+5189
+
+5603
+8006
+1486
+1469
+5413
+5638
+2242
+8559
+6333
+1389
+
+4187
+2794
+1067
+1632
+1679
+4572
+5964
+1170
+4199
+5612
+6321
+6658
+3737
+
+2093
+2221
+4741
+5892
+3781
+4034
+1030
+1542
+1547
+5429
+1896
+1371
+4041
+2522
+
+15827
+1404
+8514
+8983
+6878
+
+56181
+
+11350
+12192
+12659
+9552
+14896
+
+5308
+6289
+5069
+3594
+1499
+1034
+5546
+3430
+2292
+2825
+4427
+2315
+2738
+
+5102
+3295
+6423
+1653
+6199
+2459
+1569
+6588
+5691
+4490
+7235
+
+6470
+9298
+10054
+6316
+1773
+6657
+4398
+4420
+
+25785
+1283
+
+9366
+10257
+3221
+2899
+7247
+4711
+
+4108
+6265
+4824
+6589
+2869
+4826
+5853
+1770
+5627
+6581
+2591
+2107
+
+1300
+1774
+9933
+6743
+11425
+8454
+8080
+
+1292
+6230
+1017
+5895
+2718
+6219
+5511
+7161
+1201
+4493
+
+3268
+1306
+5417
+4691
+13018
+13021
+
+9165
+12000
+7531
+10585
+2802
+10764
+2744
+
+8261
+4961
+3019
+3309
+6632
+7955
+3538
+7392
+
+2730
+4479
+1909
+6013
+5214
+1188
+5074
+1589
+1103
+1393
+1745
+4162
+4231
+4197
+3307
+
+1246
+5200
+2648
+6419
+5659
+7380
+4479
+4589
+4108
+7290
+5514
+4406
+
+4256
+5658
+9668
+8745
+6698
+11874
+9277
+
+19436
+11206
+7547
+1540
+
+4757
+11223
+9685
+6113
+10587
+5328
+1896
+
+3312
+2758
+3528
+3501
+1933
+5876
+3471
+1208
+3892
+5302
+2674
+1282
+1195
+5675
+5753
+
+3127
+21845
+
+5244
+9557
+8744
+2783
+6549
+6225
+1122
+7317
+7574
+
+5154
+2790
+3239
+6496
+7433
+5770
+3835
+6644
+5503
+1273
+1244
+7098
+
+4307
+1882
+9426
+7432
+3558
+5765
+9957
+6974
+
+9510
+35767
+
+3109
+5208
+4756
+1226
+5645
+7133
+2308
+5784
+5194
+2739
+
+1850
+9199
+6957
+6793
+9231
+9094
+7275
+2519
+
+52651
+
+2337
+6455
+5574
+3001
+1296
+5120
+5175
+1704
+7041
+2118
+3446
+2219
+
+10123
+2817
+6853
+11370
+9490
+
+11194
+1887
+1922
+2390
+10687
+3573
+8476
+
+3646
+1365
+5255
+1882
+5705
+2428
+5833
+2242
+3674
+2254
+5141
+1317
+4873
+4421
+4178
+
+7264
+12898
+4423
+1871
+4998
+10540
+
+9143
+9081
+6136
+6734
+6955
+6956
+5693
+8110
+
+8820
+11554
+5474
+9848
+
+7445
+8434
+7883
+3523
+2562
+5174
+3178
+5766
+5322
+5347
+
+2666
+1556
+4772
+5053
+5874
+5711
+1684
+3351
+4037
+4770
+4755
+6280
+1326
+5756
+
+4322
+10058
+6727
+3217
+9987
+3195
+10711
+5728
+
+8382
+32068
+
+3385
+1384
+3110
+1205
+2932
+4065
+3886
+5950
+6443
+2657
+2229
+4438
+2100
+3961
+
+1654
+2028
+8414
+3662
+4270
+3923
+4827
+5443
+2710
+3406
+
+8262
+6401
+2115
+7528
+1359
+1934
+1560
+3271
+8459
+8387
+
+8437
+5394
+5589
+5243
+3421
+5228
+3601
+
+6306
+5779
+5119
+2453
+1289
+1164
+1175
+7252
+7215
+2632
+6832
+2304
+
+4788
+3723
+5887
+2748
+7350
+5974
+6015
+1545
+1092
+2524
+4130
+7297
+
+3455
+5668
+1435
+2738
+5520
+4374
+2594
+4144
+4457
+6479
+1230
+3682
+6157
+4284
+
+10449
+6988
+2505
+6083
+3844
+2655
+8953
+
+6061
+5493
+4922
+3375
+1273
+4181
+4643
+4039
+1482
+5952
+3468
+4719
+4101
+4702
+
+1135
+3886
+3308
+3986
+2662
+1814
+5813
+1079
+4916
+5059
+2155
+1404
+2398
+2730
+1972
+
+5868
+5201
+3725
+4905
+1655
+3585
+6339
+5563
+6869
+4779
+4072
+5106
+3587
+
+5997
+1240
+2115
+4558
+1572
+7031
+1568
+3230
+4081
+3767
+1916
+5388
+
+6672
+7355
+7362
+6232
+6112
+7095
+5350
+8343
+8171
+8331
+
+4370
+11625
+6923
+1583
+9520
+11093
+11708
+
+4475
+23713
+
+6310
+6536
+3243
+2910
+2861
+5076
+6562
+3924
+5933
+4044
+1572
+2351
+6665
+
+6994
+5704
+5165
+7364
+5819
+1816
+3929
+6967
+1009
+2528
+6107
+6954
+
+6855
+11865
+9195
+18609
+
+5582
+3987
+7772
+2106
+1006
+5441
+6201
+7748
+1386
+1898
+7790
+
+5332
+5371
+3515
+6367
+6657
+2677
+4790
+2448
+3401
+1668
+4425
+3758
+5385
+
+4105
+3883
+4389
+2214
+1943
+2510
+2544
+1330
+6275
+1492
+5837
+1830
+4440
+
+5041
+
+40092
+
+34451
+
+14820
+10096
+24218
+
+2095
+3608
+1467
+6098
+9586
+4062
+6745
+1217
+2074
+
+5660
+7032
+7666
+2711
+3050
+2260
+6274
+4672
+1028
+6916
+7861
+
+37401
+29831
+
+15255
+6714
+2378
+13864
+
+7618
+15264
+8496
+7847
+8750
+
+6392
+4892
+1200
+2133
+2879
+6033
+5634
+1979
+5066
+3965
+4734
+1761
+5627
+2369
+
+19691
+16626
+6806
+
+3594
+1824
+4264
+5058
+2286
+6836
+4687
+4016
+2660
+7224
+6390
+
+6213
+6396
+5387
+5318
+3022
+5080
+6098
+3699
+2437
+6430
+6091
+1255
+2480
+2490
+
+8795
+3287
+14228
+10078
+
+6720
+3431
+
+13856
+2609
+
+1683
+1241
+5941
+8021
+11838
+
+3961
+3033
+4069
+3200
+2598
+3133
+6007
+2048
+2850
+2605
+5111
+3726
+1994
+1910
+2289
+
+11960
+3800
+11919
+3808
+12138
+7118
+
+60979
+
+10777
+8860
+3736
+3591
+12500
+8963
+
+3474
+3027
+5923
+1874
+3555
+5312
+5568
+1796
+2831
+3105
+3501
+4378
+5999
+4528
+5948
+
+2493
+13969
+
+6992
+14112
+3430
+14233
+13381
+
+17059
+5737
+1290
+12844
+
+6302
+4418
+2067
+5059
+2085
+3061
+4411
+5662
+4097
+3333
+2182
+1090
+4185
+
+4811
+1351
+6050
+7344
+2745
+6588
+3506
+2056
+4229
+4256
+1853
+5912
+
+9673
+2207
+4646
+2680
+12985
+3873
+
+1110
+6118
+4411
+6331
+1668
+6023
+6977
+5049
+6669
+4421
+5027
+3131
+
+9968
+2987
+5041
+18431
+
+7436
+5660
+15858
+7130
+12737
+
+5232
+9051
+10275
+9404
+3384
+5719
+5724
+10218
+
+4350
+2456
+7892
+1318
+6932
+7890
+9595
+4605
+7672
+
+2666
+9981
+1959
+5686
+3655
+2763
+6737
+8621
+
+9915
+5955
+10523
+3976
+4166
+9602
+2985
+6160
+
+25160
+18830
+7409
+
+1322
+1283
+3839
+3054
+5782
+4615
+2579
+3332
+3046
+3634
+2428
+1373
+5638
+
+13941
+
+2653
+14138
+2355
+12340
+6598
+
+4857
+9417
+13144
+9072
+4174
+
+1946
+6030
+5875
+1649
+1757
+2198
+2673
+3743
+1357
+1134
+1602
+
+2791
+10432
+4037
+2767
+11295
+11255
+9762
+
+9232
+11015
+21925
+
+6365
+1170
+4253
+5122
+5390
+7061
+7781
+4584
+6362
+6367
+5321
+
+23166
+21313
+16147
+
+7915
+10734
+6921
+4796
+6442
+3520
+4416
+5702
+
+31627
+21575
+
+9569
+2837
+3816
+5052
+9399
+6174
+3291
+2513
+2932
+
+6255
+14356
+5389
+18970
+
+26896
+3552
+
+19037
+5180
+6855
+
+4929
+5212
+15135
+
+1114
+1338
+8702
+7914
+6690
+5981
+6129
+4246
+4660
+
+2696
+4528
+4053
+5982
+2308
+6097
+1933
+6410
+4851
+4526
+5705
+5510
+3951
+
+4693
+4906
+4570
+1161
+2974
+4099
+5423
+4146
+3305
+3057
+2079
+6187
+3196
+2285
+
+6300
+6253
+5892
+3636
+5373
+5345
+1990
+7456
+1218
+4220
+3845
+
+3028
+1790
+2104
+6750
+2516
+2482
+2574
+6806
+1613
+2279
+5389
+3979
+6672
+
+48619
+
+15159
+1029
+
+13352
+5081
+
+6292
+6989
+5568
+6181
+2773
+4529
+3205
+1134
+6416
+5199
+2830
+4813
+
+4718
+5530
+5036
+2874
+2658
+2353
+5402
+3476
+1924
+3147
+2883
+6331
+
+14524
+30079
+
+4071
+4399
+3021
+5165
+2110
+6084
+1863
+3614
+4336
+5688
+1960
+
+25783
+28718
+
+13615
+1645
+11870
+8796
+
+5951
+6447
+2501
+7770
+2999
+6715
+8707
+5124
+6215
+3113
+
+6241
+2189
+1752
+1812
+2727
+5703
+2710
+6113
+1732
+6237
+
+7990
+6499
+8481
+3443
+9375
+10439
+5892
+2758
+
+7919
+8753
+5124
+6388
+8026
+7326
+4457
+4352
+5781
+5549
+
+49501
+
+10500
+23249
+
+8352
+9128
+4905
+5833
+1218
+2859
+11489
+
+6104
+6546
+6243
+6716
+3511
+3433
+4327
+2453
+2887
+5007
+4404
+4506
+2315
+
+7269
+3193
+3535
+2566
+2745
+6483
+3880
+5042
+6931
+4519
+3442
+6667
+
+16325
+7397
+21391
+
+12648
+9268
+8280
+1497
+13788
+3384
+
+1373
+2171
+2065
+5461
+4854
+2427
+5814
+2197
+4077
+5138
+6861
+6083
+1995
+
+4817
+3501
+1937
+4840
+4299
+6083
+1330
+2737
+5361
+5941
+2762
+3191
+5530
+3913
+4139
+
+10082
+7801
+5221
+4785
+6847
+4672
+8824
+4507
+
+25999
+21078
+
+34976
+27760
+
+6972
+2714
+1051
+4905
+1102
+6332
+6113
+4218
+7125
+4372
+4669
+
+3986
+10129
+16175
+6193
+11015
+
+6260
+5523
+2032
+5304
+5167
+2908
+6518
+5491
+1718
+6229
+3264
+4899
+2873
+
+6613
+4234
+6130
+1017
+7986
+7727
+3564
+8250
+
+12031
+11879
+11614
+13472
+8471
+7369
+
+4315
+1636
+6292
+6768
+3788
+4643
+6397
+7402
+1379
+3518
+6438
+6196
+
+5667
+7559
+13899
+18285
+
+5266
+34337
+
+29305
+22273
+
+9371
+5132
+1652
+2573
+8840
+8636
+4700
+3145
+7728
+
+5864
+4845
+3567
+1247
+3070
+1378
+2836
+5574
+2398
+5191
+3520
+1395
+4933
+5530
+2656
+
+5504
+5002
+4944
+4903
+3186
+1446
+3886
+1506
+2669
+5362
+2456
+2150
+4468
+5212
+2319
+
+1543
+1581
+4295
+5685
+1977
+4361
+2381
+5288
+5557
+3159
+4833
+5577
+5892
+
+8109
+4061
+
+7132
+2394
+9579
+7360
+9023
+8589
+5666
+3108
+
+25582
+3178
+2616
+
+5742
+2967
+2577
+2141
+6022
+1148
+1971
+1779
+5039
+5210
+1043
+1633
+2697
+
+5024
+1439
+3535
+4723
+3271
+3904
+4303
+2706
+2878
+2882
+4417
+5580
+2685
+5028
+2243
+
+4788
+2903
+6717
+5514
+4434
+6396
+3370
+2964
+6940
+3018
+1328
+6527
+4651
+
+5796
+7350
+15943
+7116
+11040
+
+9110
+1795
+10997
+9811
+5571
+8786
+8690
+
+1173
+4256
+2326
+2947
+3133
+4930
+1653
+4548
+3971
+4837
+4084
+3362
+4144
+4015
+2631
+
+22258
+
+1270
+8084
+3413
+1180
+7841
+3467
+1068
+3763
+7479
+2988
+5377
+
+4833
+2453
+2985
+5365
+1128
+2411
+2103
+
+29169
+
+9451
+5237
+3547
+13513
+3528
+4937
+
+14834
+6011
+11685
+17950
+
+3040
+4721
+1809
+5755
+2326
+4373
+1018
+1433
+3180
+3173
+1313
+4158
+1867
+3349
+5629
+
+4201
+12336
+18265
+14378
+
+5248
+2091
+6755
+4523
+6049
+1183
+3834
+1242
+6517
+1561
+6666
+5117
+5600
+
+2907
+1482
+2765
+8934
+1654
+3786
+8807
+8924
+
+6131
+4724
+4774
+1030
+6359
+4452
+5557
+1501
+5743
+2434
+1809
+4657
+5609
+4773
+
+24218
+26128
+
+11710
+8138
+7143
+7236
+11903
+4547
+2419
+
+1474
+13551
+6009
+12136
+13007
+9816
+
+7230
+3816
+5352
+5591
+
+7237
+5129
+2630
+3158
+4131
+1324
+2439
+2828
+1922
+6051
+3871
+3577
+
+21875
+13945
+15782
+
+10156
+15069
+18789
+6685
+
+6292
+12221
+17527
+
+11396
+11684
+2362
+12055
+6888
+9393
+11909
+
+37154
+17860
+
+22974
+
+3693
+2551
+3077
+7444
+8973
+5966
+2728
+
+2554
+3119
+2796
+1993
+3959
+4421
+2691
+3002
+4104
+5876
+2748
+3633
+3567
+2280
+3852
+
+9583
+4003
+
+3100
+4338
+6077
+4813
+3223
+2373
+1607
+7412
+7798
+7684
+
+4354
+3140
+2957
+5563
+6119
+2571
+1742
+3603
+5854
+3755
+2827
+
+1302
+4160
+1944
+1215
+1603
+5361
+5959
+3698
+5329
+3118
+4941
+1624
+4755
+3249
+5205
+
+4707
+3243
+6299
+3689
+8496
+8594
+4187
+
+5986
+4431
+1006
+1707
+1202
+4184
+3438
+5148
+4472
+6561
+5882
+5693
+
+11346
+8748
+12659
+
+2456
+2147
+1401
+5715
+5128
+5560
+1635
+3947
+5021
+4850
+1414
+2316
+5949
+4779
+2867
+
+2530
+3901
+7034
+4665
+7109
+2416
+5461
+8825
+
+5287
+4195
+9609
+5697
+3135
+6638
+2780
+6876
+6032
+
+17278
+18581
+4060
+13610
+
+14199
+19618
+4500
+
+4423
+15765
+6614
+11352
+1941
+
+30048
+17442
+
+6881
+8630
+10121
+9792
+6340
+8848
+7245
+7764
+
+5138
+9396
+2975
+5036
+6776
+7205
+8991
+3595
+4894
+
+1065
+4272
+2155
+2655
+9405
+10274
+8344
+
+8234
+3276
+1914
+11975
+8096
+
+7358
+13681
+13640
+1543
+13683
+
+24588
+22649
+
+5034
+2818
+4103
+2328
+2311
+4241
+6145
+2694
+5191
+4266
+6477
+6412
+4566
+3077
+
+4442
+2199
+7109
+6674
+5257
+4611
+
+2544
+1810
+1941
+3389
+3473
+1813
+1232
+3782
+1733
+4191
+3953
+3793
+4832
+2560
+1321
+
+3331
+2853
+5284
+1989
+4543
+4447
+5852
+2847
+3260
+5583
+5429
+2967
+3563
+1925
+2799
+
+9448
+3662
+6703
+7356
+1600
+
+4050
+6662
+7169
+2836
+2231
+1149
+5204
+4275
+6231
+7478
+1388
+6980
+
+2185
+1526
+1640
+9156
+6623
+8572
+7426
+9419
+
+10637
+9584
+8293
+7473
+3529
+7532
+
+3987
+12127
+10749
+3399
+11041
+4600
+9896
+
+3728
+1878
+5192
+3264
+6367
+4429
+6449
+7005
+4883
+5359
+2112
+6228
+
+13574
+6574
+11518
+11909
+13625
+
+16357
+19546
+7520
+8254
+
+2122
+1712
+2729
+2847
+1157
+2895
+4850
+2805
+5603
+2321
+6113
+5468
+1230
+2385
+
+3947
+3326
+2395
+5776
+4035
+3206
+5845
+6429
+5039
+4540
+5047
+4237
+6953
+
+1738
+8822
+11967
+10160
+4327
+8382
+2686
+
+2778
+6909
+7649
+2787
+8749
+1720
+6863
+5515
+8631
+3257
+
+1369
+2470
+2726
+7415
+5232
+1919
+2981
+4437
+3168
+6412
+7072
+3201
+
+19275
+10942
+
+12930
+12593
+9356
+5680
+10193
+4399
+
+11119
+10651
+8687
+12028
+1713
+8311
+10089
+
+3752
+
+10177
+9060
+4817
+3564
+7272
+10452
+
+1563
+3885
+3191
+6312
+5524
+5207
+3669
+
+8105
+7217
+4719
+9214
+3973
+10782
+10563
+
+10142
+4264
+
+7283
+
+15973
+9578
+9884
+4478
+10540
+
+5548
+4654
+3024
+2243
+3985
+1220
+3461
+1042
+1845
+2888
+3931
+2356
+1430
+3373
+4604
+
+8036
+3016
+3510
+2659
+8700
+1539
+1202
+2116
+4351
+7388
+
+2995
+7003
+8022
+2012
+1976
+3938
+3744
+6146
+5056
+7590
+4008
+
+4459
+12305
+7633
+2742
+12867
+12607
+
+3791
+5059
+6361
+3008
+4543
+1374
+6821
+5967
+8461
+4241
+
+1641
+1364
+2037
+2479
+1413
+4250
+5042
+2438
+2855
+3081
+3535
+3966
+3574
+1149
+3606
+
+3397
+2787
+5638
+2321
+3765
+5617
+4870
+4456
+6681
+1890
+1068
+3609
+3043
+
+3436
+4011
+5212
+5576
+4139
+1387
+6298
+4179
+4000
+4207
+3302
+1539
+2793
+3551
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/02/02.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,56 @@
+const input = "02/input.txt"
+
+struct InputLine
+    opponent::Char
+    choice::Char
+end
+
+function parse(fh::IO)::Vector{InputLine}
+    v = Vector{InputLine}();
+    while true
+        l = readline(fh);
+        if isempty(l)
+            break;
+        end
+        a, b = split(chomp(l));
+        push!(v, InputLine(a[1], b[1]));
+    end
+    v
+end
+
+function score(il::InputLine)::Int
+    shapescore = Int(il.choice - 'W');
+    op, me = Int(il.opponent-'A'), Int(il.choice-'X')
+    @assert abs(me-op) <= 2
+    if abs(me-op) == 0
+        shapescore + 3
+    elseif abs(me-op) == 1
+        shapescore + (me > op ? 6 : 0)
+    else
+        shapescore + (me < op ? 6 : 0)
+    end
+end
+
+function score2(il::InputLine)::Int
+    winscore = 3 * Int(il.choice-'X');
+    winshape = (Int(il.opponent-'A')+1)%3;
+    loseshape = (Int(il.opponent-'A')-1);
+    if loseshape < 0
+        loseshape += 3
+    end
+    shape = (if il.choice == 'X'; loseshape elseif il.choice == 'Y'; Int(il.opponent-'A') else winshape end);
+    shape+1 + winscore
+end
+
+function calc(v::Vector{InputLine})::Tuple{Int, Int}
+    sum(map(score, v)), sum(map(score2, v))
+end
+
+function run_02(file::String)::Tuple{Int,Int}
+    open(file; read=true) do fh
+        p = parse(fh);
+        calc(p)
+    end
+end
+
+print(run_02(input))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/02/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,2500 @@
+A Z
+C X
+A Z
+A Z
+C Y
+C Y
+A Z
+A Y
+C Y
+A Y
+A Z
+A Z
+A Z
+A Y
+A Z
+A Y
+C Y
+C X
+A Y
+C Y
+C Y
+C X
+A Z
+C Y
+C X
+A X
+A Y
+A Z
+A Y
+A Y
+C X
+C X
+B Y
+C X
+C X
+A Y
+A Z
+A Z
+A X
+A Z
+A Z
+C Y
+A Z
+A Z
+A Y
+C X
+C Y
+C X
+B X
+C Z
+A Y
+A Z
+A Z
+A Z
+A Y
+A Y
+C X
+A Y
+A Z
+C Y
+A Y
+A Y
+A Z
+A Z
+C Y
+A Z
+C Y
+A Y
+A Z
+A Z
+C Y
+B Z
+A Z
+A Z
+A Z
+A Z
+C X
+C X
+A Y
+A X
+A Y
+A Z
+A Z
+C X
+A Z
+C X
+A Z
+C Y
+C X
+A Z
+A Z
+A Z
+A Z
+C X
+C Y
+A Z
+A Z
+C Y
+A Z
+B Z
+C X
+A Z
+A X
+C X
+A Z
+C Z
+A Z
+C X
+A Z
+A Y
+C X
+C Z
+A Z
+C X
+C Y
+A Z
+B Z
+B Y
+A X
+A X
+A X
+A Z
+A Z
+A X
+A Z
+A X
+A Z
+A Z
+C X
+C X
+B Z
+A Z
+A Y
+A Z
+A Z
+A Z
+A Z
+C X
+C X
+C X
+A Z
+A Z
+A Z
+A Z
+A X
+A Y
+A Y
+C X
+C X
+B Z
+C X
+A X
+A Z
+A Z
+C X
+C Z
+A Z
+A Z
+C Y
+A X
+A Z
+C Y
+A X
+A Y
+A Y
+A Y
+C Y
+A Z
+A Z
+C X
+C X
+C X
+C X
+B Z
+C Y
+C X
+C X
+A Y
+A Y
+A Z
+A Z
+A X
+C X
+A Z
+B Z
+A Z
+C X
+A Y
+A Z
+A Z
+A Y
+A Y
+A Z
+C X
+A Y
+C X
+C X
+A Z
+A Y
+C X
+A Z
+A Z
+A Y
+A Z
+A Z
+C Y
+C Z
+A Y
+A Z
+C X
+C X
+A Z
+A Z
+C Y
+A Y
+A Z
+A Y
+A Z
+C X
+A Z
+A Z
+C X
+A Y
+A Y
+C Y
+A Z
+C Y
+A Z
+A Z
+C Y
+A Y
+B Z
+C Y
+C X
+C X
+A Z
+C Y
+A X
+C Y
+A Z
+A Y
+A Z
+C X
+C X
+C Y
+C Y
+A Y
+A Z
+C X
+C X
+A Y
+A X
+A Y
+B Z
+A Y
+C Y
+C X
+C X
+A X
+C X
+B Z
+A X
+C Y
+C X
+C X
+A X
+A Z
+B Z
+A Z
+A Z
+A Y
+A X
+A Z
+C X
+A X
+C Y
+A Z
+A Z
+A X
+A Z
+A Z
+C X
+C X
+A Z
+A Z
+A Z
+A X
+A Z
+A X
+B Y
+A Z
+A Y
+C Y
+A Z
+C X
+A Z
+C X
+A Y
+A Z
+C X
+C Y
+A Y
+C Y
+A Z
+C X
+A Z
+A Z
+C X
+A Y
+A Z
+A X
+A Z
+A Z
+A Z
+B Y
+C X
+A X
+A Z
+A Z
+C Y
+C Y
+C X
+C X
+C X
+A X
+A X
+A Z
+A X
+A Y
+A Z
+A Y
+A Z
+C Y
+C Z
+A Y
+A Z
+A Z
+A X
+A Z
+A Z
+C X
+C Y
+A Y
+C X
+C X
+A Z
+C X
+C X
+C X
+A X
+A Z
+A Z
+A Z
+A Z
+B Y
+A Y
+A Y
+A Z
+C X
+A Y
+A Z
+C X
+A Z
+C Z
+A Y
+C X
+A Z
+B Z
+A Y
+A X
+A Z
+C X
+A Z
+A Z
+A Z
+A Z
+A Z
+B Z
+A Z
+C X
+A Y
+C X
+A Z
+A Z
+A Y
+A Z
+B Z
+C X
+A Y
+C Y
+A Z
+A Z
+C X
+C X
+A Y
+C X
+C Y
+B Z
+A Y
+C X
+A Y
+C X
+A X
+A Y
+A Z
+A Z
+A Y
+C X
+A X
+C X
+B Y
+A Z
+A Y
+B Y
+A Y
+C X
+A Z
+A Z
+C X
+C Y
+A Y
+C X
+C Y
+A Y
+A Z
+A X
+B Z
+C X
+A Z
+A Y
+A Z
+B Z
+A Z
+A X
+C Y
+A X
+A Z
+A Y
+C Y
+A Z
+C Y
+A Z
+C X
+C X
+A Y
+C X
+C X
+A Y
+A Z
+A Z
+A Y
+A X
+C Y
+A Z
+A Z
+C X
+A X
+A Z
+C Z
+A Z
+C Y
+A Z
+C X
+A Z
+A Z
+A X
+C X
+C X
+C Y
+B Z
+B Y
+C Y
+A Y
+A X
+A Z
+C X
+A Y
+A Y
+A Z
+A Z
+C Z
+C X
+C X
+C X
+A Z
+C X
+A Z
+A Z
+A Y
+C Y
+C X
+C X
+C X
+A Y
+C X
+B Z
+C X
+A Z
+C Y
+A Y
+C Y
+A Z
+A Z
+C X
+A X
+A Z
+A Y
+A Z
+B X
+C Z
+A Z
+C Z
+A X
+C X
+C X
+C X
+C X
+A Z
+A Y
+A Z
+A Z
+A Z
+A Z
+A Z
+C Z
+C Y
+C Y
+C X
+C Y
+A Z
+C X
+C X
+A Z
+A Z
+C X
+C Y
+C Y
+A Z
+A X
+C Y
+C Y
+C X
+A Y
+C X
+A Z
+A Z
+A Y
+C Y
+A Y
+C X
+C X
+A Z
+A Z
+C Y
+A Z
+C X
+A Y
+A Y
+A Z
+C Y
+A Z
+C X
+A Y
+A Z
+A Z
+A Z
+A Z
+C Y
+A Y
+C Y
+A Z
+A Z
+A X
+A Y
+A Y
+A Z
+C Y
+A Z
+A X
+A Z
+B Z
+C X
+C X
+C Y
+A Z
+A Z
+C X
+C Z
+A Z
+C X
+C Y
+A Z
+B Z
+A Z
+B Z
+A X
+A Y
+A Z
+A Z
+A Z
+A Z
+C Y
+A Z
+A Z
+A Z
+B Z
+A Z
+C X
+C X
+A Z
+C X
+A X
+A Z
+A Y
+A Y
+A X
+A Z
+A Z
+A Z
+A Z
+B Z
+A Z
+C Y
+C Y
+C X
+C X
+B Z
+C Y
+A Z
+C Y
+A Z
+A Y
+C Y
+A X
+A Y
+C X
+A Y
+C X
+A Z
+A Z
+B Z
+A Y
+C Y
+C X
+A Z
+A Z
+C X
+A Y
+A Z
+A Z
+A X
+A Y
+A Y
+A Y
+A Z
+A Y
+A Z
+C X
+A X
+A Z
+A Z
+C Y
+A Z
+C X
+A Z
+C Y
+A Y
+A Z
+A Z
+A Z
+A Z
+C Y
+A X
+A Z
+A Z
+A Y
+A Z
+B Z
+A X
+A Y
+C X
+C X
+A Y
+A Z
+C Y
+A Z
+A Y
+A Y
+A Z
+A Y
+A Y
+A Z
+A Z
+A Z
+C X
+A Z
+A Y
+A Z
+A Z
+C Y
+A Z
+C X
+A Y
+C X
+C Y
+A Z
+C Y
+A Z
+A Y
+C Y
+C Y
+A Z
+C X
+C X
+C X
+A Z
+A Z
+A Y
+C X
+A Z
+A X
+A Z
+A Z
+C X
+A Z
+C Y
+A Y
+A Z
+A Y
+A Z
+A Z
+C Y
+A Z
+C X
+A Z
+A X
+A Z
+A Z
+C X
+A Z
+A Z
+C Y
+C X
+A Z
+C Y
+C X
+C X
+A Z
+A Z
+A Z
+A X
+C X
+A Z
+A Z
+C Y
+A Y
+C X
+A Y
+C X
+C Y
+A Y
+A Z
+C X
+A Z
+B Y
+A X
+B Z
+A Y
+A X
+C Y
+A Z
+A X
+A Z
+A Z
+C Y
+A Z
+B Z
+C X
+C X
+B Y
+A Z
+A Z
+A Z
+C Y
+C X
+A Z
+A Y
+A Y
+A Y
+C Y
+C X
+A Z
+A X
+A X
+A X
+A Z
+A Z
+A Z
+A Z
+C X
+C X
+A Z
+C X
+A Y
+C X
+B Z
+A Z
+A Z
+C X
+A Z
+C X
+C X
+C X
+A Y
+C Y
+C X
+A Y
+C X
+C Y
+B Z
+A Z
+C X
+A Z
+A X
+B Z
+A Y
+B Y
+A Z
+A Z
+A X
+A Z
+A X
+A Z
+A Z
+C X
+C Y
+A X
+C Y
+C X
+A Z
+A Z
+A Z
+C Y
+A X
+A Y
+A Z
+A Y
+C X
+B Z
+A Z
+A Y
+C Z
+C X
+A Z
+A Z
+A Z
+B Z
+A X
+C X
+A Z
+A Z
+B Z
+A Z
+A Z
+B Z
+A Z
+C X
+A Z
+C X
+A Z
+C X
+A Z
+C Y
+A Z
+A X
+A Y
+A Y
+C X
+A Y
+C X
+B Z
+A Z
+A Z
+A Z
+A Z
+C X
+A Z
+C X
+A Z
+A Y
+A Z
+B Z
+A Y
+C Z
+A Y
+C X
+A Z
+A Z
+A Y
+B Z
+A X
+C Y
+A Z
+A Y
+A Z
+A Y
+A Y
+A Z
+A Z
+A Z
+A X
+A Z
+C Y
+A Y
+A X
+A Y
+C X
+A Y
+C X
+A X
+C X
+A Z
+C Y
+A Y
+A Z
+A Z
+A X
+A Y
+C X
+C X
+A Y
+A X
+A Z
+B Z
+A Y
+A Z
+A X
+A Z
+B Y
+A Y
+A Y
+A Z
+C X
+A Z
+A Z
+A Y
+A Z
+C Z
+A Z
+A Z
+A Z
+A Z
+C Y
+C Y
+A Y
+B Z
+C Y
+A Y
+C Y
+A Z
+A Z
+A Z
+A Z
+C Y
+A Z
+A Z
+C Y
+C X
+A Y
+A Y
+A Z
+C X
+C Z
+C X
+C X
+A Z
+A Z
+A Y
+A Z
+A X
+C Y
+A Z
+A Z
+C Y
+C X
+A X
+A Z
+A Z
+A X
+C X
+C X
+C X
+A Z
+A X
+C X
+C Y
+A X
+A Z
+C X
+A Z
+A Z
+C X
+A Y
+A Z
+A Z
+A Y
+A Z
+C X
+A Z
+A Z
+C X
+A Y
+A Z
+A Z
+C X
+A Z
+A Y
+A Z
+C Y
+A X
+A Z
+A Z
+C X
+A Z
+A Y
+C Y
+B Z
+A Z
+A Y
+C X
+A Z
+B Z
+A Z
+C Z
+A X
+A Z
+A Z
+C Y
+A Z
+A Y
+C X
+C Y
+A Z
+A Z
+A Y
+A X
+C Y
+A Y
+C X
+C Y
+A Z
+C Y
+A Z
+C X
+A Z
+A Z
+A X
+A Z
+A Z
+B X
+A X
+A Z
+C Y
+A Z
+A X
+C X
+A Z
+A Z
+C X
+C Y
+C Y
+A X
+A Y
+C Y
+A Y
+A Z
+A Z
+A Z
+A Z
+A Y
+C X
+C X
+C Y
+C X
+A Z
+A X
+B Z
+B Y
+C X
+C Y
+A Y
+A Z
+A Y
+C X
+C Z
+A Z
+A Y
+C Y
+C X
+A Z
+A Z
+A Y
+C X
+C Z
+C Y
+A Z
+C X
+C Y
+A X
+A X
+A Y
+A Z
+B Z
+A X
+A Y
+A Y
+C X
+C Y
+A Z
+A X
+A Z
+A X
+A Y
+A Z
+A Z
+A Z
+C X
+A Z
+A Z
+A Z
+C Z
+C Y
+C Y
+A Z
+C Y
+C Y
+C Y
+C X
+A Z
+C X
+C X
+A Z
+A Y
+A Z
+A Z
+A X
+A Y
+A Y
+C X
+C X
+A Z
+A Z
+A Z
+A Z
+A Y
+A Z
+A Z
+A Z
+A Z
+A X
+A X
+A Y
+A X
+C Y
+A Y
+A Z
+C X
+A Y
+A Y
+A Z
+A Z
+A Z
+C X
+A Z
+C X
+C X
+C Y
+A Y
+A Z
+A Y
+A Z
+C X
+C X
+A Z
+A Z
+A Z
+C X
+A X
+A Z
+A Z
+C Y
+C Y
+A Y
+A Y
+A Z
+A Z
+C Y
+C X
+C Y
+A X
+C Y
+C X
+C Y
+A Z
+A Z
+A X
+C Y
+C Y
+A Z
+A Y
+C X
+A X
+B Z
+A Z
+C X
+A Y
+A X
+A Z
+A Z
+A Z
+C Y
+C X
+A Z
+C X
+A Z
+A Z
+A Y
+A Z
+A Y
+A X
+A Z
+C Z
+A Z
+A Z
+A Z
+A X
+A Z
+A X
+C X
+A Z
+A Z
+C Y
+A X
+A Z
+C X
+C X
+A Y
+A Z
+A Z
+C X
+B X
+A Z
+C Y
+A Z
+C X
+A Y
+A Z
+C X
+A X
+A Z
+A X
+A Z
+C X
+A Z
+A X
+A Z
+C X
+C Y
+A Y
+A X
+A X
+A Z
+C Y
+C Y
+A Y
+A Y
+A Y
+A X
+A Z
+A Z
+A Z
+C Y
+C Y
+A Y
+B X
+B X
+A Z
+C X
+C X
+A Z
+C Y
+C X
+A Z
+A Z
+A Z
+A Z
+C X
+A Z
+A Z
+C Y
+A Y
+C Y
+A Z
+C Y
+C Y
+A Z
+C X
+A Z
+A X
+A Z
+C X
+C X
+A Y
+B Z
+A Y
+C Y
+A Z
+C Y
+A X
+C X
+A Y
+C X
+A Z
+C Z
+C Y
+A Z
+C X
+C Y
+A Z
+A X
+A Z
+A Z
+A Z
+C X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+A Z
+A X
+A Y
+C Y
+B Y
+C X
+B Z
+A Z
+A Z
+A Y
+B Z
+A Z
+A Z
+C X
+C Y
+C X
+A Y
+A X
+C X
+C Y
+A Y
+C X
+C Y
+A Z
+A Z
+A Z
+A Y
+C X
+A Y
+C X
+B Z
+A Z
+A Y
+A Z
+A Z
+A Y
+C X
+A Z
+C X
+C Y
+A Y
+A Z
+B Z
+C X
+A Y
+C X
+A Y
+A Z
+C X
+A X
+C X
+B Y
+C X
+A Z
+A Y
+A Z
+A Y
+A X
+C X
+C X
+A Y
+C X
+A Y
+A Y
+A X
+B Y
+A Y
+C X
+C X
+A Y
+B Z
+B X
+B Z
+A Y
+A Z
+C Y
+A Y
+B Y
+A Z
+C X
+A Z
+A Z
+A Z
+A Z
+B Z
+C X
+C Y
+A Z
+C Y
+C Y
+A X
+C X
+A Z
+A Z
+A Z
+C X
+C X
+C X
+A Y
+C Z
+C Z
+A Z
+C X
+A Y
+A Z
+A Z
+A Z
+C X
+A Z
+A X
+A Z
+A Z
+A Z
+A Z
+A Y
+C Y
+C X
+A X
+A Y
+C X
+A X
+A Z
+A Z
+C X
+A Z
+A X
+A Z
+A Z
+A X
+A Z
+A Z
+A X
+A Z
+A X
+B Y
+A Y
+A Y
+C Y
+A Z
+A Y
+C X
+A Z
+A Y
+A X
+C Y
+B X
+C Y
+A Z
+C X
+A Y
+A Z
+A Y
+A X
+C Y
+A Z
+A Z
+C Y
+C X
+A Z
+C X
+A Y
+C X
+A Z
+A Y
+A Z
+A Z
+A Z
+A Y
+A Z
+C X
+C X
+A X
+C X
+C X
+A Z
+C X
+A Z
+C Y
+C X
+A Z
+A Z
+A Z
+C X
+A X
+C Y
+A Z
+C Y
+A X
+A Z
+C X
+A Z
+A Z
+A X
+A Z
+C X
+B X
+A Z
+A Z
+A Z
+C X
+A Y
+A Y
+A X
+C Y
+C Y
+A Z
+A Y
+A Z
+A Z
+C X
+A X
+A Y
+A Z
+A Z
+A Z
+A Z
+B Z
+C X
+C X
+C X
+A Z
+C Z
+A X
+C X
+A Z
+C Y
+A Z
+A Z
+A Y
+A Y
+C X
+A Z
+A X
+A Z
+A Z
+A Z
+A Z
+C Y
+A Z
+A Y
+A X
+A X
+A Z
+C X
+A X
+A X
+A Z
+A Y
+C X
+A Z
+A Z
+A Y
+A Z
+B Z
+C X
+C X
+C Z
+C Y
+C X
+A Z
+C Y
+A Z
+C Z
+A Z
+A Y
+A Y
+A X
+A X
+A Z
+A Y
+A Y
+A Y
+A Y
+A Z
+C Y
+A Z
+A Z
+C X
+A Z
+A Z
+C Y
+A Y
+C X
+A Y
+C X
+A Z
+B Z
+A X
+B X
+A Y
+A X
+A Y
+B Z
+A Y
+A Z
+C Y
+C Y
+A Z
+A X
+A Z
+A Z
+C Z
+A Z
+A Y
+C X
+A Y
+C X
+A X
+A Y
+C Y
+A Y
+A Z
+A Z
+C X
+C X
+B Z
+A Z
+A Z
+A X
+C X
+C Y
+A Z
+A Z
+A X
+C X
+C Z
+A Z
+C Y
+A Y
+B Z
+C Y
+A Z
+C X
+A X
+A Z
+A Z
+A Z
+A Y
+C Y
+A Z
+C Y
+A Z
+A Z
+A Z
+A Z
+A Y
+C X
+A Y
+C Y
+B Z
+A Z
+C X
+C Y
+A Z
+C X
+A Z
+C X
+C Z
+A Z
+C X
+C X
+A Z
+A Z
+A Y
+A Y
+A Y
+C X
+A Y
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+A Z
+A X
+C Y
+A Z
+A Z
+A Z
+A Y
+A Z
+A Z
+A Z
+A Z
+C X
+B Z
+A Z
+A Y
+A Y
+A X
+A Z
+A Z
+C Z
+A Z
+C X
+A Y
+A X
+B Z
+A Z
+A Z
+A Z
+C Y
+C Z
+C X
+A Z
+C Y
+C Y
+C Y
+C X
+B Z
+A Z
+A Z
+C Z
+A X
+A Z
+A Z
+A Z
+C X
+A Z
+A Z
+C Y
+C Y
+A Z
+A Z
+C X
+A Y
+C Y
+C Y
+A Z
+A Z
+A X
+A Z
+A Z
+A X
+A X
+C X
+A Z
+A X
+C X
+C X
+A Z
+A X
+A Z
+C X
+C X
+C X
+C Y
+A Z
+A Z
+A X
+A Z
+A Y
+A Z
+A Z
+C Y
+A Z
+A Z
+A Z
+A X
+A Z
+C X
+A X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+A X
+A Y
+A X
+C Y
+A Z
+A Z
+C X
+A Z
+A Z
+A Z
+A X
+A Z
+A Z
+A Y
+C X
+A Y
+A Z
+C X
+A X
+A Y
+A Z
+A Z
+A X
+A Z
+A Y
+C X
+A Y
+A Z
+A Z
+A Z
+A Z
+C X
+C Y
+A Z
+B Z
+C X
+A Z
+A Z
+C Y
+C Y
+C X
+A X
+C Y
+B Y
+A Z
+A Z
+A Z
+C Y
+A Z
+A X
+A Y
+A Z
+A Z
+A Z
+C Y
+A Z
+C Y
+C X
+A Z
+A Z
+A Z
+A Z
+A Z
+A X
+A Z
+A Z
+C X
+A Z
+A Y
+C Z
+A Z
+A Z
+A Z
+B X
+C X
+A Z
+A Z
+A Z
+A Z
+C X
+A Z
+A Z
+A Y
+A X
+C X
+C Y
+A X
+A Y
+C X
+A Z
+A Z
+C X
+C X
+A Z
+C X
+A Z
+A Y
+C X
+A Z
+B X
+B Y
+A X
+C Y
+A X
+A Y
+C Y
+A Z
+A Z
+A Z
+C X
+A Z
+A X
+A Z
+C Y
+A Z
+A Z
+C X
+A Z
+A Z
+A Y
+A Z
+A X
+A Y
+A Z
+C X
+C Y
+B X
+C Y
+A Y
+A Z
+C X
+A Z
+C X
+C Y
+A X
+A X
+A Z
+A Z
+C Y
+A Y
+A Y
+A Z
+A Z
+C X
+A X
+C X
+A X
+A Y
+C X
+A Z
+A Z
+B Y
+A Z
+A Z
+A Z
+A Z
+A Z
+A X
+A Y
+A X
+A Z
+A Z
+C X
+A Y
+A Z
+C Y
+C X
+C X
+C X
+C X
+C Y
+A X
+A X
+C Y
+A X
+A Y
+A Y
+B Z
+A Z
+B Y
+C Y
+A X
+A Y
+A Z
+A Z
+A Z
+A X
+C X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+A Z
+B Z
+A Z
+A Z
+A Y
+C Y
+C Y
+C X
+A Z
+A X
+C X
+A Y
+B Z
+C X
+A Z
+C X
+C Y
+C Y
+A X
+A X
+C X
+A Z
+A Z
+A Y
+A X
+A X
+A Z
+C Y
+B X
+A Z
+A Z
+A Z
+A Z
+A Y
+A Y
+A Z
+C Y
+C Y
+A X
+A Z
+A Z
+C Y
+A Y
+A Y
+A X
+A Y
+A X
+A X
+A X
+A Z
+A Z
+A Y
+A Z
+C X
+A Z
+A Y
+A Z
+A Z
+A Y
+A Z
+A Z
+C X
+A Z
+A Y
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+C X
+B Z
+C Z
+A Z
+A Y
+A X
+A X
+C Y
+C Y
+A X
+C X
+B Z
+A Z
+C X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Y
+A Z
+A Z
+A Y
+A Z
+A Y
+A Y
+A Z
+A Z
+A Y
+A Z
+C Y
+A Z
+A Z
+A Z
+C X
+C X
+A Z
+C Y
+A Z
+A Z
+C X
+A Z
+C X
+A Y
+A Z
+C Y
+A Z
+A Z
+C X
+C Y
+A Z
+C X
+C X
+A X
+A Y
+C Y
+A Y
+A Z
+C X
+A Z
+A Z
+A X
+A Z
+C Y
+A Z
+C X
+A Z
+C X
+A Z
+C X
+A Y
+C Y
+A X
+A Z
+A Z
+C Y
+A X
+A Z
+A Y
+B Z
+A Z
+A X
+A Z
+A Z
+A X
+C X
+A Z
+A Z
+C Y
+A Z
+A Y
+A Z
+C Y
+A Z
+A Y
+A Z
+C Z
+A Y
+A Z
+A Y
+C Y
+A Z
+C X
+A X
+B Z
+C X
+C X
+A Z
+A Z
+A Y
+A X
+A Z
+A Z
+B Z
+A Z
+C Z
+A X
+A Z
+A Z
+A Z
+A Z
+A X
+A X
+A Z
+A X
+A Z
+A Z
+A Z
+A X
+C X
+C Y
+A X
+C X
+C X
+A Z
+A X
+C Y
+B Z
+A Z
+A Z
+C X
+B X
+A Z
+A Z
+C X
+C X
+B Z
+C Y
+A Z
+A Z
+C X
+A X
+A Y
+C Y
+C Y
+B Z
+A Y
+C X
+A Z
+A Z
+A Y
+C X
+A Z
+A Z
+C X
+C Y
+A Z
+C X
+C Y
+C Y
+C X
+C Y
+A Z
+C Y
+A Z
+C X
+A Z
+C Y
+C Z
+A Z
+B Z
+A Z
+C X
+C X
+B Y
+B Z
+C Y
+C X
+C X
+A Y
+C X
+C X
+A Z
+A Y
+A Z
+C X
+A X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+C X
+C X
+A Z
+C Y
+C X
+A Z
+B Z
+A Z
+A Z
+A X
+C X
+A Y
+A Z
+A Z
+A Y
+A X
+C Y
+B X
+A Z
+A X
+C Y
+C X
+C X
+C Y
+C Y
+A Z
+A Z
+C Y
+A Z
+A Y
+C Y
+A Y
+C X
+A Z
+C X
+C Y
+C Y
+A Z
+A Z
+A X
+A Y
+A Z
+A X
+A Z
+A Z
+A Z
+C Y
+A Z
+A Z
+C X
+C Y
+A Z
+A Z
+A Z
+C Y
+C X
+A Z
+C X
+A Z
+A Z
+A Z
+A X
+A Z
+A Z
+A Y
+B Z
+A Z
+A Z
+A Z
+C Y
+A Z
+B Z
+A Z
+C Z
+A Z
+A Y
+C X
+C Y
+C X
+C X
+A Z
+A Z
+A Y
+A Y
+A Z
+A Y
+B Z
+C Y
+A Y
+A Z
+C X
+A Z
+A Z
+C Y
+A Y
+A Z
+A Y
+C Y
+A Z
+A Z
+A X
+B Z
+A Z
+A X
+C X
+A Z
+C Y
+C Y
+A Z
+B Y
+A Y
+A Z
+A Z
+A Z
+A Z
+C X
+C X
+A Z
+C X
+A Y
+A Z
+A Z
+C Y
+A Z
+A Z
+C Y
+C X
+B Z
+A Y
+A Y
+C X
+C X
+A Z
+A X
+B Z
+A Z
+C Y
+A Z
+A Y
+A Z
+A Z
+A Y
+C Y
+C X
+A Z
+C X
+A Z
+C Y
+A Z
+C Y
+A Y
+A Z
+A Y
+A Z
+C X
+A Z
+A Z
+C X
+A Z
+B Y
+A Z
+A Z
+C Y
+C X
+C X
+A Z
+A Z
+C X
+B Z
+A Y
+A Z
+A Y
+A Z
+A Z
+A Y
+A X
+C X
+C X
+A X
+A Z
+A Y
+A Y
+A Z
+A Y
+A Z
+A Z
+C Y
+A X
+A Z
+A Z
+C X
+A Z
+A X
+B X
+C X
+A Z
+A Y
+B Z
+C X
+C Y
+A Z
+B Z
+C Y
+A Z
+A Z
+A X
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
+A Z
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/03/03.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,42 @@
+const input = "03/input.txt"
+
+function parse(fh::IO)::Vector{String}
+    readlines(fh)
+end
+
+function run(v::Vector{String})::Int
+    count = 0;
+    for s in v
+        l = length(s);
+        a, b = s[1:div(l, 2)], s[div(l, 2)+1:end];
+        c = intersect(a, b);
+        @assert length(c) == 1;
+        c = c[1];
+        score = islowercase(c) ? 1+c-'a' : 27+c-'A';
+        count += score;
+    end
+    count
+end
+
+function runbadge(v::Vector{String})::Int
+    count = 0;
+    for i in 0:div(length(v), 3)-1
+        group = v[1+3i:1+3i+2];
+        shared = intersect(group...);
+        @assert length(shared) == 1;
+        c = shared[1];
+        score = islowercase(c) ? 1+c-'a' : 27+c-'A';
+        count += score;
+    end
+    count
+end
+
+
+function run_03(f::String)::Tuple{Int,Int}
+    open(f; read=true) do fh
+        p = parse(fh);
+        (run(p), runbadge(p))
+    end
+end
+
+println(run_03(input));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/03/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,300 @@
+WjmsdnddnmQPZPPJPL
+bQllTtpBlgwtrbbCwfZcfSFPSfLCSF
+GgVgQrlpphBGrlVGgTtsRHRWVRMzRdVsqdnDnV
+MMTcbpnfNGQbMjgsRwSzRptRzz
+lPqCCqQdQqQmCPRzRVSwtzgqqwqR
+lrDdllPdBWdDFQFnMbDNDn
+FldWTldlpBSLzvpnpSTpWbDhbHNDPHhJcNHNDwbH
+qVCGQRGrrgMQrJhPNchgvgJhNc
+frjGfMrGQMjsRrRQjvQGmrQQszTTpSLBznlzBlLLSBLLSZTn
+TPZZZMTTbNTZNtTlTbjPVRVGzpGQLLzdGgmslhzSzgLzQh
+wrfwDDvcnFvCfrrSQsmzGGQQdndsGg
+qfHwHCqCqCrFJrcBHCCJRmWTRTmVMttjRjRHZMNV
+vpbqnzbPmWLFjFLBnjZg
+NltQcCClQlcGQGtMTCRdGTGBFZRLZjFFZZhBPLrFHZFjHf
+lMtlGMwMsCCNlTwtsCPzzmPmmVpmpWqVWsWz
+VmWVSchSrScGtwlVtBnwBVFF
+RZZPRNpPCLZvZPZNCLbQPZNBFtttmwBMTMTtttCwtgwBgl
+RNNmPvbQQjPRQQNNHpNbhsfzWJqqSJcsGHhHcfhq
+dtJvcpccWvLDztRCRRCrCC
+qHVslPzPqHqzmPhTzmDFggjrHrSCNFFFSjgR
+qPVPMhszZPVhwBZcdpvZJncbcJ
+HBNLlBDtvLDHhHLvfwlFjqfQTFqqWfST
+ddsGcggJncZVRdGCdZdcWWzSFrjzQFrfTzqfCjFw
+VdgscZmbZNBvbDHTbL
+GtSZQqpHpHfGHzzqHzHfSbPbnJCrRCnJChmjnJnbSh
+DvcTNTDWlNDWdlbnnbjmRhRrCCRd
+cclNlwBRvvTNccRlBNRspVLLZzVzVZQqfqqLpzpw
+dBSfHdZvMQMdNVpWRmWmLCmmtB
+rbTTrrjDcqcrrqrjjJGGclltPCWDmvtpmpPpvRDsCspsLC
+vlhjThlqcjrnTvThndddHZngMnfwNQFNFM
+tHqfszrgLsvgqtHrHtwVCGBRRjGSCwsCsmmV
+MdFMclPmcDQFDlDdlZPmbVpCbFpCbBSCCRGCFpbV
+mcDJdDQMcDTZQhhNNPldhhDtvHLgqtzgLvzTzWHWnWfvvz
+sVdGlTMMVTGCdsTMHHWWnNBzNWpNWCpW
+mPmjFhlwmwmWrpSrSWHB
+jhPhjwgthtFFjRwjZgjGdJcdflfqMsZLLsdZdc
+CBRsTsBBzLCfLqtqBRPNDQglSttlcgDlgGGt
+rJdbrJjrdbVJZdVZCGrNNcgDQlcQrggl
+FpFbbppjFCdwmTvsvfzmTnTBfq
+cqhcWqqCNjGWqcqhGGZzngftmptLZLGZTn
+brJHBbPVHPvSsdHrzQLzZgpfVzpfQtnL
+dHFPBPrBJFRzcWNFhWwN
+QTBTfQTZsjWDJBJd
+FgFWNqWGDPqlPllp
+CCvHzSWFrrtvNvNNHLGQQfbVRRfHZcZcVTTTnZ
+ZCCHHCVRZzBZQThM
+nljDtcqnhcfbwjwltfLQMLLQQppJBMLQJL
+qDsqschsqblDqjcqtRmNVVdNsddNNPmFgV
+QQRnqGBSpQnMmSGmRQQFtdcbbtHHccjpTFcTfF
+wCNPNwNNWNgZHJHJFffqCjbj
+ZNPzNWgNrsmzMVqsqs
+pVWlMBWjlWWqspWDjdjMpMDCPtmmdbhtQtQtbGPCzChchz
+HZNgrHSvHwnFZnvgNvnwLPBGQHmCmtPmtBCGGCmQhG
+FrNfvSNSZLZJrJsVlRWWWqRBVTff
+PQctSHQDPSQcbShpFzbmFddpmdmR
+wqWVwvwNCJRhmdhwJw
+nMnWggVqRVZqHBSBsQsQGDSZ
+qppwrgZSLsVbbfvZ
+hhBHPQQChCDcPcsvvhbGbsllJTfv
+MDWmWFCPFWtgpRWjws
+bmRjdmrJRjhJdJLZBjTFfHGTtQFTSQBS
+wCNVnsspwsnvNDwnsDwSBHtDHHQGTFQFtMrQMS
+nWsNvqVgVcqdJrchrz
+MZlfqlmblmMRWhWNsjSQfh
+CznczgtDFnVtFBNSRNttvhQsNh
+SGDFzVrzVPrGHVnzCPVnlZlPwTbpTqlbqLMpbLlq
+lbbbGDlwLDLjvDvm
+FQfQnLTWVcPChtjmjWSj
+cfgzzgfgfVdzTdfNwBpbLbwdRbpZGrdw
+mwnWtbmdWdccwtgTmwnQfPqsqLQQJQQLsfQQ
+SjrZbhvBZzPHQqfGJfjG
+FlrMBSvMZZFBZhShMMdctWDtmFNDbDTmtmpt
+ndHWprpqFTnnpdNFlhljzlGTwDGzlhGz
+fvZmmVVfJctMZsgMgmcBmsZhwQlGDCzPPZWDGDjCllhC
+WsmvmsmRNnpRHdbS
+LgZSvhvcsWtcWnjrFrWjjjnPWW
+DJDfNlDNRFlpMlFLFP
+TmqTqDHdmfwJRwfdQJLHzzSggHZZcGzhtZvcZhzG
+lbTpqhhgSlgtlTqSDzzLPPPrLGTTGnLm
+VwGfQGBGZWNnmDLPznLB
+vQdfZFWvFMMFwWGGhpGqJbpFtgbS
+hSvCvFRDwmzCCHrszb
+jdMgfTblgjJTLLLzqqGscmPmlqPzHc
+bjQLTTbZMfJffZBBWdjBBQwVDntFpRvvDVvSnhppFv
+FFnFQndPqzmjHscmJFwc
+ZrZrRgDphGGDZgRRBSBNMHHvmwJJSNJHcv
+DGrbbthfWWWDgtfffttfpGPVqnmblqPqCdQTlTPCzTll
+sHTsGrHpsftmddRRZfRv
+MqFcqcMQbMcVPCdFZCzZsRsFzL
+qnVlBbcJJbbMcbgQJMMbQlDWWwHWSWwpTsGHGrpDWG
+qpmvVVcGvVVcVmDsCfqTHLLJzTjfZzLZ
+rSSgwwnSRRBrQrZzZHCQrZ
+BFgFRgdNnSBbbnhSMBSNFdsWVtpWmzsGtvpVPvGWVDDN
+fBBRfJBzzMRGRzCBgWtbCWtbgHHHWdqt
+mvNcDcsDLLnnqfbv
+hpTsTsTrDrfpMSFFZjPFMrSP
+CNQGGDMFWGnWWvvNMQFPvrgzBLVBLszwgggLgw
+mppZVZtZRTbTTpRccVbgrSLzSPSzBrfbPBbSPw
+VtZJhRJcTpJTHlhtHZCFFWFjNjGGnFhCqDqG
+cppcZGcGgGpdTgSSnmpFMFrFzmwqwmrHwz
+RStQJNCNvfBQNjrqmrjFrBMzFB
+LJDNNJCDLcdLnSVd
+gNrBNSrNNtSjBndzmzlVnm
+MbfqfpCLpCsLqsLFSbQLfnMdcdRRcdzldlnljzncnJ
+QPQLqZqhSqhvtvTTWrNg
+DtrrcGvtLnrrvLrfctfHztrfQpbwwphpdSbbPPPwFSFFRPwH
+gggBqTNdTNjqWBlNmCqCmNggQPhpPPPbhhQpSBpJwbSJSQFR
+ZglTmgWNgVZMZdsGMcvDcMdMnz
+bjtTFsPmmtpvVlQHlQJQnJjn
+WzDzwLCSLrrDNLdrSZRCwNzrlQlJMnJQJJVhbcMhgllwnJQh
+fRCZzrWRzzGbGvTmBPTf
+lVlfJVblPQbllflfLdJdvGpjnFRFqJFnDqpJjnpF
+HcwZMgmwWCHHCSwcWCcgSCtCqqpFppGDqvDnRhgnnqFDpjFT
+cwCHtGrCssWHCCWZZMbPPNBVbNfVbPllVszf
+DSpSnRwrZDPWsJdZ
+zjjlQVjlNZmCVCfhCfgFFfFFFqWJbgbFWHJH
+lNQMlGjQBZjCmhNMCChGzlVNrpTnccLLwcRwTSppSpprLRcB
+vLfvcgglbfLfgqdgNpPtzqDmPzmJTTztPCHT
+ZWSQVGwQcWjSshGwVcnSzDJZtPPTzmzzJHCTzDtJ
+SjVSrWVhQVQhwrLMcrFbfplcflvv
+NgtfSRPnnRrSlgsPhnShDWQlMWpVBMMMpCWVBpCQBB
+LLJnvwJvZHZbHTbVCQBppCFJCWWQBz
+wHTGZmZvdvLvjLwZdqngNgsGtrDPSDhtNfDf
+DwrDRlrwmbSbRgwsSbRwGJvQGqjJqGNTJTNGTSGn
+PZdMZzCQFBZWWFQvJZvcNcjqNjjZJG
+WHWCFHBBdzzMWhPFtFdMzlRsVbVmDrRVVrtQplwVwD
+bpWbJMWpJbprfNMrBfJfprWhPnGtnHnLHjPPjLvsWnHGvGvj
+qZdgVVgDQhQZlwcqgDcchldjjmLtntmntPQsmLnLPjssnL
+RVRlgcSSdglZczdqbTCrhBrBpNBSBSbF
+SgbGvfbnGgmnNnnzqMqqHHRzbZBzZR
+TWlssdFwWdtswWPtTtWltwdVHlZZzRHZBZRzrprqHMpqgZrq
+dssdCWTFwSvgmDjDCG
+pqsDnNzzZsdZSnDSpwjBCBWvgjvWjNFWQgWC
+lVGtRtLMGGfbTGTtTbQCQnBQBnBFgFQcgjfc
+GPbTbPtnPttmLTGRRbtmdwSDwpwwhZqmdpzDhDJd
+MdccRQMJvHdgZggvhjjMgHcHlWWqFFWmGqFbJWzzFLWlLmPm
+TDpSsTrtblSzQlGQ
+tfVNrwTwtswTssMRjMMQQddNMRCd
+GqGqGpFqqgDGFRqDwwqqmzpGTLPvVWMPVCPLJLRJJMLTlCWV
+rHrSbrsbQcbtdNHHHfdPlvWBLLWlvMTVlVLCJf
+rccbtthHSHsNHrrcttwqpnDFnMmpnzFnFhnF
+vQQQbRvlLjNNLLBzNllNHNBqGqhMWhGGhTqmPmqhWTFhRm
+tnsZwgSnCDrZSCDsfTMSGpPWmPSWmGmbFq
+CrVnfnCCtrCgfrffcrstDnJNlvJdNvzdBcHdLBJHvbBv
+nmQsMqTnLlmmpQZmTZcdHwCFSpHJSSWHSJVSWSHH
+vRgRRtfPvDjzDgDbsjzRvjfNNWWCSJFwrHCFbrCJWJHCSC
+GhsRBztDBgzRPstgzBLZcqmlcLMMlmdLQBZT
+CWfvvhfWrlllSSRrdQrQDQGQdTRr
+jsNctMZLmMZLMmmmbbNZswZNqBTHPHzBMHHTMGqBRMRPDQqP
+jcwjntLngngplgFhgRvJVp
+vchzqzwlhzRqzVZQwqtVPZLnLLbDnDFnbGLnDbPLDGWD
+pBTHpdpHsrNBBsgdrdCpCpCgRFCMFDLFWWnFWLRRGWbDFGSF
+prsBHfggjpjjcRQlqvtw
+VDwzLQrDDWrrwWbJrVJwVrVQfMfSCNPMfSlMlPcMmThChf
+tsjFdsRsgtRmGZHpHRgBClSlGSClcPhGCfPlllll
+qBBFBZZpmgdFHdstjFJbzVwJVqJWWbrvWJDL
+mgjZmrqmdsmGtDplglJgRVVc
+nPhnLvnHLtLnWzzcNwwcchVJRflhpc
+SnnLntLWZsMqZrSZ
+jcrNfnrNLNNqFgbDfCSgSQbS
+zPPHtMrGGptvTWPVvzvHRgQsbDsSRRCCQbtJsJDS
+wHzrWVzPwThGGwMHzTGGPGwhdlZnBndZLljNjBcLdZdNBN
+qNPhNqddBNhqvPhFvllNgNBHCrrCQnjpCfPVJnnJQJCjJj
+ZZbZTZcmGWWMDWRSDnBVQCjVDffJjnnVCJ
+SGBRTTZGGcLSSWTScsmcMbGlhgwFqslhzqggghwhNvwwvw
+GCCPwpsBqNSsBPpSCrSshzQzLhTvQhqTnhtTVQcT
+JDjFJfMJgWbWWlDJcnvvhvtdLnjnzhjz
+FlDflbZfZgJgMgbmgZJfSpGCvvrGrRCpCBrZRprw
+HwqhgFGSMgPPCGQQQnvvcpjn
+BllbdfRBsBmsmZlBTmQCjTnNWNCmNmvc
+lJDlBflDdbbRlLbfsbZBJtbRqrVFPnwwwhVMHwVrgJwwrSwH
+LTvLtTFLCddFTTthsbVVmHHcqVHmWRcmHL
+lBgwwNggwMwNVbjBCQcCqCRB
+nCMCwZGGNGJnGhtrzsdDDndtsF
+ZlZdJJplLZBDpJjNJlGjQCLmCQmTwVVCbQQbqWCT
+SfgFzftrnRzMnVbPPPQmPq
+FfmrRvgShchvFfghzRvgtvFBpJDpcGNGdBHJlpDDDJlDJZ
+LdNrLzjdWQnrDHsD
+tBZmBZtVZpldVMPRnsRQsnnsHVbRHs
+MlfldwMBBFMZTSFTSqLqcvSJ
+nJqBlvvBjHhBcqqRrGPrTrGpBCGzTG
+MfVCVMLZVZtQCdtLMtQtQSSSTSzFRSRPFpFRGpdTFd
+CCQQtQVgfbbQNggsNfQZZbHbcWmnhlhnvlnlHjJWvnhv
+SGmmGwVwnmhbhnhwhhwbdMgNNgjmvMDrJTCgmBTBBj
+ztFWcWQQfcRzzRFllvjDjggjDDfBgJMBgC
+QtzcJtFtqcFQRRWRRQWFzFGpVnVSGLLGZVGVqddbLqGL
+tBmdmQtjMMqDLqBtttQMjDdwwgwccMMbffllgzncwfFflF
+TPVHTVsRsJVHVrVvHvrRhVJbfCgFbzwbCGgFlwgcCwbn
+hssVWnRrTVZSSZZqjLddWtLBddqtQL
+WhhtGZtZGQZmvCfCwtvhqgbfdDJdfjlSDlSlBBJDSg
+rHnpFHnDrdBggJngnL
+HVcTzFPNzTpPPVrzmtwtvvvmNQwDQvWw
+dStBwStGGBrNnBdrSSMzvjhgFcvvDcnnvPDn
+RLZbCWWJbHRsTHspZWLcDWcPPhzczfjgPjjvjz
+ZmLHJqJsLJJHLRsmmmGSztQdQzmNBrBN
+JrmRVdvcmvvmvvRTdBVVfjFQLwjqLFLWFMqwcFjz
+DDhhttDHHHbHSnsDbHqMqzwQLLFwLsjjLLQf
+bSbPthtgGQPNPHnSDChCRJZZJRCZdCrCBZZZZvJd
+rqvVqNJpVVNwnqqTwthMMq
+jsFRFDQRLQDQmsPRmQsmcQFMzGhwBGBhTzTTzHnRhnhBhRwz
+dCccQcQsFCmCQfbJbvZMNZfJrJll
+TGjrrTRLHvrQrFDCrmzzVm
+NwWqqhndWtzDQhCzVCsh
+CSSwNNwqgBBBBbGGvLTTvb
+fRBRBHCVRRzcCdZHvRvZVCZLNjtwtNwNTtLjNtTpTNttfS
+DZshMssZmTMjwjSLtw
+QPrJDDJsPDFmFrFDscHHRzrcvccCZRVzrR
+zgqzLLvlvdgpgrWpWW
+RnJmNRncnScFmZSScrJQQdbpGdHbWHtPHpBHsdFdsW
+JDfRcrSnmDSJcNfrNZNjvlwjhllhMzlDqMqMvh
+fDLzSMLhhtDWMvtjCRRZjCHHJjChHN
+pmTNpVwPNbPwPBFRqRJqjCnFjZFV
+dTwpddsTbgbQBssprsgtvgcNLzWMctfSgcfWLt
+fbBsBTsNDhGBGZcLLLJJQffQLQ
+MpsCCMHClsHQqZcQWLqR
+FtjdCFzVljFlslVCpFrFjPhggBGDgNSTTgbGNmbGTr
+HqTfmsCFmPlGHddNVGpLhz
+JjjcQQJgjZvZZzzwgpNVGwLGgV
+nQnSbDDRbSQJQQpRZtZcZZsPPrFfWCPFWlrFsFPqmqFt
+TgTDDrCmqJDGLrhqLmLGqDQRFtttjMbQZJjtdtjFdsdF
+WHffcHWnlvvcSSWzPVvHpWWVRbFdQQtQnjwZFMwZtwddsZbd
+cBpPplVVPfvVGBDLGCBqmmLM
+dlMMmnmjvCCjJrrvMdgHcbcFbqFbzQrFbGzb
+tPhRBRZPtZRshTzRsNShRZNGDfGgFFbFQqbGHDHbqfGD
+TSPhBVsTwRBTpVtRZpVhZLJjWzLjJlJlJvmwWWzwWn
+WcvLLgLcczLTDtccbLcgzMMfPsGwRPjwfMwHMfMvMp
+QVmlPQCdJlJJJlFJJJnPQQhlwwMMMnMwNMpwMGwwfswwGMsR
+lrSCZZVFhPSZgzgWttWBcc
+bwbbZLlbwlJhBzFCgtTGRGQldQRmQW
+SSnpHnPHqpmggCWgdT
+PPscHHTfcsPSDVfVssjvwFJLBJFjFJJZFJLNLwrL
+nLgDSHgwRgGnHjjNfTRhjPVpWV
+BstQsvhQZQQbMvCvMPVNWpPcTjfmPmmW
+brtCrtvtzrhdSDJDwh
+dTQTwgmZQbDzzMQCCl
+WLLtntFnfnRHbttnSRRzSMVGDDMGzVlV
+JsPhFtfbLWnsLPLqgdJcjmcwTwjcdw
+wMwMbMRRBBMLPBlhLRQlhPcWzgJNvJtzWNtJptpgjJgpBj
+TnmGGmVnFFNSZsnZqFsWzWjrTJzvzWvWgWtTWz
+qnHGnVSsqZCddnGCGCSNdDbLQPcLLQlDhPRMhb
+NGsBTBlqsvfQBQqsTLTFltRMmRwmmHmFtPSRhM
+gjZWJWCZdDpjggDdgnpWdZZJtFwFRFFRMwbbmRPtShnwRbtt
+zZpSDDgpzcDddjVWggJsQGrfQvrQcTGTGrTrqr
+hpJchhFWMpRDWHWcDGnCGrnGnwPTwpQnCt
+bmgddgmlmjjbfddgmmmNvGQLrtfTwrTtLtGTLQVQQP
+qqbmdZgzZbvgPDccHcZPhWWH
+VVrdQZZrZSZFgQTTTzggrVZVMlfBBfvcMBCBslMhBvsMBSff
+bQwnHwbNpwcsCwjMBw
+pHqqPnJHqpPNJFzqTzQWWDQQZq
+HgwTDfgBwBgcRHqRRjHqHTzQQClSzvlzPVSQLvbbPC
+MnhtNZNnJpWpGhMQbCCPVSPLNmSPQQ
+rrhJMFJJZFJpHcjRLFRfHjgj
+vGvGMBlttBltvjdgbPsrsDWdjPPP
+HnJQHVqNmQHmZsDZPPrDWpgFps
+JSqJQVVDqqVfJNfRffGSGMBwGTCCCTlBMSBl
+PsFZPfGbDNbtQmCCmCBBbmmL
+dcRdhSrCqjThTRcTpLzHQzTmpmlgBz
+hhhcqCvwhhVhfPNvsMstZtsZ
+VvGwBBwvZtGgfZCqShnFFjSstCMC
+NlTRdvpDdTRNzdTHHnMssCnCnCqjSz
+LvWvPcWLpGwBwVVgVc
+bVVmSrLmLSJzTZMSFTBdMj
+QnvqRGGDvWpQWGDpvsRZLBzTRjBTtjRTPtBF
+QWGvDpqcvpGWQpGngqGQGwpLhJVNJcrbfrVbfbhHrmlVJHVV
+NGRGPZWZpblGcJtfssSSsbffCs
+gwRhjvrgjmwgnzvJJJtVCtHJqs
+rrmLrhwFFmmTMgFRjNZWNpZlZLppQNcDWP
+qsHZsHZrTBtZrHBNFCJGWrMcpcddWGJWLG
+mRDDzbPVDVlVDgbgRRvmwCcWdGvJwGddpvLm
+PnfDbPbVzDbVfjnnlbzhVFsspBSfFsssHQNTBpFqNQ
+gCmtbDqPVVVqggCGqTJjHMpMQfgMpMHQQpcM
+zNZnsSLzZzrlRhTTJMHppjfHSpvp
+nhdrBsLlRRrdTlsTVmCmGqDVFdtDPGwV
+FnqNfdGfgzmPLGmj
+blvVvbsRwgnzjCPcbT
+RWWvtvphnZQZwMBNdHfNDBZZdq
+DMRhDhdvnjhnPnvPMfdZSGTccGJFjGFFpFpFTbTpTW
+NVgVmtzVlLBmgztsBNmtgCmqFpJJFGGpGbrcGGsrcpbWPr
+zwBztLBzllQPDZvfQZfRfHSR
+mFCgPzmqgtPPqMmFWzbMttcRGvRclvHhWGGcZvclRfHh
+psSNnhnLGnwZHZGv
+hBpNLTNLBhsPmbCgBtPDbM
+JsbLLWLJRfQFnccmQhtvvPCP
+dwgrVwGpgVhCrrhPDHtC
+gpGSjpVdVpVppjjVZBwdCbFRWLzLMSRMbNzfzbWR
+DmMQMJmnmGwzGwwG
+ZcLcgLgcRsZSctHFWLGfjjBwvbvBsvjpfhGb
+GgFPqFtLRHLFSHLRRFRHHtMnJVNCQCrJCJCnMJDdnqDV
+tqdqFqdsRdVdtHMNdRZHTZLrHJgrlZQPJLgr
+GGwVcpGznmhbWhwcVVgzTrDrDDLZlTLLZQrJ
+nhbnbfjcnfMfFNVtBq
+QHmPNZvfCLsSwJSm
+pDhjpVDFcRBpFFjjMnRcVhpFCzbzsZbSSCtwtLMSLZLLtLbs
+FRjrnRchnfHPrrZlHl
+bjjMbdChgRDZthpQpRQnwRTprRwS
+mGzJsGsHzHGPvvvqvzGzSnglSJrrwQgnlQQSrlQl
+qvzHqHLHmHgPsNBdCdZtVBtVVMBFbh
+CctrCwrdpTwcpVrdpTpcrcnSJQttvQPHJQNQnQNjvvHQ
+zsqRlslRLqfgRmWsRgRzqzQnHjSBSQWJHPhHnSvHnJJJ
+GRgllbgfRgbzfRmwwcGdFMcTVPrFCF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/04/04.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,52 @@
+using Transducers
+import BenchmarkTools
+
+const input::String = "04/input.txt";
+
+struct Range
+    a::Int
+    b::Int
+end
+
+function torange(s::AbstractString)::Range
+    a, b = split(s, '-');
+    Range(parse(Int, a), parse(Int, b))
+end
+
+function containsfully(a::Range, b::Range)::Bool
+    (a.a <= b.a && a.b >= b.b) || (b.a <= a.a && b.b >= a.b)
+end
+
+function overlaps(a::Range, b::Range)::Bool
+    containsfully(a, b) || (a.a <= b.a && a.b >= b.a && a.b <= b.b) || (a.a >= b.a && a.b >= b.b && a.a <= b.b)
+end
+
+function parse_ranges(fh::IO)::Vector{Tuple{Range,Range}}
+    collect(eachline(fh) |>
+        Map(l -> split(chomp(l), ",")[1:2]) |>
+        Map(es -> torange.(es)) |>
+        Map(Tuple))
+end
+
+function part1(rs::Vector{Tuple{Range,Range}})::Int
+    (rs |>
+     Map(es -> containsfully(es...)) |>
+     sum)
+end
+
+function part2(rs::Vector{Tuple{Range,Range}})::Int
+    (rs |>
+    Map(t -> overlaps(t...)) |>
+    sum)
+end
+
+function run_04(f::String)::Tuple{Int,Int}
+    open(f; read=true) do fh
+        rs = parse_ranges(fh);
+        a = part1(rs);
+        b = part2(rs);
+        (a, b)
+    end
+end
+
+println(run_04(input));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/04/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,1000 @@
+1-93,2-11
+26-94,26-94
+72-92,48-88
+36-37,37-52
+2-98,1-98
+1-83,1-84
+74-79,76-76
+66-85,66-86
+6-73,6-73
+31-57,30-58
+1-98,1-98
+28-47,55-97
+29-71,70-72
+40-53,40-53
+14-71,39-71
+19-98,18-94
+94-96,81-95
+79-98,79-97
+52-66,60-61
+2-3,8-89
+53-59,59-83
+79-81,3-80
+14-84,84-92
+90-90,7-89
+10-76,11-76
+9-31,10-12
+8-8,8-72
+2-97,1-96
+3-33,2-94
+3-5,4-99
+46-94,8-94
+97-98,14-92
+60-98,81-99
+11-98,11-97
+27-82,26-81
+21-61,12-18
+26-55,26-56
+89-96,97-97
+29-30,29-31
+66-90,40-87
+7-49,8-88
+37-61,39-58
+8-65,9-96
+7-72,2-51
+14-73,15-56
+7-11,16-24
+12-83,13-85
+72-91,7-71
+78-82,56-77
+1-46,15-46
+1-76,1-75
+75-98,5-98
+37-41,22-41
+1-1,2-98
+76-94,77-93
+88-88,4-89
+86-87,38-90
+85-89,46-86
+64-99,1-99
+16-48,32-96
+6-95,6-95
+44-68,43-49
+19-78,19-79
+35-95,7-34
+72-72,32-71
+21-26,24-26
+20-57,21-58
+17-98,17-98
+22-97,21-98
+62-92,92-99
+1-74,1-75
+9-75,10-74
+5-7,4-8
+37-41,4-81
+3-96,4-99
+92-98,94-96
+69-89,75-88
+13-29,14-18
+35-48,42-49
+10-11,11-95
+17-33,32-32
+16-80,61-77
+38-41,40-42
+6-79,6-80
+51-95,50-52
+18-94,19-33
+95-99,15-96
+18-37,19-47
+25-33,24-31
+9-9,10-98
+5-72,6-72
+6-6,7-95
+39-96,38-84
+79-95,57-78
+61-67,61-61
+44-95,9-94
+69-93,16-68
+24-24,23-95
+56-90,49-57
+13-82,13-13
+5-94,4-94
+46-61,44-46
+3-37,7-84
+3-73,3-72
+2-2,3-95
+12-94,24-94
+37-58,37-57
+79-95,7-78
+10-77,76-76
+4-98,5-97
+64-99,27-99
+68-68,69-69
+18-28,18-29
+58-95,9-95
+4-93,5-94
+9-84,85-85
+50-89,51-90
+38-97,2-39
+22-70,78-90
+62-68,67-67
+36-44,36-44
+59-59,36-58
+97-97,1-97
+14-15,15-94
+90-90,3-62
+2-4,3-80
+29-97,81-97
+8-35,34-54
+14-57,14-60
+42-78,10-56
+32-99,31-98
+31-87,86-87
+44-57,44-57
+1-92,92-92
+8-69,5-83
+33-47,34-59
+94-98,11-98
+60-66,67-76
+20-21,21-81
+18-76,17-76
+24-61,24-62
+48-48,1-49
+28-84,85-91
+4-51,4-50
+30-32,31-69
+38-70,39-39
+28-92,37-79
+22-65,22-68
+29-56,9-46
+11-97,2-99
+4-98,31-94
+29-92,29-93
+93-97,32-92
+24-27,25-48
+54-55,6-77
+10-81,82-96
+27-94,28-89
+32-81,47-81
+64-83,65-97
+41-49,50-79
+99-99,14-94
+66-78,66-77
+16-95,17-95
+98-98,3-97
+2-6,6-53
+26-26,12-25
+2-54,3-86
+59-95,94-95
+40-62,2-40
+9-90,9-91
+3-53,2-52
+91-93,88-92
+63-98,64-99
+32-68,68-84
+34-77,74-80
+2-83,1-2
+32-79,60-73
+96-98,3-96
+28-74,29-87
+8-96,29-96
+50-64,50-65
+26-72,15-73
+63-80,44-86
+10-87,11-86
+5-94,36-94
+5-93,6-92
+3-92,4-93
+83-83,14-83
+9-9,9-40
+88-96,12-89
+31-56,34-42
+83-96,28-84
+5-6,6-36
+31-96,30-96
+26-82,41-82
+95-95,18-96
+32-71,31-71
+55-69,56-85
+1-87,2-98
+15-92,9-91
+1-76,1-76
+3-45,3-27
+53-59,52-58
+1-97,5-96
+2-78,4-78
+65-84,84-89
+74-80,79-79
+36-90,37-66
+3-66,54-74
+35-79,35-80
+76-76,75-75
+66-77,65-78
+3-91,3-90
+25-45,26-62
+35-35,36-82
+28-73,29-72
+36-96,37-64
+46-85,85-87
+70-99,2-99
+27-65,36-39
+8-70,70-84
+39-47,38-50
+66-89,23-66
+2-93,5-92
+1-70,92-92
+12-95,15-95
+44-85,45-84
+17-54,17-72
+20-23,19-31
+27-37,14-33
+16-96,82-96
+8-61,7-62
+11-91,73-96
+3-93,40-81
+30-30,29-90
+7-38,38-44
+70-82,12-93
+53-57,54-58
+37-66,66-99
+94-96,11-95
+11-97,11-96
+39-56,40-55
+27-74,1-96
+43-48,3-98
+62-79,63-79
+16-22,24-25
+1-96,2-99
+58-83,57-83
+43-76,42-67
+41-46,8-46
+2-52,2-55
+50-80,28-51
+9-34,9-9
+47-48,46-46
+47-85,85-99
+29-44,29-45
+20-89,19-88
+51-58,60-75
+57-58,57-57
+39-90,38-89
+18-77,20-76
+55-76,54-62
+26-83,25-82
+2-87,2-86
+1-83,2-94
+7-88,88-89
+6-33,7-99
+17-18,10-13
+40-99,40-99
+14-66,31-95
+46-98,46-98
+50-76,73-76
+39-45,2-80
+19-76,18-23
+19-92,98-98
+95-95,1-94
+1-86,87-88
+44-86,45-87
+4-99,4-87
+15-30,14-16
+11-66,13-76
+1-84,14-55
+2-72,2-87
+34-83,77-83
+13-90,30-33
+55-77,49-54
+18-25,7-16
+46-46,47-91
+14-86,14-58
+14-75,79-99
+13-45,14-46
+6-26,7-81
+24-99,35-48
+3-95,94-99
+71-81,20-71
+30-30,31-82
+15-15,14-41
+81-92,82-87
+3-49,48-67
+2-89,2-90
+18-92,19-92
+9-76,8-70
+40-47,41-64
+53-81,81-88
+44-86,44-44
+4-90,98-98
+8-94,95-95
+31-31,32-78
+31-82,30-83
+59-59,40-60
+48-69,48-68
+9-28,28-51
+23-90,23-91
+25-36,57-93
+31-88,30-32
+6-99,4-15
+9-68,28-69
+2-99,3-99
+3-31,30-32
+4-99,4-98
+17-74,11-18
+19-91,19-70
+74-97,75-89
+80-80,33-79
+10-76,2-4
+4-98,18-94
+1-63,1-63
+5-97,5-96
+16-63,16-81
+2-92,91-92
+1-78,79-79
+60-99,35-98
+74-84,39-73
+9-87,9-88
+78-85,77-78
+1-1,1-43
+11-44,12-43
+33-93,9-98
+6-74,5-65
+4-50,4-6
+27-30,25-39
+3-69,39-45
+83-85,86-86
+10-49,50-50
+81-83,8-82
+17-17,18-63
+10-24,20-24
+28-85,86-92
+36-36,37-69
+49-73,46-49
+8-88,7-88
+8-71,9-62
+10-47,46-75
+95-95,92-96
+10-97,7-7
+4-9,3-97
+58-93,43-95
+41-94,40-75
+5-79,3-79
+45-76,46-77
+15-88,7-14
+3-93,3-93
+96-99,4-97
+4-9,6-13
+69-77,5-61
+47-56,71-72
+98-99,15-97
+19-57,53-54
+14-58,37-59
+5-90,22-97
+79-81,63-80
+32-65,33-70
+2-50,50-50
+84-96,7-96
+26-26,27-95
+99-99,2-98
+21-39,21-21
+53-80,54-80
+69-98,59-68
+51-57,57-59
+56-59,29-72
+1-98,2-99
+23-82,34-83
+29-67,30-67
+69-84,85-85
+7-78,78-88
+26-80,81-81
+12-43,12-97
+46-76,45-78
+10-22,9-94
+26-29,25-36
+26-85,26-26
+14-98,15-19
+5-23,9-96
+54-55,55-70
+97-99,2-98
+39-71,3-26
+6-96,6-99
+24-89,62-89
+21-37,37-38
+16-98,15-99
+62-64,2-63
+4-73,4-72
+4-58,6-59
+14-68,14-68
+48-50,49-88
+51-82,45-49
+17-75,4-76
+31-78,78-78
+22-34,14-34
+2-96,1-92
+1-99,98-98
+41-65,64-73
+80-82,17-85
+23-97,22-59
+19-54,16-58
+85-97,47-86
+4-24,23-50
+12-91,90-90
+91-98,91-98
+10-63,9-9
+49-82,48-50
+22-80,23-99
+12-82,13-98
+1-60,2-47
+28-50,19-72
+44-61,44-44
+98-99,66-97
+37-37,37-83
+22-24,23-25
+65-71,65-70
+10-90,89-93
+10-42,42-66
+13-91,90-99
+38-62,48-62
+3-98,4-99
+26-68,27-68
+8-71,82-83
+5-49,50-70
+1-35,1-36
+20-78,79-79
+39-59,39-39
+61-79,61-80
+94-99,95-95
+51-82,83-90
+1-57,2-72
+10-19,11-42
+55-99,54-54
+24-90,89-94
+24-34,34-88
+98-99,45-97
+27-65,2-90
+6-73,5-73
+73-89,72-90
+81-83,78-82
+3-99,3-98
+96-99,52-95
+75-92,6-92
+58-58,12-57
+17-38,37-41
+75-75,5-75
+22-46,22-47
+89-97,2-98
+53-70,19-53
+25-90,89-93
+36-54,46-55
+1-98,97-97
+34-36,2-33
+32-55,31-85
+2-56,56-68
+1-59,1-58
+83-84,1-82
+3-67,4-66
+65-84,41-85
+7-73,16-73
+66-66,23-68
+42-83,42-76
+17-91,17-82
+29-78,29-36
+29-82,29-81
+17-55,54-55
+64-77,63-87
+85-85,45-84
+4-34,3-3
+16-51,52-73
+4-96,39-95
+1-94,31-94
+1-87,2-88
+11-24,12-25
+1-1,3-79
+26-64,13-17
+35-81,54-71
+1-44,1-43
+59-62,22-24
+14-77,8-14
+64-83,83-99
+64-87,87-89
+1-15,15-99
+43-57,48-48
+2-25,2-26
+39-78,39-79
+13-98,14-56
+5-33,75-93
+98-98,3-98
+11-72,10-72
+6-92,5-6
+4-57,4-56
+94-94,40-95
+55-85,55-84
+46-75,45-74
+35-94,34-94
+33-86,85-90
+85-96,42-86
+7-92,5-92
+11-33,10-33
+43-73,38-77
+22-96,1-99
+5-98,4-6
+79-83,78-81
+4-73,32-72
+14-20,20-52
+31-89,30-88
+18-74,9-75
+2-65,2-64
+17-32,33-41
+4-99,8-98
+96-97,77-96
+91-96,63-94
+23-71,52-54
+40-89,49-56
+10-89,10-90
+21-57,21-88
+32-91,33-57
+44-97,44-44
+5-65,4-86
+19-60,18-45
+30-79,80-80
+9-12,8-12
+60-60,59-59
+18-57,48-53
+32-71,72-85
+65-78,35-66
+27-44,41-44
+43-72,14-42
+28-97,28-99
+35-55,35-56
+27-50,1-51
+69-69,51-70
+65-66,5-25
+4-20,3-20
+30-91,31-91
+61-90,61-86
+38-74,98-98
+45-82,78-81
+64-64,5-65
+3-23,2-99
+26-45,2-26
+97-98,19-75
+76-76,5-77
+13-71,12-72
+17-53,52-99
+15-86,87-87
+57-98,23-29
+15-69,9-12
+8-99,18-91
+94-94,19-95
+1-93,93-96
+10-92,52-92
+47-54,70-85
+13-36,12-13
+7-96,15-47
+10-98,11-98
+79-94,89-95
+28-80,80-81
+36-72,37-56
+67-83,67-83
+91-91,80-90
+8-78,1-84
+16-41,40-42
+3-6,5-7
+12-96,8-12
+68-95,95-95
+88-89,16-92
+97-97,43-96
+20-35,34-92
+45-93,46-92
+8-19,9-32
+30-44,13-22
+5-50,6-50
+30-85,84-86
+11-58,57-74
+36-75,7-26
+6-86,3-6
+21-95,94-98
+10-94,14-93
+72-72,7-72
+50-65,51-97
+67-67,68-75
+97-98,10-94
+37-75,33-38
+4-89,4-98
+3-97,2-98
+3-50,47-68
+51-89,52-59
+50-85,84-85
+97-99,29-98
+95-97,35-96
+51-98,99-99
+4-99,75-75
+35-62,5-62
+22-56,21-56
+38-43,49-86
+5-38,5-15
+11-70,6-69
+63-86,28-86
+8-89,10-20
+14-94,4-97
+10-51,10-50
+3-40,4-41
+45-46,46-85
+61-97,62-96
+5-88,5-92
+29-92,91-96
+89-94,3-88
+3-71,2-72
+33-81,34-82
+48-57,47-84
+2-83,48-76
+24-67,24-66
+30-90,30-89
+82-82,58-83
+52-58,52-59
+23-80,8-80
+33-79,34-80
+22-70,23-70
+24-59,25-77
+1-50,8-61
+19-91,91-96
+6-6,7-85
+84-84,81-83
+25-41,16-41
+1-18,2-8
+40-86,78-83
+24-40,41-84
+92-96,3-93
+5-97,2-3
+59-95,94-98
+13-18,13-19
+1-68,5-65
+39-66,66-84
+12-56,8-9
+37-94,38-71
+27-74,27-75
+18-18,19-92
+14-29,14-81
+91-94,11-90
+61-77,3-62
+5-7,6-74
+24-67,23-66
+4-96,4-98
+40-94,41-93
+30-51,52-91
+3-35,1-35
+24-40,39-39
+91-91,76-90
+13-89,14-69
+6-95,7-96
+2-72,1-71
+71-72,72-94
+5-6,6-58
+14-26,28-77
+63-99,57-99
+32-88,4-88
+3-64,63-63
+62-86,85-87
+48-92,24-47
+69-74,62-80
+10-98,53-56
+22-87,1-22
+23-87,92-98
+30-76,31-76
+20-66,21-40
+23-87,87-91
+10-10,11-12
+36-74,75-94
+36-36,10-35
+20-73,14-81
+56-68,55-66
+8-98,7-61
+4-96,4-97
+13-90,1-90
+45-87,45-85
+66-68,24-67
+53-60,39-66
+98-99,2-97
+6-81,80-99
+4-98,4-97
+88-88,14-87
+20-57,21-38
+25-76,24-76
+8-8,10-61
+13-46,13-45
+71-98,70-97
+3-6,9-41
+18-41,40-40
+9-70,21-36
+33-83,11-33
+8-22,80-83
+5-37,6-36
+32-67,67-87
+26-48,25-47
+15-70,69-71
+11-94,15-93
+16-39,16-40
+81-85,81-85
+23-75,23-74
+55-79,55-79
+30-85,29-86
+7-79,78-78
+13-15,7-16
+82-82,29-81
+2-69,15-68
+63-91,52-63
+35-86,87-87
+17-96,18-96
+57-57,58-87
+46-54,46-53
+26-78,27-93
+12-81,12-82
+15-85,5-20
+28-88,36-88
+62-73,63-72
+42-43,17-43
+56-97,56-98
+20-65,17-66
+32-99,33-57
+14-96,15-95
+8-25,7-25
+56-60,56-59
+20-86,19-20
+19-97,20-96
+86-86,58-87
+60-70,59-72
+9-50,32-51
+8-10,14-62
+56-89,88-88
+46-93,92-97
+12-25,1-66
+11-16,18-95
+62-64,17-61
+78-89,43-78
+30-92,30-90
+68-86,69-71
+89-98,33-44
+9-20,8-20
+57-77,16-57
+12-86,11-53
+7-11,28-53
+13-92,14-82
+49-91,92-92
+60-86,60-99
+73-99,73-97
+34-67,54-63
+75-76,43-76
+9-95,94-96
+37-69,38-77
+76-77,45-77
+42-69,42-68
+2-35,2-14
+95-96,15-96
+1-97,2-98
+31-57,31-56
+34-37,33-68
+25-54,24-54
+19-43,9-59
+38-94,93-95
+38-73,38-73
+58-85,58-84
+64-98,58-63
+12-22,12-21
+13-13,14-82
+17-55,17-81
+90-97,88-96
+8-99,47-99
+2-60,35-60
+5-66,6-60
+78-78,4-79
+61-68,48-90
+23-94,93-97
+13-69,12-12
+17-74,1-74
+17-47,48-48
+56-71,70-72
+17-17,17-99
+11-98,12-63
+58-58,58-59
+64-64,65-94
+83-91,1-65
+31-79,78-80
+4-77,78-78
+53-80,3-52
+34-63,62-64
+97-98,1-98
+93-94,41-94
+49-79,50-80
+14-66,14-66
+53-89,45-53
+11-47,10-99
+60-65,61-85
+27-78,26-78
+18-92,19-98
+31-45,17-31
+6-42,5-61
+52-79,51-84
+82-86,83-92
+8-72,71-82
+7-39,6-6
+3-75,75-99
+22-22,22-55
+6-88,6-88
+3-78,34-71
+70-70,11-71
+88-90,52-89
+11-14,28-33
+61-71,50-60
+80-84,7-84
+5-97,98-99
+2-79,3-80
+8-94,8-94
+5-83,83-84
+41-41,10-40
+51-76,13-96
+47-97,48-98
+6-96,7-96
+40-47,41-51
+22-97,22-23
+3-62,3-61
+48-80,43-80
+86-88,8-87
+80-80,52-79
+30-43,29-44
+57-75,56-75
+4-85,3-77
+39-83,38-79
+2-50,1-51
+12-93,11-93
+4-81,3-21
+80-98,79-79
+44-52,51-53
+2-93,92-93
+15-86,2-15
+5-85,5-85
+36-73,36-72
+4-86,3-4
+7-27,8-28
+11-70,69-71
+36-60,37-60
+10-10,16-55
+87-92,88-94
+21-93,20-92
+16-16,15-92
+18-44,19-45
+24-24,24-79
+50-63,15-76
+64-68,65-66
+34-36,30-35
+83-85,2-84
+37-82,37-82
+17-69,17-80
+29-30,30-90
+9-95,9-94
+58-86,58-58
+96-99,17-96
+4-52,12-64
+7-99,8-99
+7-75,7-75
+2-52,26-75
+92-92,9-93
+2-64,3-70
+2-6,5-69
+19-86,9-19
+76-76,7-76
+4-99,1-99
+44-74,2-43
+20-97,79-96
+31-75,31-74
+13-97,13-96
+76-90,90-94
+3-63,4-94
+16-17,17-98
+2-84,84-98
+6-90,5-89
+23-25,24-24
+56-78,78-80
+8-63,7-29
+23-29,23-29
+26-94,25-95
+51-70,51-51
+9-57,14-57
+26-31,25-28
+59-96,59-94
+3-54,1-1
+57-69,31-57
+6-97,5-97
+2-88,55-82
+74-99,73-77
+36-44,36-43
+15-15,2-26
+3-59,4-69
+25-79,26-81
+97-99,59-98
+10-89,74-89
+56-93,92-93
+73-75,18-74
+89-89,12-88
+30-91,31-94
+16-24,15-92
+52-93,51-93
+42-93,41-98
+73-97,21-99
+12-88,87-94
+10-14,10-15
+83-95,53-82
+72-90,68-72
+52-66,14-81
+70-72,11-71
+43-43,13-42
+2-46,2-45
+46-94,76-89
+27-67,9-67
+9-89,28-89
+2-92,92-92
+5-85,86-99
+38-86,12-38
+4-98,3-98
+1-82,6-82
+24-30,24-29
+28-93,27-68
+39-76,5-38
+6-19,5-86
+12-14,13-17
+86-87,29-86
+12-91,12-91
+3-99,3-99
+7-84,6-65
+30-45,31-90
+11-14,21-57
+8-62,61-62
+20-92,20-91
+8-89,8-89
+18-36,6-14
+18-45,17-45
+66-66,5-65
+95-96,11-96
+1-3,4-74
+12-94,94-98
+25-58,25-57
+15-70,15-69
+6-82,1-6
+4-5,5-12
+28-60,59-64
+2-92,92-98
+61-85,86-94
+48-97,39-97
+51-53,42-73
+7-94,93-94
+19-49,15-68
+14-56,3-56
+21-85,20-84
+18-19,19-63
+2-98,3-99
+86-94,73-99
+62-64,4-63
+18-86,19-86
+24-56,25-96
+93-99,16-93
+37-96,36-50
+16-91,15-53
+27-32,28-34
+16-71,15-16
+55-57,56-70
+82-93,70-83
+24-66,24-83
+1-96,2-95
+8-18,9-28
+1-59,1-60
+26-57,11-26
+45-50,46-48
+7-90,8-41
+56-92,57-93
+8-91,8-91
+1-63,6-12
+48-96,96-99
+26-99,26-97
+51-51,52-68
+47-50,6-46
+3-64,13-40
+5-75,3-3
+66-66,9-65
+92-92,7-91
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/05/05.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,98 @@
+const input = "05/input.txt";
+
+mutable struct Crates
+    stacks::Vector{Vector{Char}}
+end
+
+using ParserCombinator
+
+crate = (
+    (
+        (E"[" + p"[A-Z]" + E"]") |> s -> s[1][1])
+    | (E"   " |> _ -> nothing)) + (E" " | Eos())
+crate_row = Repeat(crate) + Eos()
+
+crate_base = Repeat(P"\s*"+ p"\d" + P"\s*", 1, 100) + Eos()
+
+function parse_stacks(lines::Vector{String})::Crates
+    stacks = nothing
+    # start is the line on which instructions start.
+    start = 3
+    for l in lines
+        try
+            cs = parse_one(chomp(l), crate_row);
+            if isnothing(stacks)
+                stacks = Crates([Vector{Char}() for i in 1:length(cs)])
+            end
+            for (i, e) in enumerate(cs)
+                # inefficient but saves reversing
+                if !isnothing(e)
+                    pushfirst!(stacks.stacks[i], e);
+                end
+            end
+            start += 1
+        catch e
+            @assert typeof(e) == ParserException
+            break
+        end
+    end
+    println(stacks)
+    stacks
+end
+
+struct Instr
+    n::Int
+    from::Int
+    to::Int
+end
+
+instruction = E"move " + PInt() + E" from " + PInt() + E" to " + PInt() + Eos()
+
+function parse_instructions(lines::Vector{String})::Vector{Instr}
+    v = Vector{Instr}();
+    for l in lines
+        try
+            i = parse_one(chomp(l), instruction);
+            push!(v, Instr(i[1], i[2], i[3]));
+        catch e
+            @assert typeof(e) == ParserException
+        end
+    end
+    @show v
+    v
+end
+
+function act(init::Crates, instr::Vector{Instr}; newcrane=false)::Crates
+    for i in instr
+        @assert length(init.stacks[i.from]) >= i.n
+        if newcrane
+            push!(init.stacks[i.to], init.stacks[i.from][end-i.n+1:end]...);
+            init.stacks[i.from] = init.stacks[i.from][begin:end-i.n];
+        else
+            for j in 1:i.n
+                push!(init.stacks[i.to], pop!(init.stacks[i.from]));
+            end
+        end
+    end
+    init
+end
+
+function endresult1(c::Crates)::String
+    String([s[end] for s in c.stacks])
+end
+
+function run_05(f::String)
+    open(f; read=true) do fh
+        ls = collect(eachline(fh));
+        crates = parse_stacks(ls);
+        instrs = parse_instructions(ls);
+        crates2 = act(crates, instrs);
+        println(endresult1(crates2));
+        
+        crates3 = parse_stacks(ls);
+        crates3 = act(crates3, instrs; newcrane=true);
+        println(endresult1(crates3));
+    end
+end
+
+run_05(input);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/05/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,511 @@
+    [G]         [P]         [M]    
+    [V]     [M] [W] [S]     [Q]    
+    [N]     [N] [G] [H]     [T] [F]
+    [J]     [W] [V] [Q] [W] [F] [P]
+[C] [H]     [T] [T] [G] [B] [Z] [B]
+[S] [W] [S] [L] [F] [B] [P] [C] [H]
+[G] [M] [Q] [S] [Z] [T] [J] [D] [S]
+[B] [T] [M] [B] [J] [C] [T] [G] [N]
+ 1   2   3   4   5   6   7   8   9 
+
+move 2 from 4 to 2
+move 6 from 9 to 7
+move 4 from 7 to 2
+move 2 from 4 to 1
+move 2 from 6 to 7
+move 1 from 3 to 8
+move 4 from 7 to 1
+move 2 from 3 to 2
+move 3 from 8 to 5
+move 3 from 1 to 4
+move 12 from 2 to 5
+move 2 from 6 to 8
+move 12 from 5 to 8
+move 3 from 7 to 9
+move 18 from 8 to 9
+move 2 from 8 to 6
+move 3 from 2 to 3
+move 14 from 9 to 4
+move 1 from 1 to 3
+move 7 from 9 to 3
+move 1 from 2 to 1
+move 8 from 4 to 5
+move 5 from 6 to 3
+move 2 from 7 to 9
+move 3 from 4 to 9
+move 4 from 9 to 6
+move 4 from 6 to 1
+move 8 from 4 to 6
+move 10 from 1 to 2
+move 13 from 3 to 2
+move 17 from 5 to 9
+move 2 from 5 to 1
+move 9 from 9 to 7
+move 1 from 3 to 6
+move 2 from 1 to 8
+move 11 from 2 to 4
+move 5 from 6 to 8
+move 1 from 6 to 3
+move 1 from 1 to 4
+move 3 from 8 to 6
+move 3 from 2 to 8
+move 9 from 7 to 9
+move 4 from 4 to 7
+move 1 from 9 to 5
+move 15 from 9 to 7
+move 7 from 8 to 3
+move 1 from 5 to 6
+move 2 from 6 to 9
+move 8 from 2 to 6
+move 3 from 4 to 3
+move 1 from 2 to 5
+move 4 from 9 to 3
+move 1 from 3 to 4
+move 13 from 6 to 2
+move 1 from 5 to 1
+move 4 from 4 to 9
+move 6 from 3 to 2
+move 11 from 2 to 7
+move 6 from 3 to 4
+move 3 from 3 to 2
+move 1 from 3 to 4
+move 1 from 1 to 3
+move 3 from 9 to 2
+move 1 from 3 to 1
+move 4 from 7 to 1
+move 1 from 9 to 5
+move 5 from 1 to 4
+move 11 from 2 to 4
+move 1 from 5 to 3
+move 1 from 2 to 3
+move 12 from 4 to 2
+move 2 from 7 to 2
+move 7 from 4 to 3
+move 5 from 4 to 1
+move 7 from 7 to 6
+move 4 from 1 to 8
+move 1 from 8 to 5
+move 8 from 3 to 2
+move 4 from 7 to 4
+move 13 from 7 to 1
+move 2 from 8 to 6
+move 5 from 4 to 9
+move 1 from 3 to 6
+move 1 from 5 to 8
+move 1 from 2 to 9
+move 4 from 2 to 6
+move 2 from 8 to 6
+move 10 from 1 to 3
+move 4 from 9 to 4
+move 2 from 1 to 3
+move 5 from 2 to 9
+move 4 from 9 to 2
+move 1 from 1 to 2
+move 13 from 2 to 4
+move 15 from 4 to 5
+move 3 from 6 to 8
+move 8 from 3 to 8
+move 1 from 4 to 2
+move 14 from 5 to 1
+move 1 from 5 to 4
+move 1 from 4 to 2
+move 8 from 6 to 7
+move 3 from 6 to 2
+move 2 from 9 to 1
+move 8 from 8 to 7
+move 9 from 1 to 5
+move 7 from 5 to 3
+move 14 from 7 to 9
+move 2 from 2 to 3
+move 7 from 2 to 1
+move 1 from 6 to 1
+move 4 from 9 to 2
+move 8 from 3 to 6
+move 2 from 4 to 3
+move 4 from 3 to 5
+move 5 from 5 to 7
+move 2 from 6 to 9
+move 6 from 6 to 2
+move 4 from 2 to 3
+move 1 from 6 to 2
+move 2 from 7 to 8
+move 13 from 9 to 5
+move 2 from 7 to 1
+move 14 from 1 to 5
+move 15 from 5 to 7
+move 3 from 8 to 7
+move 5 from 3 to 5
+move 6 from 5 to 7
+move 4 from 1 to 7
+move 1 from 2 to 5
+move 3 from 2 to 8
+move 11 from 5 to 2
+move 10 from 7 to 1
+move 1 from 3 to 4
+move 10 from 2 to 9
+move 1 from 5 to 8
+move 6 from 7 to 3
+move 1 from 4 to 6
+move 2 from 3 to 8
+move 1 from 2 to 1
+move 4 from 3 to 9
+move 3 from 1 to 6
+move 2 from 7 to 1
+move 1 from 5 to 6
+move 1 from 3 to 8
+move 4 from 1 to 4
+move 5 from 2 to 9
+move 3 from 1 to 4
+move 18 from 9 to 7
+move 4 from 8 to 4
+move 3 from 1 to 2
+move 1 from 9 to 7
+move 1 from 4 to 7
+move 1 from 6 to 2
+move 1 from 2 to 5
+move 25 from 7 to 3
+move 7 from 4 to 2
+move 8 from 7 to 9
+move 4 from 8 to 6
+move 1 from 8 to 5
+move 4 from 6 to 5
+move 2 from 9 to 5
+move 3 from 5 to 8
+move 4 from 6 to 4
+move 12 from 3 to 5
+move 11 from 3 to 2
+move 13 from 5 to 8
+move 4 from 9 to 6
+move 7 from 4 to 9
+move 2 from 6 to 2
+move 12 from 2 to 7
+move 1 from 6 to 3
+move 1 from 5 to 6
+move 2 from 5 to 3
+move 15 from 8 to 6
+move 4 from 6 to 7
+move 1 from 5 to 1
+move 10 from 2 to 8
+move 8 from 8 to 3
+move 8 from 6 to 8
+move 2 from 7 to 6
+move 9 from 9 to 7
+move 8 from 8 to 9
+move 1 from 1 to 3
+move 1 from 2 to 7
+move 7 from 3 to 1
+move 3 from 8 to 5
+move 3 from 1 to 6
+move 7 from 9 to 2
+move 2 from 3 to 7
+move 5 from 7 to 9
+move 17 from 7 to 5
+move 2 from 7 to 6
+move 10 from 6 to 3
+move 1 from 1 to 3
+move 6 from 9 to 3
+move 1 from 2 to 9
+move 2 from 7 to 9
+move 2 from 9 to 7
+move 1 from 5 to 8
+move 1 from 8 to 5
+move 6 from 2 to 5
+move 1 from 6 to 1
+move 5 from 3 to 5
+move 1 from 6 to 8
+move 1 from 7 to 9
+move 2 from 9 to 3
+move 15 from 5 to 2
+move 2 from 1 to 8
+move 2 from 3 to 7
+move 2 from 8 to 3
+move 3 from 5 to 9
+move 1 from 8 to 6
+move 1 from 9 to 6
+move 3 from 7 to 6
+move 17 from 3 to 4
+move 1 from 1 to 2
+move 6 from 2 to 9
+move 16 from 4 to 1
+move 4 from 6 to 8
+move 9 from 5 to 6
+move 8 from 6 to 2
+move 2 from 9 to 5
+move 2 from 3 to 5
+move 1 from 6 to 2
+move 1 from 4 to 8
+move 14 from 1 to 3
+move 8 from 5 to 3
+move 20 from 3 to 1
+move 1 from 8 to 2
+move 1 from 9 to 6
+move 1 from 6 to 7
+move 1 from 7 to 3
+move 22 from 1 to 2
+move 3 from 3 to 6
+move 27 from 2 to 8
+move 2 from 2 to 8
+move 2 from 6 to 9
+move 2 from 9 to 4
+move 2 from 4 to 8
+move 1 from 1 to 3
+move 14 from 8 to 5
+move 1 from 3 to 9
+move 3 from 9 to 2
+move 5 from 2 to 8
+move 10 from 2 to 9
+move 1 from 6 to 7
+move 1 from 7 to 5
+move 7 from 5 to 2
+move 2 from 9 to 2
+move 1 from 6 to 2
+move 2 from 9 to 5
+move 3 from 5 to 6
+move 6 from 5 to 3
+move 1 from 5 to 6
+move 4 from 3 to 9
+move 2 from 9 to 8
+move 3 from 9 to 5
+move 23 from 8 to 1
+move 2 from 6 to 1
+move 1 from 5 to 7
+move 2 from 3 to 5
+move 2 from 9 to 5
+move 4 from 9 to 7
+move 2 from 9 to 4
+move 1 from 5 to 4
+move 5 from 8 to 5
+move 2 from 6 to 2
+move 3 from 7 to 3
+move 1 from 3 to 4
+move 3 from 2 to 8
+move 4 from 1 to 6
+move 2 from 6 to 3
+move 4 from 1 to 2
+move 3 from 8 to 1
+move 13 from 2 to 5
+move 4 from 3 to 2
+move 14 from 5 to 7
+move 5 from 2 to 7
+move 18 from 7 to 9
+move 4 from 4 to 7
+move 2 from 5 to 4
+move 17 from 9 to 5
+move 1 from 9 to 1
+move 1 from 7 to 2
+move 5 from 7 to 2
+move 18 from 1 to 4
+move 1 from 7 to 3
+move 1 from 3 to 6
+move 2 from 1 to 3
+move 1 from 6 to 5
+move 2 from 6 to 8
+move 1 from 8 to 9
+move 1 from 8 to 3
+move 13 from 4 to 5
+move 1 from 1 to 6
+move 3 from 2 to 4
+move 1 from 6 to 1
+move 3 from 2 to 9
+move 3 from 3 to 1
+move 5 from 4 to 5
+move 30 from 5 to 3
+move 1 from 4 to 6
+move 1 from 9 to 8
+move 1 from 9 to 6
+move 21 from 3 to 7
+move 3 from 1 to 6
+move 1 from 1 to 4
+move 1 from 9 to 6
+move 1 from 8 to 2
+move 1 from 3 to 6
+move 1 from 9 to 3
+move 5 from 4 to 8
+move 1 from 2 to 4
+move 9 from 5 to 7
+move 2 from 5 to 9
+move 2 from 8 to 2
+move 2 from 6 to 3
+move 1 from 4 to 1
+move 4 from 3 to 8
+move 2 from 9 to 2
+move 4 from 2 to 6
+move 1 from 1 to 4
+move 2 from 6 to 9
+move 2 from 5 to 4
+move 1 from 3 to 1
+move 1 from 1 to 3
+move 2 from 9 to 1
+move 5 from 3 to 5
+move 1 from 1 to 8
+move 4 from 6 to 4
+move 5 from 5 to 6
+move 18 from 7 to 5
+move 1 from 3 to 4
+move 12 from 7 to 5
+move 15 from 5 to 6
+move 1 from 5 to 8
+move 1 from 3 to 7
+move 1 from 1 to 2
+move 1 from 2 to 4
+move 1 from 7 to 9
+move 2 from 8 to 2
+move 1 from 2 to 4
+move 4 from 4 to 2
+move 1 from 2 to 1
+move 1 from 9 to 8
+move 4 from 6 to 4
+move 3 from 2 to 6
+move 1 from 2 to 6
+move 8 from 4 to 3
+move 1 from 1 to 3
+move 6 from 6 to 1
+move 1 from 3 to 6
+move 5 from 1 to 7
+move 10 from 5 to 9
+move 3 from 9 to 8
+move 7 from 6 to 2
+move 1 from 7 to 8
+move 3 from 5 to 8
+move 3 from 6 to 2
+move 6 from 8 to 9
+move 1 from 5 to 3
+move 2 from 3 to 1
+move 2 from 4 to 8
+move 6 from 6 to 9
+move 1 from 1 to 4
+move 17 from 9 to 2
+move 1 from 4 to 1
+move 2 from 7 to 8
+move 1 from 9 to 8
+move 3 from 8 to 4
+move 3 from 1 to 4
+move 9 from 8 to 2
+move 1 from 8 to 4
+move 12 from 2 to 7
+move 4 from 7 to 4
+move 1 from 8 to 1
+move 10 from 4 to 2
+move 3 from 3 to 2
+move 1 from 9 to 7
+move 11 from 7 to 3
+move 1 from 3 to 1
+move 2 from 3 to 9
+move 1 from 3 to 7
+move 2 from 1 to 9
+move 1 from 6 to 5
+move 7 from 3 to 6
+move 1 from 7 to 3
+move 3 from 3 to 4
+move 1 from 5 to 7
+move 2 from 4 to 3
+move 2 from 4 to 8
+move 1 from 7 to 6
+move 2 from 6 to 8
+move 1 from 9 to 2
+move 1 from 9 to 5
+move 1 from 5 to 1
+move 1 from 8 to 6
+move 1 from 3 to 2
+move 4 from 6 to 1
+move 5 from 1 to 4
+move 11 from 2 to 4
+move 2 from 8 to 2
+move 1 from 8 to 9
+move 27 from 2 to 5
+move 4 from 6 to 3
+move 3 from 2 to 4
+move 2 from 5 to 9
+move 1 from 5 to 7
+move 2 from 9 to 5
+move 14 from 4 to 7
+move 2 from 4 to 7
+move 3 from 4 to 8
+move 4 from 3 to 1
+move 4 from 1 to 8
+move 2 from 3 to 9
+move 2 from 9 to 3
+move 7 from 8 to 9
+move 1 from 3 to 8
+move 2 from 3 to 2
+move 25 from 5 to 9
+move 1 from 5 to 8
+move 1 from 8 to 7
+move 26 from 9 to 1
+move 23 from 1 to 5
+move 7 from 9 to 7
+move 1 from 9 to 8
+move 1 from 9 to 2
+move 5 from 7 to 1
+move 20 from 5 to 6
+move 1 from 7 to 6
+move 2 from 5 to 3
+move 1 from 8 to 6
+move 21 from 6 to 8
+move 1 from 6 to 4
+move 1 from 1 to 7
+move 2 from 1 to 6
+move 1 from 1 to 3
+move 1 from 2 to 5
+move 1 from 2 to 6
+move 2 from 7 to 6
+move 6 from 7 to 9
+move 3 from 1 to 2
+move 17 from 8 to 1
+move 1 from 4 to 1
+move 2 from 6 to 9
+move 3 from 8 to 9
+move 2 from 3 to 7
+move 2 from 9 to 8
+move 4 from 7 to 3
+move 4 from 3 to 4
+move 2 from 5 to 8
+move 4 from 8 to 4
+move 3 from 6 to 8
+move 18 from 1 to 5
+move 1 from 3 to 4
+move 3 from 2 to 4
+move 5 from 9 to 1
+move 10 from 7 to 5
+move 5 from 1 to 3
+move 5 from 3 to 5
+move 5 from 4 to 3
+move 2 from 4 to 2
+move 5 from 8 to 3
+move 25 from 5 to 2
+move 3 from 3 to 6
+move 1 from 1 to 3
+move 3 from 6 to 7
+move 1 from 4 to 2
+move 1 from 5 to 8
+move 2 from 4 to 9
+move 1 from 8 to 1
+move 20 from 2 to 7
+move 10 from 7 to 1
+move 1 from 1 to 7
+move 4 from 7 to 8
+move 5 from 5 to 4
+move 4 from 8 to 6
+move 1 from 1 to 3
+move 5 from 7 to 4
+move 2 from 1 to 5
+move 4 from 9 to 1
+move 3 from 2 to 5
+move 5 from 5 to 1
+move 1 from 9 to 1
+move 11 from 1 to 3
+move 1 from 6 to 2
+move 7 from 3 to 5
+move 11 from 3 to 7
+move 1 from 2 to 6
+move 7 from 7 to 8
+move 1 from 9 to 1
+move 2 from 3 to 1
+move 1 from 5 to 3
+move 4 from 1 to 6
+move 4 from 6 to 3
+move 9 from 4 to 5
+move 2 from 8 to 2
+move 4 from 6 to 9
+move 3 from 2 to 4
+move 1 from 8 to 6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/06/06.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,26 @@
+
+const input::String = "sbpbwwrlwrwggscsfcsshsvhshphttzctztfflddvbvcbcvbcbnbrrstsspsvpvllncccqssqdssnsmshmshhtssbzzlplffzppddmhhwnhntnjtnjtnnqggjdgjdjrjffsdfsfbsffhtthwwfssqpspllcvcdvvfvfzfbzzgpglpgpmppfsfdfbfvvfjfsjjvqqbvqbvqbvvlvglvglvljvjzvvqcvqcqjcqqpddqbqcqrqmmvnvbnnfqnncznccqjcqqjzzwlltrrmmlwlllbjlblzlddfdmmscmsspfssqggbsbsjjdqdqgqgqbqdqrqlrrltttghthrtrwrdrnrfnfvftvtsvtvwtvwttvqtvtccqtqmqggwhhhlzhhrwwbwqwbbfrrmddwhdwdnwdwbdwwsswtwnnvvdggbbtwbbwllgffqpffpgpgmpmmjqqmpmffjgfgrffdzzspzptzzdszszbsbsbsvsbbhsbsbddnhhrqqcwwblbwlwnnthtsshmshmhgmgqgjqqpccfvcvbbbnllgmlgmmbnmnlmlzlffrrrgssmcmddnpdndtntrrqdqldldbbtppvddgndnwwctwccpbpffngnsgshggphggtssgngtnthtllzflzflzfzrfftgtstppghgnnpggrdgdnnswwccljlflwwgzgcgrrhssbwbllblnlvlddsffgrrnbbmsmmmhjmjvmjvmjmqqpdqppltlflmfmssqcqsqvsvsggpglplslggqtggmsmmmgffrccrvvsdvdvfddprdprrwjrjcjjmlmrmqmggqgdqdwdsdwwwgfwfddrcdcvcmmjbbmrrhlrrwcwvcclttwbwttgffnmnjmjdmmmlqmqrrlblplccdbcbwcbcpphpqpqlqrllqwwjsjgjbjqbbmcmzmrrqtrqqmcmmnjmjbbtnnbbjdjzzvbzvzjzdjzjrzzfzfbbmnmdnnzppmbpbhbdbvvqnqqnqrnrzrhhrddbqdqpqqwgwlglplglslhhpjpdjdjgddnppmvppjddczccgsccdsccbcvczccnbnmmsnsmmrwmwbmbbcpbbwbppzggdnnnzmnzzvrvcrvcvcrvrnrzzqzmzttjhhnffqggnqqwzwfzfwzwfwcwnccwgcwgcgqcgqcggzgwgfwgfffjttjddwswqqnttqwqsqhhcmchcscbbnwnlwlrlppqnnwjnjtntrtdtbbmzzrmzrzvrzvrzzwqwqllccnffvmmfmvmzzfttnnzttrbttdvvhdhzhzhvzzfsfszsvsttrqqdlldflfjjnqjjbhhqhzhcchppzsznntdntdddqqwjqjqmmgnnhrhjhnjnznwwdpplzzfzztbzzbmzmbbgjgtjtqjqpqhqgqhhtztpzpmzmjmhhjwwjsspbssvdsvsgvssghgvglgtltgllmhmtmhttfgglwgllpvpgpspzzhnnzcnzzldzdmzmlzzwtwhhlfhhvthhjdjsdsmddgzzsjjnznjnmjjgdgtdtzdtdvtddzwzgwwqvqccwrrrvddbtdbbshbhssnvsnvssswcwjcjlltvvltvvdsdqdsswlwttzfzhzjjgjsgjgttbccsvcscllbfbzzwwwznwwtzwzjzwjjgqjqrjrdjrddzsznsznzpzszhzzspzzbzrzhhsbspsqpqqqpddhdcdldttlccjrjsrsfftfdfrrtntpnpsnnwjnwnznpzzlqqlmqlmmcddlqqzssglsglssprmnvltqhslvqmvszjtvtwqjcdngjmftnhwvjdvtwwhtnsdmvjdspnhnlmjgnmwlspcvpdmlsrnbbzlmwwrslssmcbggmfvgzsnpnlnzdqsbhcfjdccrspnzfmhbvwstvccvqqjlwhpnlrrwszjnrtdfzwrwlzwvdvbzbvltdpfwrjlslmrctwvbbvdrctgtgwtwpjjghhvdsqhplfrsjqlgsrbfgwdjlzdpdljtvjmpwqqbghndqnvjhngtpnpvzfbtchncwdqjhmzjlpdggbdcqrfjlwvczvpspljqmpgtrsvwwhqncfvfrwbnvsfjqlsjdlrqzmlqjgcpghhgzfhjcglllnhtmchrrptbzhqnfntgqbfstrvpsqsvqvcvpgjnchbvmgtgzqfrqcjrvldzghdfrvllrtfcwnsmmgdrcbjmdqgbfwmpwhfjmnbqrbvqvnmjlqtsjqvhzpdsgbjpjngmzbgnznvjqprfvwzjrfrwfdqrtlcgqqlvrzwmqwjbdvprvpwvdcrfdrcttnmnvjfrsrrmjgfjdmpdpnfsrwnprtdpvdmdwssvjrqtlcvpgrqgqqqffvvssbmghzjrzrzlcrnfjtdbvwsjzfvcrsmgqbcrdrjwdwbltffwbgjwtgtdblmlhvhlcpgdmpcztmpmgjghqpwzwtpnmnmgnqqrrtwczgmgtdbgdqtpnlbnzhshsfzsmrztffrmlsgqcprbjpqwjlqgwvctpmpshgzbzsjgqhzvsrjfwplvjbvltrlfldvsmlppcmsfrbbctggmqmjnhppstzrcfjtdgfwrrnmlvjphwtlqtjqcntjtzvgjtwvthjfbgpwhlrzdqncmggvgthmgjvrbnzbndsldnlcgtcqbqdnnbnqhvtpfnrclttfwcpnqscjbzdvbqrrsbzpdfhjllbjwsltjpmdnbrrzvhvzzqnlbglsjrnjbqffnnzmldfvtvmldfsztrnpcjgblsdhzfzmfqzlfrtslglhfvszppptjnjqcdmjcwqmfzhnqbfhslwhvtjfvcftzsphvghvtjjswpwghnfngmzddbwwqddsphvhcrwtthsjfswfqbvdsqghmrspdldfqmchnnrcdvjsclcnlsncsplchvzrwqbtvvqlqspftrwmjcbgpzbsmnfccbzgnhqsfjgmmsqsscdscfjbrmmtjbsphhlrlsgbllrptqrcgnqchzfddjwlldsbpcnzfbspfpchclqfbbtjpmtmtjthcdvwhrtqbgmgldcgcnmmhtbnqpzzcwlrscbzcqjzgztwjrnbmsnqtcllznlctzrntftspmnvhtfwbljnmrwsstvbmwclqrfpmwvjphrwddzdwtlfcvzlvqdmzhnvslfnfjhvdndlgbvvzbztpwvqzbzsbtqpqfmgqfgpzctfrqfjwmsnmlfqbgrlmncntcbshjhdcbqnvznhtcgcmmhnsbwpzbvtqbntwgflhjgmvvfhdbwfqmnfjlzdvvnpmvjrdfdnrhpbtllhbtbswwvrbwjgnqpbgnfrjtvbczbpmrcbwdlhztzssnwshjmmcqchptrtchrqncdgdtmwrlnmmwqlzqswwwvpngvwcphgnzrhpprjnbldscvwlqdjwnhjrnscdwlnhnsbwgzjtgvzdgqcjcgvrdhntszhdnjsbbrfphlmdlldjdslbjnnsfbmcnvtlczmtnhrwblnbrdptcpmsbwqptgmwzsqnmmchwnnrvrlfsrglfzzqbnzmpdtnhhbmfqvsrsdsctvhqwfgbtvhbbrsrqmrvvplrnbfnbdmrvzpgctdtglndhcqnllvvcppgfbwjrpqcbghlqdbmpzwrqpmvwddqgthlmzmdsvzdfsmgzltbsvphctzgjsmqvgjlsbgnvmgprbcsfhgrtbwtnnrsqcwfzrhlgjcwcfrjhffrvrvtnpczvwvjnnhfdgcppnnjjpttptcbmdqvgdbhdmlqgcqsrnbcrbtcgzbvgmhbnwzsgnwzbhdqqmvtpssvlvsttgnmcclqnjcgjnvtdggrcwsgbpjljgzgtllsnfvfshtbbpwrjhzvzswlfdvhbpngvgddcmhbzqcvnjhfsqpnvvsdvdtmqlqpzcgsnwlflnqprbqnwdqchjvsptbtrvtzvhrmrvznfpzmcsgnqtdvghhzwrrwvqwrztvdbjjtfchpftdcbthpfdczwchpptwzdpswvbhppdphgvpfzhprpqtnprgfmdnqrbrdlclcmhrdfrcdhwpcqhnbwmhrrgnctpvsqmphcwwvlmslszhdz";
+
+function find_marker(s::String; n=4)::Int
+    i = n;
+    L = length(s)::Int;
+    while i <= L
+        dup = false;
+        for Ref = i:-1:(i-(n-2))
+            for Cmp = (Ref-1):-1:(i-(n-1))
+                if s[Ref] == s[Cmp]
+                    i += Cmp - (i-n);
+                    dup = true;
+                    break;  # To do: optimize
+                end
+            end
+        end
+        if !dup
+            return i;
+        end
+    end
+    return -1;
+end
+
+println(find_marker(input; n=4));
+println(find_marker(input; n=14));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/07/07.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,184 @@
+const input::String = "07/input.txt"
+
+import Base: push!
+using ParserCombinator
+
+abstract type Entry end
+
+struct File <: Entry
+    name::String
+    size::Int
+end
+
+struct Dir <: Entry
+    name::String
+    children::Vector{Entry}
+end
+
+function filename(f::File)::String
+    f.name
+end
+
+function filesize(f::File)::Int
+    f.size
+end
+
+function filename(f::Dir)::String
+    f.name
+end
+function filesize(d::Dir)::Int
+    sum(filesize(f) for f in d.children)
+end
+
+function push!(d::Dir, e::Entry)
+    # Avoid duplication of entries
+    if !isnothing(findnext((==)(e), d.children, 1))
+        return;
+    end
+    push!(d.children, e::Entry);
+end
+
+function cd(d::Dir, s::String)::Entry
+    d.children[findnext(e -> filename(e) == s, d.children, 1)]
+end
+
+function count_dirs_belowsize(root::Dir; maxsize=100000)::Int
+    sizes = [filesize(e) for e in root.children];
+    mysize = sum(sizes; init=0);
+    subsizes = [count_dirs_belowsize(r) for r in root.children if isa(r, Dir)];
+    (mysize <= maxsize ? mysize : 0) + sum(subsizes; init=0)
+end
+
+# Parsing types
+
+abstract type TerminalLine end
+
+struct Cd <: TerminalLine
+    dir::String
+end
+
+struct Ls <: TerminalLine
+    contents::Vector{Entry}
+end
+
+# Parsers
+
+ParseFilename() = p"[a-z/\.]+" |> (x -> string(x[1]))
+ParseCd() = (E"cd " + ParseFilename()) |> (x -> Cd(x[1]))
+ParseLs() = (E"ls" + Eos()) |> (_ -> Ls([]))
+
+ParseCommandLine() = E"$ " + (ParseCd() | ParseLs()) + Eos()
+
+ParseLsEntry() = ((E"dir " + ParseFilename()) |> (d -> Dir(d[1], []))) | ((PInt() + E" " + ParseFilename()) |> (f -> File(f[2], f[1]))) + Eos()
+
+
+function build_filesystem(io::IO)::Entry
+    root = Dir("/", [])
+    current = root
+    path = []
+
+    pcl = ParseCommandLine()
+    ple = ParseLsEntry()
+
+    state = "shell";
+
+    for line in eachline(io)
+        parsed = false;
+        while !parsed
+            if state == "shell"
+                cmd = parse_one(line, pcl)[1]
+                parsed = true;
+                if isa(cmd, Cd)
+                    if (cmd::Cd).dir == "/"
+                        current = root;
+                        path = [];
+                    elseif (cmd::Cd).dir == ".."
+                        current = pop!(path);
+                    else
+                        push!(path, current);
+                        oc = current;
+                        current = cd(current, (cmd::Cd).dir);
+                    end
+                elseif isa(cmd, Ls)
+                    state = "ls";
+                else
+                    error("unknown type: ", line);
+                end
+            elseif state == "ls"
+                try
+                    e = parse_one(line, ple)[1]::Entry;
+                    push!(current, e);
+                    parsed = true;
+                catch exc
+                    state = "shell";
+                end
+            else
+                error("unknown state ", state);
+            end
+        end
+    end
+    root
+end
+
+function find_smallest_directory_larger_than(root::Entry, sz::Int)::Entry
+    best_dir = root;
+    best_difference = filesize(root) - sz;
+    for e in best_dir.children
+        if !isa(e, Dir)
+            continue;
+        end
+        fs = filesize(e);
+        if fs - sz >= 0 && fs - sz < best_difference
+            best_dir = e;
+            best_difference = fs - sz;
+        end
+
+        sub = find_smallest_directory_larger_than(e, sz);
+        fs = filesize(sub);
+        if fs - sz >= 0 && fs - sz < best_difference
+            best_dir = sub;
+            best_difference = fs - sz;
+        end
+    end
+    best_dir
+end
+
+function collect_all_dirs(root::Entry)::Vector{Entry}
+    queue = [root];
+    list = [root];
+    while length(queue) > 0
+        d = pop!(queue);
+        for e in d.children
+            if isa(e, Dir)
+                push!(queue, e)
+                push!(list, e);
+            end
+        end
+    end
+    list
+end
+
+open("07/input.txt"; read=true) do fh
+    root = build_filesystem(fh);
+    #println(root);
+    #println(count_dirs_belowsize(root));
+    #
+    total_size = filesize(root);
+    capacity = 70_000_000;
+    required_free = 30_000_000 - (capacity - total_size);
+    println("Using $total_size out of $capacity - need $required_free of additional free space");
+    sdlt = find_smallest_directory_larger_than(root, required_free);
+    println(sdlt.name, " ", filesize(sdlt));
+
+    # Serial algorithm:
+    by_filesize = [(d.name, filesize(d)) for d in collect_all_dirs(root)];
+    best = 1;
+    best_diff = by_filesize[1][2] - required_free;
+    for (i, (n, s)) in enumerate(by_filesize)
+        if (s-required_free) > 0 && (s-required_free) < best_diff
+            best = i;
+            best_diff = s - required_free;
+        end
+    end
+    println(by_filesize[best], " ", best_diff);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/07/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,1013 @@
+$ cd /
+$ ls
+dir jmtrrrp
+dir jssnn
+dir lbrmb
+11968 pcccp
+$ cd jmtrrrp
+$ ls
+77968 chq.jvb
+dir fmgsql
+$ cd fmgsql
+$ ls
+dir dbnsfp
+dir vvp
+$ cd dbnsfp
+$ ls
+51021 crlq.lrj
+186829 dhcrzvbr.wmn
+16232 fvhn.fqm
+54150 qpbqqj.rpg
+$ cd ..
+$ cd vvp
+$ ls
+179105 rrcsndz.tzp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd jssnn
+$ ls
+dir bphfqs
+dir dbnsfp
+dir pcccp
+dir snr
+dir zjbvwsnv
+$ cd bphfqs
+$ ls
+110077 dhcrzvbr.wmn
+$ cd ..
+$ cd dbnsfp
+$ ls
+dir hgvh
+dir jtqdcmsz
+154197 rrcsndz.tzp
+$ cd hgvh
+$ ls
+dir qjnbg
+$ cd qjnbg
+$ ls
+dir bqzfpr
+$ cd bqzfpr
+$ ls
+124394 wjsbsp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd jtqdcmsz
+$ ls
+275597 dbnsfp.fpg
+$ cd ..
+$ cd ..
+$ cd pcccp
+$ ls
+dir cnbd
+85621 cqzvwl
+dir dbnsfp
+114355 hbhp.cfv
+dir mcgq
+dir pcccp
+dir qpbqqj
+224038 rrcsndz.tzp
+dir zcsm
+27570 zjbvwsnv.fjt
+$ cd cnbd
+$ ls
+dir jrbz
+dir pphv
+$ cd jrbz
+$ ls
+dir dwvlwfq
+$ cd dwvlwfq
+$ ls
+32237 fwclr.rnb
+$ cd ..
+$ cd ..
+$ cd pphv
+$ ls
+180370 dhcrzvbr.wmn
+50154 dzvwdwl.gbt
+123965 mlsv.hlw
+163116 wnhtwr.mwl
+$ cd ..
+$ cd ..
+$ cd dbnsfp
+$ ls
+252181 btv.mpv
+dir hwncj
+dir pcccp
+$ cd hwncj
+$ ls
+51410 jbd.fcm
+$ cd ..
+$ cd pcccp
+$ ls
+258123 chq.jvb
+$ cd ..
+$ cd ..
+$ cd mcgq
+$ ls
+206506 qpbqqj.bbb
+$ cd ..
+$ cd pcccp
+$ ls
+193219 ddhtnql.hmb
+134114 hjbpzqzb.rwn
+108927 lznndn.nqd
+73241 ncdrv
+$ cd ..
+$ cd qpbqqj
+$ ls
+dir crdt
+dir tgchdnc
+$ cd crdt
+$ ls
+205710 chq.jvb
+$ cd ..
+$ cd tgchdnc
+$ ls
+dir bdw
+dir dpl
+dir jssnn
+dir pcccp
+dir plpzbm
+$ cd bdw
+$ ls
+211300 dbnsfp.tjm
+$ cd ..
+$ cd dpl
+$ ls
+287744 rsbjqwm
+$ cd ..
+$ cd jssnn
+$ ls
+dir jssnn
+$ cd jssnn
+$ ls
+9644 hmjhshg.vbv
+$ cd ..
+$ cd ..
+$ cd pcccp
+$ ls
+dir jssnn
+85888 pcccp.hdj
+dir qpbqqj
+dir rmscmwtv
+$ cd jssnn
+$ ls
+129698 crlq.lrj
+7499 dhcrzvbr.wmn
+283607 qpbqqj.djr
+234874 wqnrhll
+$ cd ..
+$ cd qpbqqj
+$ ls
+184229 qqpb.ftd
+$ cd ..
+$ cd rmscmwtv
+$ ls
+188048 dhcrzvbr.wmn
+dir jwtpgbnt
+$ cd jwtpgbnt
+$ ls
+209946 hgg
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd plpzbm
+$ ls
+32627 tlb.qmc
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd zcsm
+$ ls
+dir lczflft
+dir zjbvwsnv
+dir zmh
+$ cd lczflft
+$ ls
+40043 dzgnvlw.scr
+dir lrnb
+$ cd lrnb
+$ ls
+109881 bjpbs
+dir jssnn
+46901 npmw
+$ cd jssnn
+$ ls
+9216 sgrp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+214676 jssnn.hgn
+$ cd ..
+$ cd zmh
+$ ls
+dir jdt
+dir rggpltr
+$ cd jdt
+$ ls
+147387 jhhsv
+90052 jssnn.wns
+53105 qpbqqj.dzq
+$ cd ..
+$ cd rggpltr
+$ ls
+121454 dbnsfp.dzt
+dir gcc
+$ cd gcc
+$ ls
+dir zbqwl
+dir zjbvwsnv
+$ cd zbqwl
+$ ls
+260297 pcccp.jrw
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+248709 pcccp.tph
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd snr
+$ ls
+152569 chq.jvb
+1437 crlq.lrj
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+dir cqhb
+53235 ghhtl.bhv
+199640 npcfdw
+136346 qpbqqj.lmv
+dir zjbvwsnv
+$ cd cqhb
+$ ls
+24712 sqqf
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+dir gzqg
+dir hfbfvn
+dir srsphr
+dir vgvdcvc
+$ cd gzqg
+$ ls
+dir jjw
+$ cd jjw
+$ ls
+240052 zdcjjz.pmg
+$ cd ..
+$ cd ..
+$ cd hfbfvn
+$ ls
+278190 bfgndw.pvf
+$ cd ..
+$ cd srsphr
+$ ls
+42591 zjbvwsnv.hgh
+$ cd ..
+$ cd vgvdcvc
+$ ls
+120322 rrcsndz.tzp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd lbrmb
+$ ls
+dir bjhpdj
+42241 crlq.lrj
+dir dbnsfp
+244610 dhcrzvbr.wmn
+dir hppb
+dir mcnzs
+dir npntsr
+13625 tpjpcsgp.dlz
+219424 vvpbt.zvf
+dir zjbvwsnv
+191467 zjbvwsnv.htn
+$ cd bjhpdj
+$ ls
+dir bqjvst
+204722 dbnsfp
+dir dhltrqqq
+226082 dmdqcjp
+dir fcqwgzp
+dir jssnn
+6453 jssnn.ndh
+23799 jssnn.zqn
+dir nwglfhpl
+dir pcccp
+dir pdnj
+269246 shzqns.nws
+dir sjstqlcb
+dir zssln
+$ cd bqjvst
+$ ls
+202793 dbnsfp.pjj
+259783 jssnn
+dir rbvbhnvs
+30683 rvddnjmb.tlz
+dir tzhslnv
+$ cd rbvbhnvs
+$ ls
+86934 vrtrf.htt
+$ cd ..
+$ cd tzhslnv
+$ ls
+76278 mghcwdlr.tsc
+$ cd ..
+$ cd ..
+$ cd dhltrqqq
+$ ls
+dir mfd
+dir pcccp
+dir smmb
+251164 wsdnsgtt.lhr
+191876 zvr.bbz
+$ cd mfd
+$ ls
+51017 crlq.lrj
+99213 rjtbnnnq.hgd
+$ cd ..
+$ cd pcccp
+$ ls
+160487 dhcrzvbr.wmn
+dir nhdrnthj
+dir qpbqqj
+$ cd nhdrnthj
+$ ls
+181291 bbn.wtm
+186551 fnw.tnn
+23622 rrcsndz.tzp
+dir zjbvwsnv
+$ cd zjbvwsnv
+$ ls
+227547 dhcrzvbr.wmn
+$ cd ..
+$ cd ..
+$ cd qpbqqj
+$ ls
+212353 crlq.lrj
+170195 dhcrzvbr.wmn
+dir ttvp
+$ cd ttvp
+$ ls
+185994 tgjcfgjv
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd smmb
+$ ls
+dir dbnsfp
+85354 dbnsfp.zpn
+80665 dfmmjbm.rnr
+135989 dhcrzvbr.wmn
+93718 lrbzr.nfs
+dir mjpfnfns
+dir nsdpfnhb
+dir pmnssvd
+32270 qpbqqj.vtd
+$ cd dbnsfp
+$ ls
+31796 gzs.rgv
+64506 vbjncw.bpz
+181659 vjlfrdp.tqh
+$ cd ..
+$ cd mjpfnfns
+$ ls
+231611 chq.jvb
+17518 cmnlrzq.hvh
+144795 dbnsfp
+162194 jssnn.wjz
+29305 vdqnlw.fzf
+$ cd ..
+$ cd nsdpfnhb
+$ ls
+281844 chq.jvb
+$ cd ..
+$ cd pmnssvd
+$ ls
+165816 dfvl.czb
+144561 gbn
+150785 lnzdwrmb
+111214 rrcsndz.tzp
+164156 tzgdb.hht
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd fcqwgzp
+$ ls
+199161 dhcrzvbr.wmn
+34251 rrcsndz.tzp
+198345 vjlfrdp.tqh
+167001 zjbvwsnv.bsd
+$ cd ..
+$ cd jssnn
+$ ls
+dir ccblfvl
+103180 dhcrzvbr.wmn
+dir prw
+dir tzqfn
+dir zjbvwsnv
+166467 zjbvwsnv.tdt
+$ cd ccblfvl
+$ ls
+159752 crlq.lrj
+20805 jssnn.dvb
+243040 lct.zll
+27492 qbh
+27174 vjlfrdp.tqh
+dir zvfwq
+$ cd zvfwq
+$ ls
+135126 chq.jvb
+41664 gphw.vzd
+dir hmrdghbr
+dir jssnn
+dir qzzb
+dir tmdlcv
+$ cd hmrdghbr
+$ ls
+dir jvgpwrbs
+$ cd jvgpwrbs
+$ ls
+dir wzdv
+$ cd wzdv
+$ ls
+26834 qpbqqj.njf
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd jssnn
+$ ls
+90199 jqqmqddf.qnz
+$ cd ..
+$ cd qzzb
+$ ls
+dir mgpql
+dir src
+dir zvdgc
+$ cd mgpql
+$ ls
+141852 qpbqqj
+$ cd ..
+$ cd src
+$ ls
+204425 lqmcbndm.jrj
+75571 qsbrsv.jcm
+$ cd ..
+$ cd zvdgc
+$ ls
+268742 ffjmrmmz.lhg
+18385 rvmp.hjv
+$ cd ..
+$ cd ..
+$ cd tmdlcv
+$ ls
+182587 sfwvjrj.mzl
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd prw
+$ ls
+207429 dbnsfp.rqf
+dir ptgn
+dir pzgpqp
+252902 rbt
+169694 trg.rsh
+$ cd ptgn
+$ ls
+dir jssnn
+dir qpbqqj
+dir rpd
+$ cd jssnn
+$ ls
+189316 dbnsfp.bqc
+$ cd ..
+$ cd qpbqqj
+$ ls
+167937 zjbvwsnv.bhz
+$ cd ..
+$ cd rpd
+$ ls
+8775 crlq.lrj
+$ cd ..
+$ cd ..
+$ cd pzgpqp
+$ ls
+dir pcccp
+$ cd pcccp
+$ ls
+51496 pcccp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd tzqfn
+$ ls
+dir cbpfvdp
+285700 crlq.lrj
+7426 dbnsfp.fsd
+dir gdl
+141367 jssnn.hmw
+184482 sczphnp.vnc
+126288 vjlfrdp.tqh
+dir wndpdj
+$ cd cbpfvdp
+$ ls
+dir cvfr
+dir qpbqqj
+$ cd cvfr
+$ ls
+dir jfrnvts
+dir qpbqqj
+$ cd jfrnvts
+$ ls
+dir vwdn
+$ cd vwdn
+$ ls
+236936 vjlfrdp.tqh
+$ cd ..
+$ cd ..
+$ cd qpbqqj
+$ ls
+254275 bqd
+$ cd ..
+$ cd ..
+$ cd qpbqqj
+$ ls
+dir jssnn
+201960 qpbqqj
+$ cd jssnn
+$ ls
+131127 jssnn
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd gdl
+$ ls
+225146 hsgzmtp.wcs
+204436 jssnn.lhh
+64007 mjzjgfg.jsb
+$ cd ..
+$ cd wndpdj
+$ ls
+245412 bvcq
+211386 dbnsfp.tqd
+186962 fql.mww
+dir hlmhtfz
+117446 smvjvcn.lcp
+$ cd hlmhtfz
+$ ls
+150152 lrdhbq.rvm
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+179703 fvmbz
+87552 qtz.ccw
+129764 rrcsndz.tzp
+$ cd ..
+$ cd ..
+$ cd nwglfhpl
+$ ls
+66039 crlq.lrj
+dir cwq
+dir dlgrsw
+267814 frhlttn.nmd
+dir hmprt
+dir qpbqqj
+dir wnfzznfh
+$ cd cwq
+$ ls
+77655 cpjnwzh
+dir pcccp
+dir zjbvwsnv
+dir zzhjfmnr
+$ cd pcccp
+$ ls
+dir pcccp
+$ cd pcccp
+$ ls
+245309 bggzbrg.flf
+$ cd ..
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+196915 gnmfb.dzq
+dir ngqbdqp
+$ cd ngqbdqp
+$ ls
+355 rrcsndz.tzp
+$ cd ..
+$ cd ..
+$ cd zzhjfmnr
+$ ls
+dir dbnsfp
+$ cd dbnsfp
+$ ls
+223184 chq.jvb
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd dlgrsw
+$ ls
+181906 chq.jvb
+5636 dbnsfp
+219889 jbr.slc
+dir zrntbl
+$ cd zrntbl
+$ ls
+61864 brnpgpwt
+138980 qpbqqj
+$ cd ..
+$ cd ..
+$ cd hmprt
+$ ls
+90249 dbnsfp.mbd
+$ cd ..
+$ cd qpbqqj
+$ ls
+290377 crlq.lrj
+$ cd ..
+$ cd wnfzznfh
+$ ls
+83022 hclmps
+64095 zhm
+$ cd ..
+$ cd ..
+$ cd pcccp
+$ ls
+dir rdzntr
+dir rvccq
+$ cd rdzntr
+$ ls
+239028 rrcsndz.tzp
+$ cd ..
+$ cd rvccq
+$ ls
+22746 chq.jvb
+288752 jjvppq.swt
+dir msgwsnjq
+dir pggz
+228469 vjlfrdp.tqh
+$ cd msgwsnjq
+$ ls
+102522 lwgqc.mhv
+25239 ndm.llf
+$ cd ..
+$ cd pggz
+$ ls
+dir cnjqsqj
+$ cd cnjqsqj
+$ ls
+229407 shpnq
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd pdnj
+$ ls
+193069 rwnhgttz.pvp
+$ cd ..
+$ cd sjstqlcb
+$ ls
+263295 chq.jvb
+224091 jss.wtr
+$ cd ..
+$ cd zssln
+$ ls
+5859 ncdlcr.dll
+$ cd ..
+$ cd ..
+$ cd dbnsfp
+$ ls
+271252 dhcrzvbr.wmn
+$ cd ..
+$ cd hppb
+$ ls
+259968 jssnn
+81292 qpqqb.clj
+$ cd ..
+$ cd mcnzs
+$ ls
+170903 crlq.lrj
+59482 dhcrzvbr.wmn
+dir dqzwzbgm
+dir gnrztn
+286736 jssnn.jcm
+32791 phqsgl
+dir pzjnrwt
+197323 vjlfrdp.tqh
+dir wvnwbpct
+$ cd dqzwzbgm
+$ ls
+78575 qpbqqj
+251546 qpbqqj.slb
+$ cd ..
+$ cd gnrztn
+$ ls
+158603 hdnwmd.rhj
+dir nbfdtwzr
+178239 ptnchzpg
+40517 rrcsndz.tzp
+dir smvb
+198007 vjlfrdp.tqh
+$ cd nbfdtwzr
+$ ls
+200354 crlq.lrj
+$ cd ..
+$ cd smvb
+$ ls
+163921 zjbvwsnv.brz
+$ cd ..
+$ cd ..
+$ cd pzjnrwt
+$ ls
+33891 lwrll
+259646 pcccp.sfn
+106835 pqfzthjq
+189673 rrcsndz.tzp
+$ cd ..
+$ cd wvnwbpct
+$ ls
+234188 dhcrzvbr.wmn
+dir gmtpsgv
+86379 jssnn
+146663 sfpmdbbd.jvt
+25795 vjlfrdp.tqh
+$ cd gmtpsgv
+$ ls
+18642 chq.jvb
+3046 cznlwtw
+26335 ddgpngrc
+116455 vnnls.hsg
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd npntsr
+$ ls
+dir cccjdcvb
+206657 chq.jvb
+280518 crlq.lrj
+dir dbnsfp
+dir jphnn
+dir jssnn
+dir mpl
+195193 rrcsndz.tzp
+dir rztc
+dir znwp
+$ cd cccjdcvb
+$ ls
+192965 mcr.sfq
+$ cd ..
+$ cd dbnsfp
+$ ls
+dir gfns
+173317 jssnn.tjq
+dir mgr
+68817 mvwcwfcr.zmz
+dir pqfht
+108571 swfl.dtj
+10398 tvvvv
+dir vzg
+174361 zjbvwsnv
+$ cd gfns
+$ ls
+203999 zjbvwsnv.hfg
+$ cd ..
+$ cd mgr
+$ ls
+dir zjbvwsnv
+$ cd zjbvwsnv
+$ ls
+26871 tqlgcf.jrn
+$ cd ..
+$ cd ..
+$ cd pqfht
+$ ls
+199590 clpvscl.rlm
+dir dwlhv
+dir vhzfzhrb
+$ cd dwlhv
+$ ls
+130761 qpbqqj
+242752 rrcsndz.tzp
+$ cd ..
+$ cd vhzfzhrb
+$ ls
+dir njdgcbvm
+$ cd njdgcbvm
+$ ls
+dir snjfqg
+$ cd snjfqg
+$ ls
+dir qpwh
+$ cd qpwh
+$ ls
+153353 qsjpj
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd vzg
+$ ls
+dir pcccp
+$ cd pcccp
+$ ls
+dir jfbtl
+$ cd jfbtl
+$ ls
+209199 dbnsfp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd jphnn
+$ ls
+52305 crlq.lrj
+193480 gmms.whz
+59354 nmq.dww
+64638 qpbqqj
+47072 rrcsndz.tzp
+$ cd ..
+$ cd jssnn
+$ ls
+69168 crlq.lrj
+1549 dhcrzvbr.wmn
+219596 hdmczg.lmm
+108063 jssnn
+24327 vjlfrdp.tqh
+dir zjbvwsnv
+$ cd zjbvwsnv
+$ ls
+189952 chq.jvb
+$ cd ..
+$ cd ..
+$ cd mpl
+$ ls
+144856 bqrrzm
+249487 crlq.lrj
+dir ffqgpgfg
+93632 flqwtn.nsz
+dir mwpcqr
+195910 pdqwn.lcg
+$ cd ffqgpgfg
+$ ls
+66459 dbnsfp
+200500 lcmt.zmz
+207093 qpbqqj
+77042 vjlfrdp.tqh
+57109 wwzv.hbn
+$ cd ..
+$ cd mwpcqr
+$ ls
+dir zjbvwsnv
+$ cd zjbvwsnv
+$ ls
+166393 vjlfrdp.tqh
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd rztc
+$ ls
+57788 chq.jvb
+$ cd ..
+$ cd znwp
+$ ls
+164627 chq.jvb
+$ cd ..
+$ cd ..
+$ cd zjbvwsnv
+$ ls
+dir dgrrl
+71529 jssnn
+198617 pcccp.qqh
+dir phggn
+56842 zjbvwsnv.vqd
+$ cd dgrrl
+$ ls
+dir czm
+dir fhhlbdlz
+dir gstjw
+dir qpbqqj
+dir stgb
+$ cd czm
+$ ls
+dir jssnn
+$ cd jssnn
+$ ls
+162335 chq.jvb
+30099 mfdgdw
+96389 pcdsd.wmw
+251423 tmz.lcb
+205979 vpltdt.gtv
+$ cd ..
+$ cd ..
+$ cd fhhlbdlz
+$ ls
+dir qpbqqj
+dir vdjs
+dir zgz
+$ cd qpbqqj
+$ ls
+285561 chq.jvb
+263924 lbqcfdrs
+138854 pcccp.dtn
+$ cd ..
+$ cd vdjs
+$ ls
+32688 chq.jvb
+223233 tbn.blt
+$ cd ..
+$ cd zgz
+$ ls
+92804 bqltmv.wzb
+$ cd ..
+$ cd ..
+$ cd gstjw
+$ ls
+151784 fvfszzzn.cbh
+$ cd ..
+$ cd qpbqqj
+$ ls
+dir blztqf
+dir plgnh
+$ cd blztqf
+$ ls
+195097 wlvmtz
+$ cd ..
+$ cd plgnh
+$ ls
+dir dbnsfp
+246221 dhcrzvbr.wmn
+271121 jhwmmzls.mhw
+170162 pcccp.dpp
+37872 qpbqqj
+$ cd dbnsfp
+$ ls
+dir dhpnr
+$ cd dhpnr
+$ ls
+152837 pcccp
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd stgb
+$ ls
+248436 vjlfrdp.tqh
+$ cd ..
+$ cd ..
+$ cd phggn
+$ ls
+284602 dhcrzvbr.wmn
+dir lctr
+dir rjmc
+66651 rrcsndz.tzp
+117525 vth.fgw
+156877 wcqnjzbq.dgf
+7803 zpsrzclh.bzw
+$ cd lctr
+$ ls
+212339 jssnn.whp
+dir jzhcqb
+99974 pcccp.zhs
+111354 pmc
+104899 vjlfrdp.tqh
+93496 zhwmbw
+$ cd jzhcqb
+$ ls
+dir zjbvwsnv
+$ cd zjbvwsnv
+$ ls
+146807 rbrg
+$ cd ..
+$ cd ..
+$ cd ..
+$ cd rjmc
+$ ls
+dir fvbmsc
+139747 glwmr.lrg
+dir gvnnz
+102023 tbj.qmz
+dir vsztsjfh
+$ cd fvbmsc
+$ ls
+136838 vpvbz.qtw
+$ cd ..
+$ cd gvnnz
+$ ls
+95498 zjbvwsnv
+$ cd ..
+$ cd vsztsjfh
+$ ls
+215479 ffwlcrwb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/07/small.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,23 @@
+$ cd /
+$ ls
+dir a
+14848514 b.txt
+8504156 c.dat
+dir d
+$ cd a
+$ ls
+dir e
+29116 f
+2557 g
+62596 h.lst
+$ cd e
+$ ls
+584 i
+$ cd ..
+$ cd ..
+$ cd d
+$ ls
+4060174 j
+8033020 d.log
+5626152 d.ext
+7214296 k
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/08/08.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,90 @@
+
+const input = "08/input.txt"
+
+const short = "30373
+25512
+65332
+33549
+35390";
+
+function parse_trees(lines::Vector{S})::Matrix{Int} where {S <: AbstractString}
+    m = zeros(length(lines), length(lines[1]));
+    for (i, line) in enumerate(lines)
+        for (j, c) in enumerate(line)
+            m[i,j] = parse(Int, c);
+        end
+    end
+    m
+end
+
+function visibility(row_or_col::AbstractVector{Int})::Vector{Bool}
+    v = zeros(Bool, length(row_or_col));
+    highest = row_or_col[begin];
+    v[begin] = true;
+    for i in eachindex(row_or_col)
+        if row_or_col[i] > highest
+            v[i] = true;
+            highest = row_or_col[i];
+        end
+    end
+    v
+end
+
+function is_visible(m::Matrix{Int})::Matrix{Bool}
+    rows, cols = size(m);
+    v = zeros(Bool, size(m));
+
+    # Row-wise
+    for row in 1:rows
+        v_forward = @views visibility(m[row,:]);
+        v_backward = @views visibility(m[row,end:-1:begin]);
+        reverse!(v_backward);
+        v[row,:] .= v_forward .| v_backward;
+    end
+    # Col-wise
+    for col in 1:cols
+        v_down = @views visibility(m[:,col]);
+        v_up = @views visibility(m[end:-1:begin,col]);
+        reverse!(v_up);
+        v[:,col] .|= v_down .| v_up;
+    end
+    
+    v
+end
+
+function find_scenic_distance(v::AbstractVector{Int})::Int
+    ref = v[1];
+    for i = 2:length(v)
+        if v[i] >= ref
+            return i-1;
+        end
+    end
+    return length(v)-1;
+end
+
+function scenic_score(m::Matrix{Int}, row::Int, col::Int)::Int
+    v = m[row, col];
+
+    l = find_scenic_distance(@view m[row, col:-1:begin]);
+    r = find_scenic_distance(@view m[row, col:end]);
+    u = find_scenic_distance(@view m[row:-1:begin, col]);
+    d = find_scenic_distance(@view m[row:end, col]);
+    l*r*u*d
+end
+
+function scenic_scores(m::Matrix{Int})::Matrix{Int}
+    s = zeros(Int, size(m));
+    for ix in CartesianIndices(size(m))
+        s[ix] = scenic_score(m, Tuple(ix)...);
+    end
+    s
+end
+
+println("Real challenge, part 1:");
+inp_lines = readlines(input);
+trees = parse_trees(inp_lines);
+println(sum(is_visible(trees)));
+
+println("Part two:");
+ss = scenic_scores(trees);
+println("max scenic score: ", maximum(ss));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/08/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,99 @@
+230302102312303431324124303141114045300001501242156105363242032123135210143324224140132332112100221
+322200120140130323143433402101444233512140224062422011111403231052521053542252401012232443102111032
+220300201042003221454531141345330151415344324656555610153343240503352304331551230452141112120303320
+131301034134041313145104311104431531104002136262204021050462633364005504230105333250310334430012231
+021000431324243205221240551231546346005546113055526350502461501303260444304552521404504240012202100
+130032042140100501120530551053341401664420533042546256013026351632616214431331333233341222140143402
+102213021202104044154525451632332223320015014365014110000262152226451306654102512123512023131343201
+331321033401405043214153225511265312435604105124767542760400104362304616510410004451235001241134031
+234010022341252215202325124644011146300614531262461555623242615510132104506502155353245030411321214
+304102101231325220244422554336626240225366453655233535214545356712401516453566460554521045401410034
+124222310241022025221634021203456261377536264451547554432421672616632511164231351545110100421124041
+231432431351552412035636562534314116212363155763515352233177566413166344310511112324524355103343213
+103031123324141030040550165506212465546735652123674755314542271633361443500442335114204031255241224
+320113443131100311503426244335257671411253247761166615472155473411374661621210160254602143000503002
+003031503150544521324165216521624371212157515435232724117746343274255223574322040541222535240125320
+431234101124435354234422257673575575175341283683836588272273446224536761435621240216142511140302323
+123130200251405600130545412766211145442246588283778878426386645127335561311156623533260243441410122
+432402514341626355125037245134531317588423262388855625822687585244364351651321623121561560010312113
+312341305215255100304471152277172523637784345263433358277226635245516164123212336452605424200110430
+001434330142034560665237211325533756327872855833882354736845633764265764254723135136216531341302425
+345110412256633232261137637156368637757634446735753883783375577533786454271246611655350133245255344
+130515311233246602623742771612278266785844368233445235428485736334867477631346361563230603123034134
+330040046512436325746335744443684727248746257893478978476233834562664674872164576161101306065422041
+222154026412500467311716243862854643768585738339383839693837627262625554423155651645532206206134414
+542550455123342216235327358832483365754856794969568679863575688486863754828773355515541016335040545
+404234533623052522751165344644483278684968464647937735374953694986883822877673474565215510426220344
+314254353400344713147333655472357537587356967673598874457668767889935746887521663427411521635661241
+250301522140303127537224263455464893375697787574446387685355687386368545878447447117247625662212301
+531245634640354662654558667774728435789865389774334746464789766764944468568554351264634206163162541
+254210565205047575772722425336239545866857335764867899689375964484886366575237326255114412442436305
+254440240052645344117878758858477694934868449869846797495773435673485582766622343237654674230614650
+302350056253421457757382352837655457348549979584868566587675763536549455773244366226575120110432202
+524251410101643732555863746673768898357598988876769465556757759865678788677845447537546514520246465
+412424366507365464723435562846447777556788564867748886999988659539789863738827284322243654235650222
+302260630341726247764652638469957786688964699758599945666799457875988357894464748565724572166261234
+215150213244237121847528247786444449998976749466844877974565875546766745893426378444445742710223525
+424160233533557213425484474439489658786978977985856797555685676569553489768586885887425626363046446
+153322066741372433344452464455559968984567799888687677756697744545783483874576867684647332571001005
+145420124453223247785888737894569596698676567955697655669665679864796955354676474465373675660155614
+033506450161333145373824444348436889577445897969987595896979686466678689467597644746532527513131131
+225012522655144432763537973395798658496758867787886779885975689947696977368784268458336146373115143
+216342537614133655675625959443677654855666875698895757965779667678777945996749485327555574145424460
+166106344353256563624325443477776845578965867968867569996565856754694668864655545773383227234335414
+150522031675635233237668486584959896545865765899786958699768689485564988376498275457676373151605464
+412336103615667832572493349365459748765865988788966796676798558958658889874394465442751254315016610
+352326617457732528434753466738454444568858687988678798897989789856878957499594873552874152661460523
+062415331267566426437243673895878674897896558788889897878987955994767455333837536424584567627336053
+411350266636525852438469567638886987958577976996868967687585597767547999698594634538245463464543005
+052464462614766832722735867947598567878869668679877788879769878876988899643845375267672315514353000
+543545564473648376567477376798669977686956967668898889969875757785956549649485643782434576251353131
+634033674455736672452884665689654778778759896979877869977686568577555776433947564287374612267436364
+620541245674573376723897469464969646966776677799787978979857977798869788359344972235473531452736105
+602620347126374653254296764775476547797557857869988876878957998886476566934646536357683276776151421
+453313013613244386884696349435758974966876787969887886879899685595858499393337785854825724737215563
+633162016753461244685737989459664898569667899679799786798979988797998958559548885735471347141136630
+000101426742225562735894769979656676989556887676998666978968879767489645833678358457422477754521142
+620262606411662643533249376858748847498879757666997687879595676878844467633967768755461265735510400
+360023137544654575733228376896988578467698566656988978959969695576685749457685864437734765717026064
+453004005155344764583728835857979544659758957678779579869558958494954483997436423583442547122611144
+542364512554772785834745874957646879945679759867877799887755596454644564849589474263221373377352410
+002404034225236156254239388474876685554666797767767967895789558759867549659597464467365225556245635
+245410135477125426663788797639838547747878866579559887665897566567957973945395387477415314463463430
+134134265157751574644752634743354666668958565798799857969998998868959355953856752485414215452524346
+134233063522723113742886693543696949958945798696986777765986578999899884698774475872617234240653423
+244361001066345154366465584498936779955869489578987799745999756687935697875536775754117227145563503
+424615513054521426726444456756894679964484855474988695686689467459399699543485425832215323565610231
+010511022361177421578425884488933866869996559974758675556944646898573447548734866775441423552334113
+455000614233131572534883424588896457684489858997764475858957676964979965647378323342574224433221410
+554234433657562455545554335673953366894875796478846544767476975987878676385863745315342113644542314
+334234343615275457652768335759749448996379787584585465788795884334949898848654742611353314261636503
+333304555356366151638427333872998755488366686597689567687856687846596683534345663212543346305030250
+221202454261633375664542356764698437549939857548989949987335436749598666277762261737227146546505534
+240412550420563537276688628732843367868467736695759997434973759746799657483248636225432651522613045
+234101415413036337546543888388563596433499988836578844689689497975764628525732325317653041241353030
+431410263125326725415234754275746658476797893535668937455785755994425345326575247342241464251000421
+235305105630506142127546572374764553754685586586673543349859396362874755756655416517334460144522501
+053230360255455453432625173284836864837934635996948769536785973725832747476731215716516416145320150
+220341023145561653434447455522778482225563875986777563368797985846552555226462623761223514365411344
+555505021215644010564473315638562438843876455985785666379866472746877227331266714741141010601131000
+453335252144616255521312353556677472322787423527747647554222386736627248134362414253412412531431213
+042151015320560413551651234262565787675225582872838475557456742335545484137617276444245016450453552
+014404334344615462565743465273746656366752555484464325685467246827267515345457117051354205241444340
+213041551013263163616741653367152326275633684378845888827238722532735171772265542620411543050510551
+224455113205603560061536164734146772822552432636277537568582283454552565546556622004610432104440414
+120034300413036442405642132721761733145582724757284464865848374626544672733422446132110450322334043
+321102323253550034451665134657546626247721386824348475375862731112516436572563504423615532222151203
+423413023253053651012440232734663275166577433646527244777525111735773767313620631626060044333201413
+310311122105544263022025236566616265144255413423733523634375771573412213343520014446112203251501244
+242112304444105230054262221514232727536351532732445557376642241447573270443566533260102401044113312
+300401122201443130504625604224103567247721576334262357161547725313757534624304442441502400005401420
+312140241542522534423315456561105236441214136262754317657256235334116150340065011324403154142414212
+144233324321121441233255150514400352347655162673141155544742475145632635002103305025150134340421444
+111103103110050242122311312046534446626061741554364774752533752234163656421540312341011215100222430
+303431234002202314522440214134041163045124514037641775350115015005306206502562310105314100032000400
+022101131200322543535350013343206260166164021153334624135541245000601615213233143310354543221432032
+233233001110344441512334010360062644015111403065346201116113310635016323603102000435213440203331333
+221234200414024043305553013402501300310163441031202131631042043410330561032554522352320341422042103
+321123401142123425525550311314256215506650120142506242614512364236453401432552531430304012423410223
+122333244113420243051112411113522042223653563261365250113056645225530145055223432541231304233333203
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/09/09.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,134 @@
+
+const test_input::String = "R 4
+U 4
+L 3
+D 1
+R 4
+D 1
+L 5
+R 2";
+
+const test_input2::String = "R 5
+U 8
+L 8
+D 3
+R 17
+D 10
+L 25
+U 20";
+
+@enum Direction begin
+    U
+    D
+    L
+    R
+end
+
+function to_direction(c::Char)::Direction
+    if c == 'U'
+        U
+    elseif c == 'D'
+        D
+    elseif c == 'L'
+        L
+    elseif c == 'R'
+        R
+    end
+end
+
+struct Step
+    direction::Direction
+    n::Int
+end
+
+function parse_input(lines::Iter)::Vector{Step} where {Iter}
+    v = Vector{Step}();
+    for l in lines
+        a, b = split(l, ' ');
+        push!(v, Step(to_direction(a[1]), parse(Int, b)));
+    end
+    v
+end
+
+function wheretogo(H::Tuple{Int,Int}, T::Tuple{Int,Int})::Vector{Direction}
+    # This might have a more elegant solution...
+    if H == T
+        []
+    elseif H[1]==T[1]
+        if abs(H[2]-T[2]) < 2
+            []
+        else
+            (H[2] > T[2] ? [U] : [D])
+        end
+    elseif H[2]==T[2]
+        if abs(H[1]-T[1]) < 2
+            []
+        else
+            (H[1] < T[1] ? [L] : [R])
+        end
+    elseif abs(H[1]-T[1]) + abs(H[2]-T[2]) == 3  # diagonal
+        if abs(H[1]-T[1]) > abs(H[2]-T[2])
+            snd = (H[2]-T[2]) > 0 ? U : D;
+            (H[1]-T[1]) > 0 ? ([R, snd]) : ([L, snd])
+        else
+            snd = (H[1]-T[1]) > 0 ? R : L;
+            (H[2]-T[2]) > 0 ? ([U, snd]) : ([D, snd])
+        end
+    elseif abs(H[1]-T[1])==abs(H[2]-T[2]) && abs(H[1]-T[1]) > 1
+        [(H[1]>T[1] ? R : L), (H[2]>T[2] ? U : D)]
+    else
+        if abs(H[1]-T[1])+abs(H[2]-T[2]) == 2
+            []
+        else
+            error("unhandled case: ", H, T)
+        end
+    end
+end
+
+function apply(p::Tuple{Int,Int}, dir::Direction)::Tuple{Int,Int}
+    if dir == U
+        p .+ (0,1)
+    elseif dir == D
+        p .+ (0,-1)
+    elseif dir == L
+        p .+ (-1,0)
+    else
+        p .+ (1,0)
+    end
+end
+
+function process1(v::Vector{Step}; ntails=1)::Int
+    H = (0, 0);
+    T = [(0,0) for i in 1:ntails];
+    visited = Set{Tuple{Int,Int}}([H])
+
+    for step in v
+        for i = 1:step.n
+            H = apply(H, step.direction);
+            # Tail follow
+            pred = H
+            for (i,t) in enumerate(T)
+                wtg = wheretogo(pred, t);
+                for w in wtg::Vector{Direction}
+                    T[i] = apply(T[i], w);
+                end
+                pred = T[i];
+            end
+            push!(visited, pred);
+        end
+    end
+    length(visited)
+end
+
+println("test input (should be 13):");
+println(process1(parse_input(split(test_input, '\n'))));
+println("part 1:");
+open("09/input.txt"; read=true) do fh
+    @time println(process1(parse_input(eachline(fh))));
+end
+
+println("part 2:");
+println(process1(parse_input(split(test_input2, '\n')); ntails=9));
+open("09/input.txt"; read=true) do fh
+    @time println(process1(parse_input(eachline(fh)); ntails=9));
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/09/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,2000 @@
+R 1
+D 1
+L 1
+D 1
+L 2
+U 2
+D 2
+R 1
+D 1
+L 2
+R 1
+L 2
+R 2
+L 1
+R 2
+D 1
+R 1
+D 2
+U 1
+R 1
+D 2
+R 2
+L 1
+D 1
+R 2
+D 2
+R 1
+L 2
+D 1
+L 2
+D 2
+R 2
+D 2
+L 1
+D 1
+L 1
+D 1
+R 2
+L 2
+R 2
+D 2
+R 2
+D 2
+R 2
+L 2
+R 2
+U 1
+R 1
+D 2
+R 1
+L 1
+U 1
+L 2
+U 1
+D 1
+R 1
+U 1
+R 2
+D 2
+U 2
+D 2
+R 1
+L 1
+U 2
+L 2
+D 2
+L 1
+R 2
+D 1
+R 1
+L 2
+U 2
+R 1
+D 1
+U 2
+L 1
+U 2
+L 1
+R 2
+D 2
+R 1
+D 2
+R 1
+D 1
+R 1
+D 1
+L 2
+D 2
+R 2
+D 2
+R 1
+D 1
+R 2
+L 1
+U 2
+R 2
+D 1
+L 2
+U 1
+D 2
+L 2
+D 2
+L 2
+D 1
+R 1
+L 1
+U 2
+L 2
+D 1
+L 2
+U 1
+L 3
+D 1
+R 1
+U 3
+L 2
+U 1
+D 3
+L 1
+D 2
+R 1
+L 3
+D 2
+L 2
+D 1
+L 1
+R 2
+L 3
+D 2
+L 1
+U 3
+L 1
+R 3
+U 1
+R 3
+U 3
+D 1
+L 2
+U 2
+D 2
+U 3
+D 3
+L 1
+U 3
+D 3
+L 3
+R 1
+D 1
+U 2
+R 1
+U 3
+L 3
+D 2
+L 3
+D 1
+R 2
+U 1
+D 2
+L 3
+D 2
+U 2
+R 1
+L 3
+R 2
+L 2
+U 2
+R 2
+L 1
+D 1
+U 3
+D 1
+R 2
+L 1
+U 1
+R 1
+L 1
+D 2
+L 1
+D 1
+L 1
+D 3
+U 3
+D 3
+R 3
+D 2
+L 1
+R 1
+L 1
+D 3
+L 2
+D 1
+R 1
+D 3
+U 3
+L 2
+D 1
+U 1
+D 1
+U 3
+R 2
+L 1
+D 3
+U 3
+D 3
+U 2
+L 1
+R 1
+U 1
+D 3
+R 2
+U 1
+L 2
+U 1
+L 2
+U 2
+D 1
+L 3
+U 1
+R 1
+L 2
+U 1
+D 2
+L 1
+D 4
+L 3
+D 4
+R 2
+D 2
+L 3
+U 2
+L 3
+D 1
+L 4
+R 2
+D 1
+U 4
+L 3
+D 1
+R 1
+D 4
+R 4
+U 3
+D 3
+L 3
+D 3
+U 1
+R 4
+L 2
+D 1
+R 3
+L 4
+D 1
+R 2
+L 4
+U 3
+L 4
+R 1
+L 3
+D 1
+U 4
+L 4
+R 3
+U 4
+D 3
+U 2
+R 3
+D 1
+R 3
+L 3
+D 2
+U 4
+R 3
+U 4
+L 4
+R 4
+L 2
+R 2
+D 3
+L 2
+U 1
+L 4
+U 3
+R 3
+L 4
+U 1
+L 1
+U 1
+D 2
+R 1
+U 1
+L 3
+R 4
+L 2
+D 4
+R 3
+L 2
+R 1
+L 4
+R 1
+D 2
+R 4
+L 3
+U 3
+L 3
+D 1
+R 2
+L 4
+D 2
+R 3
+U 2
+D 3
+R 2
+U 4
+L 1
+U 2
+D 2
+L 1
+D 4
+R 3
+L 3
+R 4
+D 1
+U 2
+R 2
+D 1
+L 3
+U 2
+L 3
+R 1
+D 1
+R 4
+L 4
+R 1
+U 3
+R 4
+L 3
+D 3
+L 4
+R 4
+D 5
+R 2
+U 5
+L 1
+D 5
+L 5
+R 1
+L 5
+U 5
+L 3
+D 3
+L 2
+D 1
+L 1
+U 1
+L 1
+D 2
+L 3
+U 2
+D 3
+L 4
+R 5
+U 2
+L 3
+D 3
+R 4
+U 3
+D 5
+U 1
+R 3
+L 3
+D 1
+U 2
+L 3
+R 5
+D 2
+R 2
+U 4
+L 2
+R 4
+D 5
+R 2
+U 2
+D 5
+L 3
+R 2
+D 2
+L 1
+U 2
+R 1
+D 2
+U 1
+L 2
+U 5
+R 1
+U 4
+D 1
+R 4
+U 4
+R 3
+D 1
+U 2
+L 5
+U 1
+L 3
+D 1
+U 5
+D 5
+U 1
+L 3
+D 1
+R 2
+L 4
+R 4
+L 2
+U 2
+R 5
+U 1
+R 5
+L 1
+D 1
+R 3
+D 2
+R 4
+L 5
+D 3
+L 3
+U 5
+R 2
+D 5
+L 1
+U 2
+D 2
+U 4
+R 4
+L 4
+U 1
+D 1
+U 4
+R 4
+D 3
+L 4
+R 2
+D 3
+R 5
+U 4
+L 4
+R 4
+L 2
+U 4
+R 4
+D 1
+R 3
+D 6
+U 6
+D 5
+L 4
+R 2
+D 5
+R 5
+D 3
+R 3
+U 3
+D 3
+U 2
+L 2
+R 6
+L 6
+D 1
+L 4
+R 6
+D 5
+L 2
+R 4
+U 2
+L 5
+R 6
+U 6
+D 1
+U 3
+D 3
+R 1
+L 4
+D 2
+U 1
+L 2
+R 1
+D 3
+U 5
+R 1
+D 2
+U 5
+D 5
+R 3
+U 2
+D 4
+U 2
+R 5
+U 4
+R 2
+L 4
+U 5
+L 3
+D 1
+R 3
+U 3
+L 1
+U 1
+L 2
+R 5
+U 2
+D 4
+R 1
+D 5
+L 6
+R 6
+U 2
+D 4
+R 4
+D 4
+L 6
+D 3
+U 1
+L 4
+U 5
+R 3
+D 3
+R 6
+D 3
+R 6
+D 1
+L 3
+R 4
+D 5
+R 4
+D 6
+R 3
+U 6
+R 4
+U 1
+D 4
+L 2
+D 4
+L 2
+U 2
+R 4
+D 4
+L 1
+D 4
+U 4
+D 6
+U 3
+D 1
+L 2
+D 5
+R 2
+D 2
+L 5
+R 4
+L 5
+R 5
+U 6
+L 1
+R 3
+U 5
+D 1
+U 2
+R 2
+D 4
+R 4
+D 6
+R 4
+L 4
+D 2
+R 6
+L 1
+D 1
+U 3
+R 1
+D 4
+L 1
+D 3
+U 5
+R 2
+U 2
+D 6
+L 5
+U 4
+L 5
+R 3
+U 7
+R 2
+D 1
+R 6
+D 6
+U 6
+R 5
+D 5
+R 6
+D 6
+R 6
+D 5
+U 5
+D 7
+L 4
+U 3
+D 3
+U 2
+L 2
+U 4
+D 1
+R 7
+U 4
+L 1
+D 4
+L 3
+R 6
+L 1
+R 2
+L 4
+R 5
+U 6
+D 6
+U 2
+R 5
+U 4
+L 5
+U 3
+D 1
+L 6
+R 2
+D 2
+L 3
+U 5
+R 6
+U 7
+R 1
+L 7
+D 5
+U 5
+D 2
+R 4
+U 2
+L 7
+R 4
+D 7
+U 4
+D 3
+R 2
+D 3
+L 3
+U 6
+R 2
+L 6
+D 2
+R 6
+L 3
+R 4
+U 1
+D 3
+U 2
+L 4
+D 6
+U 7
+D 4
+L 3
+R 1
+U 6
+L 3
+R 3
+U 7
+R 7
+U 6
+L 1
+U 8
+L 1
+D 8
+L 6
+R 3
+L 7
+D 5
+U 8
+R 5
+L 4
+U 8
+L 3
+D 2
+U 1
+R 8
+D 8
+R 7
+U 1
+D 2
+R 6
+L 8
+D 5
+L 6
+U 1
+R 2
+U 6
+L 3
+D 6
+U 2
+R 2
+D 1
+U 4
+L 8
+D 8
+R 1
+L 2
+R 2
+D 7
+U 5
+D 8
+L 1
+R 7
+L 8
+D 2
+R 8
+D 7
+U 3
+R 3
+U 3
+D 1
+L 2
+U 6
+D 7
+U 8
+R 6
+D 6
+R 5
+U 7
+R 8
+L 1
+U 7
+D 2
+R 6
+U 7
+R 3
+D 3
+R 3
+U 4
+D 8
+L 7
+R 5
+U 1
+L 6
+R 8
+D 6
+R 4
+L 4
+D 1
+U 5
+L 6
+U 1
+D 8
+U 2
+R 4
+L 2
+R 8
+D 1
+R 1
+L 4
+R 7
+U 7
+D 8
+R 8
+L 6
+U 7
+L 4
+D 2
+R 2
+U 5
+D 1
+R 5
+L 6
+U 8
+L 1
+R 7
+D 8
+L 3
+D 2
+U 3
+D 3
+L 1
+R 3
+L 7
+D 6
+R 4
+D 1
+U 8
+L 3
+D 6
+L 7
+U 5
+R 6
+D 2
+L 4
+R 9
+D 2
+R 4
+D 6
+R 5
+L 7
+R 5
+U 7
+R 1
+L 5
+U 6
+R 4
+D 8
+U 5
+L 4
+U 1
+D 8
+U 9
+D 4
+U 7
+L 4
+R 8
+D 4
+R 4
+D 8
+R 1
+D 3
+R 5
+D 7
+U 8
+D 2
+R 2
+U 1
+L 1
+U 2
+L 9
+R 9
+D 1
+U 1
+D 8
+R 3
+L 8
+D 7
+U 9
+R 6
+L 4
+U 8
+D 4
+U 2
+L 3
+D 8
+L 2
+R 5
+U 4
+D 6
+U 6
+L 8
+R 7
+D 2
+R 3
+L 8
+U 9
+R 2
+U 4
+L 9
+R 5
+D 5
+R 4
+D 6
+R 3
+D 3
+R 8
+D 3
+R 4
+D 1
+U 2
+D 6
+R 4
+D 7
+U 5
+D 2
+R 6
+D 3
+U 3
+R 4
+U 5
+L 3
+U 5
+L 8
+D 3
+L 8
+D 5
+R 4
+L 8
+R 5
+U 8
+R 10
+D 2
+U 10
+R 1
+D 1
+L 4
+D 9
+L 6
+U 2
+R 3
+D 2
+L 6
+R 2
+L 10
+D 2
+L 10
+U 3
+L 2
+D 8
+U 10
+R 5
+L 1
+U 8
+R 9
+D 8
+U 2
+R 4
+U 3
+D 2
+U 4
+D 2
+R 3
+L 2
+U 4
+D 1
+U 9
+R 2
+U 1
+R 3
+D 3
+L 3
+R 2
+D 1
+U 8
+D 1
+L 5
+R 4
+L 8
+D 3
+L 1
+U 10
+R 9
+D 9
+U 9
+D 1
+R 6
+L 6
+U 6
+L 1
+D 5
+L 4
+U 8
+L 10
+U 9
+R 9
+D 5
+U 4
+D 7
+R 5
+U 10
+D 5
+U 1
+R 5
+L 7
+D 9
+R 5
+L 3
+U 2
+D 6
+R 4
+D 7
+U 4
+R 8
+L 5
+R 8
+L 9
+R 8
+D 1
+R 1
+L 9
+D 7
+L 10
+D 6
+R 8
+U 4
+D 4
+R 7
+L 9
+D 9
+R 9
+L 1
+R 6
+L 7
+R 10
+L 1
+U 9
+D 11
+R 4
+D 4
+U 5
+R 8
+U 9
+L 8
+D 8
+L 10
+U 10
+L 4
+D 1
+L 3
+U 7
+D 11
+U 4
+L 7
+R 2
+U 9
+D 4
+R 4
+U 1
+L 5
+U 10
+R 4
+D 3
+L 9
+R 2
+L 3
+U 5
+D 6
+U 2
+R 7
+D 7
+R 4
+L 8
+U 5
+R 1
+U 4
+D 3
+U 5
+R 9
+D 2
+R 4
+D 8
+U 9
+R 7
+U 5
+D 3
+R 6
+L 7
+U 7
+R 10
+L 3
+U 10
+L 8
+R 11
+L 3
+U 10
+R 5
+D 1
+U 7
+R 6
+U 9
+L 3
+R 9
+L 4
+R 9
+L 5
+R 9
+D 5
+U 8
+R 7
+L 7
+R 4
+L 9
+R 9
+D 7
+R 2
+L 3
+U 1
+L 1
+D 11
+U 3
+D 5
+R 3
+U 11
+L 1
+U 7
+R 8
+D 8
+U 7
+D 7
+R 6
+D 3
+R 8
+L 9
+U 10
+D 10
+L 1
+D 9
+L 1
+R 5
+D 6
+U 5
+L 1
+R 10
+L 1
+U 7
+D 11
+R 8
+U 11
+L 6
+R 4
+U 7
+R 3
+L 8
+D 8
+L 12
+U 3
+D 12
+L 6
+R 1
+U 8
+R 3
+U 4
+L 3
+D 10
+L 9
+D 6
+L 12
+R 11
+D 4
+U 4
+L 12
+R 1
+U 1
+D 10
+L 11
+R 3
+D 4
+R 4
+U 4
+D 3
+U 10
+R 9
+U 9
+L 1
+U 10
+D 11
+U 4
+D 3
+L 10
+R 5
+D 8
+R 5
+U 6
+R 12
+L 10
+U 10
+D 2
+L 6
+U 5
+D 3
+R 2
+D 3
+U 7
+D 1
+L 5
+U 9
+D 3
+U 10
+L 10
+U 4
+L 12
+R 11
+D 2
+L 10
+U 6
+L 4
+D 5
+R 3
+L 4
+D 8
+U 7
+R 12
+D 1
+U 5
+L 2
+D 7
+R 3
+U 1
+L 10
+R 9
+L 7
+R 8
+U 9
+R 9
+U 1
+L 7
+D 6
+L 1
+R 11
+L 9
+U 12
+R 8
+U 3
+R 5
+U 5
+L 12
+R 7
+L 8
+R 11
+L 4
+R 10
+D 2
+L 4
+U 12
+R 5
+D 1
+L 12
+D 1
+L 5
+D 3
+U 8
+L 5
+U 5
+R 7
+D 1
+L 3
+D 9
+L 12
+R 5
+D 12
+U 6
+L 7
+D 6
+L 5
+U 6
+R 7
+U 5
+D 8
+R 11
+D 12
+R 10
+L 11
+R 6
+L 13
+D 3
+L 2
+U 4
+D 12
+U 8
+D 6
+R 2
+D 2
+R 13
+U 1
+D 6
+R 8
+D 12
+L 8
+R 4
+L 7
+R 8
+D 9
+U 3
+L 1
+U 3
+L 10
+R 12
+U 13
+R 7
+U 1
+D 13
+U 6
+L 13
+D 11
+U 8
+L 10
+D 13
+R 11
+L 8
+D 5
+U 11
+R 1
+D 9
+L 4
+D 12
+R 13
+L 11
+D 7
+L 9
+U 8
+L 13
+D 11
+L 10
+R 4
+U 4
+D 4
+L 5
+D 7
+L 12
+U 10
+R 3
+L 10
+U 2
+L 2
+R 8
+L 6
+U 11
+L 4
+D 4
+U 9
+L 1
+R 12
+D 12
+R 13
+D 8
+R 8
+L 12
+U 5
+D 8
+L 7
+D 13
+U 12
+D 12
+R 10
+U 10
+R 13
+D 9
+R 3
+U 13
+L 12
+R 6
+U 14
+D 11
+R 14
+L 2
+R 5
+U 6
+R 10
+U 6
+L 3
+R 8
+U 7
+L 3
+D 4
+R 13
+L 10
+D 5
+U 10
+R 13
+L 6
+R 6
+L 1
+D 4
+U 10
+R 14
+U 7
+L 11
+R 14
+D 11
+R 8
+D 2
+U 13
+L 5
+R 10
+D 6
+U 7
+D 7
+L 6
+U 11
+L 4
+D 11
+L 9
+R 6
+L 5
+U 14
+R 2
+D 1
+U 12
+L 3
+U 3
+D 2
+U 3
+L 7
+U 10
+D 2
+R 9
+L 8
+U 10
+D 4
+R 7
+U 4
+L 8
+R 3
+L 6
+D 2
+R 11
+L 2
+D 12
+U 14
+L 1
+R 1
+U 12
+R 3
+L 14
+U 9
+D 7
+L 3
+U 8
+R 9
+L 4
+U 7
+D 4
+R 5
+D 7
+R 11
+L 13
+R 3
+D 10
+R 11
+U 6
+L 4
+D 9
+R 4
+U 5
+D 9
+R 13
+D 6
+R 11
+L 1
+D 1
+R 13
+U 4
+L 9
+U 14
+L 9
+R 2
+D 2
+L 7
+D 13
+L 11
+D 8
+R 4
+L 7
+R 4
+U 12
+D 5
+R 13
+D 14
+R 7
+U 6
+R 2
+U 13
+L 7
+U 14
+R 11
+U 15
+R 8
+U 7
+D 7
+L 5
+U 2
+D 13
+U 11
+L 12
+R 6
+D 13
+L 6
+U 8
+L 3
+R 15
+L 13
+D 1
+U 2
+L 14
+D 8
+L 4
+U 6
+R 11
+D 11
+R 2
+U 13
+L 13
+R 2
+U 15
+R 3
+D 4
+L 7
+R 7
+D 7
+R 7
+L 13
+R 10
+U 8
+R 13
+L 2
+U 13
+D 8
+U 15
+L 4
+D 13
+R 13
+U 8
+R 3
+L 11
+R 12
+U 2
+L 13
+U 1
+L 9
+U 11
+D 14
+R 12
+D 6
+U 6
+D 12
+U 8
+R 3
+U 4
+R 8
+U 2
+D 5
+L 12
+U 14
+D 4
+R 1
+U 10
+L 10
+R 6
+D 13
+U 11
+D 11
+U 11
+R 14
+D 15
+L 11
+U 14
+D 7
+L 12
+D 3
+L 14
+U 7
+R 1
+U 5
+L 1
+R 15
+U 13
+D 7
+R 9
+L 15
+U 15
+L 15
+D 7
+R 15
+D 3
+U 5
+L 8
+R 13
+L 15
+D 8
+L 15
+D 12
+L 5
+D 14
+U 16
+R 11
+L 14
+R 6
+L 10
+U 11
+R 8
+U 16
+L 6
+U 9
+L 13
+D 14
+R 7
+D 10
+L 15
+D 1
+L 10
+D 1
+R 2
+U 15
+L 9
+U 6
+D 3
+L 8
+D 13
+U 16
+D 12
+R 2
+L 1
+D 8
+L 15
+R 14
+D 8
+L 9
+U 12
+R 3
+U 15
+D 10
+U 13
+R 8
+L 15
+D 9
+R 8
+L 9
+U 2
+R 7
+L 11
+R 3
+D 13
+U 16
+L 9
+U 6
+L 7
+U 4
+L 16
+U 16
+L 12
+U 9
+R 8
+D 13
+L 2
+R 15
+D 7
+U 15
+D 16
+R 12
+L 12
+U 8
+L 8
+D 3
+R 16
+L 3
+U 13
+R 1
+L 5
+R 10
+U 13
+D 7
+R 3
+D 10
+L 2
+R 1
+U 4
+L 13
+U 15
+R 4
+D 1
+R 2
+L 5
+D 3
+L 1
+R 4
+L 1
+U 1
+D 7
+R 9
+L 12
+R 13
+D 5
+R 5
+D 9
+L 15
+R 17
+D 4
+R 2
+U 1
+D 1
+R 3
+L 15
+D 10
+L 8
+U 16
+L 14
+U 12
+R 5
+L 13
+D 10
+L 15
+D 12
+U 4
+D 8
+R 9
+L 17
+D 17
+U 3
+D 2
+L 14
+D 12
+L 5
+D 9
+L 3
+R 10
+U 1
+R 9
+U 16
+L 14
+R 13
+L 11
+R 4
+U 2
+L 10
+D 6
+R 5
+D 17
+L 15
+R 12
+U 15
+L 9
+U 9
+D 3
+R 8
+U 6
+R 8
+U 9
+D 14
+R 7
+U 1
+L 3
+R 3
+D 2
+U 4
+R 5
+L 17
+D 16
+U 13
+D 5
+U 6
+R 2
+U 5
+D 7
+U 11
+R 6
+L 17
+R 4
+L 14
+D 3
+U 15
+L 5
+R 4
+U 1
+D 16
+L 16
+U 10
+L 10
+D 17
+R 6
+D 2
+U 10
+L 10
+D 12
+R 15
+L 4
+R 11
+L 17
+U 15
+L 8
+U 8
+L 16
+D 6
+L 7
+U 17
+L 14
+D 6
+L 5
+R 14
+U 5
+D 1
+U 2
+D 17
+R 14
+L 1
+R 4
+D 7
+L 8
+U 7
+D 6
+L 16
+U 5
+D 7
+R 7
+D 17
+L 16
+R 1
+D 5
+U 17
+L 2
+U 7
+L 16
+U 15
+L 17
+D 3
+L 2
+R 7
+L 11
+R 1
+L 16
+U 2
+L 1
+R 18
+U 5
+L 9
+U 4
+D 8
+U 4
+L 18
+D 17
+L 14
+D 2
+R 1
+U 13
+L 9
+R 14
+D 14
+U 12
+D 14
+L 2
+U 10
+D 11
+R 10
+L 9
+U 7
+D 12
+L 4
+D 2
+R 17
+D 1
+U 15
+R 14
+D 16
+L 1
+R 11
+U 9
+R 8
+U 6
+D 7
+U 7
+L 2
+D 10
+U 9
+D 9
+L 11
+D 11
+L 14
+U 16
+D 11
+L 17
+R 5
+L 13
+U 16
+R 16
+U 18
+D 1
+R 1
+U 13
+R 6
+L 7
+U 11
+D 12
+L 8
+U 17
+D 11
+U 8
+L 14
+U 17
+L 4
+U 18
+D 18
+R 8
+D 13
+L 10
+U 3
+R 9
+L 14
+R 7
+U 14
+R 14
+L 9
+U 5
+R 4
+D 13
+U 10
+D 1
+R 10
+D 4
+R 3
+U 14
+D 10
+U 12
+L 11
+U 9
+L 16
+R 5
+L 14
+D 4
+U 11
+L 2
+R 10
+U 8
+D 9
+L 2
+R 16
+L 1
+R 12
+U 7
+D 11
+U 18
+D 4
+R 8
+U 18
+D 5
+R 15
+U 16
+L 2
+D 15
+U 5
+D 10
+U 18
+L 7
+U 4
+R 2
+U 17
+L 2
+R 3
+D 2
+L 2
+U 3
+R 10
+L 8
+U 4
+L 18
+U 6
+D 11
+R 13
+D 9
+U 10
+L 16
+R 15
+L 4
+D 1
+L 5
+D 7
+U 18
+L 5
+R 7
+L 15
+U 4
+L 6
+U 19
+D 19
+L 2
+R 2
+L 19
+D 9
+L 14
+U 18
+D 12
+R 19
+U 15
+L 16
+U 9
+L 11
+R 5
+L 14
+R 16
+U 19
+D 7
+U 8
+R 6
+U 14
+R 17
+D 9
+L 5
+U 3
+D 9
+U 8
+L 4
+U 12
+D 12
+R 13
+U 3
+R 18
+U 5
+L 12
+U 4
+L 1
+D 14
+R 5
+L 19
+U 17
+R 18
+D 11
+L 4
+U 18
+L 9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/10/10.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,122 @@
+
+const test_input = "10/test_input.txt";
+const input = "10/input.txt";
+
+@enum OpType begin
+    Noop
+    Addx
+end
+
+struct Op
+    type::OpType
+    arg::Int
+end
+
+function parse_line(s::S)::Op where {S<:AbstractString}
+    p = split(s, ' ');
+    if length(p) == 1
+        Op(Noop, 0)
+    else
+        Op(Addx, parse(Int, p[2]))
+    end
+end
+
+function parse_input(io::Iter)::Vector{Op} where {Iter}
+    map(parse_line, eachline(io))
+end
+
+function check_register(interest::Vector{Int}, cycle::Int, reg::Int)::Int
+    if length(interest) == 0
+        return 0;
+    end
+    if cycle == interest[begin]
+        popfirst!(interest);
+        cycle * reg
+    else
+        0
+    end
+end
+
+function evaluate(v::Vector{Op})::Int
+    interest = [20, 60, 100, 140, 180, 220];
+    reg = 1;
+    i = 1;
+    cc = 0;
+    acc = 0;
+    L = length(v);
+    for i = 1:L
+        op = v[i];
+        cc += 1;
+        acc += check_register(interest, cc, reg);
+        if op.type == Noop
+            # pass
+        elseif op.type == Addx
+            # first cycle;
+
+            # second cycle;
+            cc += 1;
+            acc += check_register(interest, cc, reg);
+            # done.
+            reg += op.arg;
+        end
+    end
+    acc
+end
+
+function draw_pixel(crt::Matrix{Bool}, cycle::Int, reg::Int)
+    row, col = (div(cycle, 40)), ((cycle)%40);
+    reg_ = (reg)%40;
+    if abs((col)-reg_) < 2
+        crt[row+1, col+1] = true;
+    end
+end
+
+function draw_crt(v::Vector{Op})::Matrix{Bool}
+    crt = zeros(Bool, 6, 40);
+    cc = 0;
+    reg = 1;
+    L = length(v);
+    for i = 1:L
+        op = v[i];
+        cc += 1;
+        draw_pixel(crt, cc, reg);
+        if op.type == Noop
+            continue
+        elseif op.type == Addx
+            # first cycle;
+
+            # second cycle;
+            cc += 1;
+            # done.
+            reg += op.arg;
+            draw_pixel(crt, cc, reg);
+        end
+    end
+    crt
+end
+
+println("part 1:");
+println("test:");
+open(test_input; read=true) do fh
+    println(evaluate(parse_input(fh)))
+end
+println("input:");
+open(input; read=true) do fh
+    println(evaluate(parse_input(fh)))
+end
+
+println("part 2:");
+println("test:");
+open(test_input; read=true) do fh
+    m = (draw_crt(parse_input(fh)));
+    for r in eachrow(m)
+        println(r);
+    end
+end
+println("input:");
+open(input; read=true) do fh
+    m = (draw_crt(parse_input(fh)));
+    for r in eachrow(m)
+        println(r);
+    end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/10/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,146 @@
+noop
+addx 5
+addx -2
+noop
+noop
+addx 7
+addx 15
+addx -14
+addx 2
+addx 7
+noop
+addx -2
+noop
+addx 3
+addx 4
+noop
+noop
+addx 5
+noop
+noop
+addx 1
+addx 2
+addx 5
+addx -40
+noop
+addx 5
+addx 2
+addx 15
+noop
+addx -10
+addx 3
+noop
+addx 2
+addx -15
+addx 20
+addx -2
+addx 2
+addx 5
+addx 3
+addx -2
+noop
+noop
+noop
+addx 5
+addx 2
+addx 5
+addx -38
+addx 3
+noop
+addx 2
+addx 5
+noop
+noop
+addx -2
+addx 5
+addx 2
+addx -2
+noop
+addx 7
+noop
+addx 10
+addx -5
+noop
+noop
+noop
+addx -15
+addx 22
+addx 3
+noop
+noop
+addx 2
+addx -37
+noop
+noop
+addx 13
+addx -10
+noop
+addx -5
+addx 10
+addx 5
+addx 2
+addx -6
+addx 11
+addx -2
+addx 2
+addx 5
+addx 3
+noop
+addx 3
+addx -2
+noop
+addx 6
+addx -22
+addx 23
+addx -38
+noop
+addx 7
+noop
+addx 5
+noop
+noop
+noop
+addx 9
+addx -8
+addx 2
+addx 7
+noop
+noop
+addx 2
+addx -4
+addx 5
+addx 5
+addx 2
+addx -26
+addx 31
+noop
+addx 3
+noop
+addx -40
+addx 7
+noop
+noop
+noop
+noop
+addx 2
+addx 4
+noop
+addx -1
+addx 5
+noop
+addx 1
+noop
+addx 2
+addx 5
+addx 2
+noop
+noop
+noop
+addx 5
+addx 1
+noop
+addx 4
+addx 3
+noop
+addx -24
+noop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/10/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,146 @@
+addx 15
+addx -11
+addx 6
+addx -3
+addx 5
+addx -1
+addx -8
+addx 13
+addx 4
+noop
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx -35
+addx 1
+addx 24
+addx -19
+addx 1
+addx 16
+addx -11
+noop
+noop
+addx 21
+addx -15
+noop
+noop
+addx -3
+addx 9
+addx 1
+addx -3
+addx 8
+addx 1
+addx 5
+noop
+noop
+noop
+noop
+noop
+addx -36
+noop
+addx 1
+addx 7
+noop
+noop
+noop
+addx 2
+addx 6
+noop
+noop
+noop
+noop
+noop
+addx 1
+noop
+noop
+addx 7
+addx 1
+noop
+addx -13
+addx 13
+addx 7
+noop
+addx 1
+addx -33
+noop
+noop
+noop
+addx 2
+noop
+noop
+noop
+addx 8
+noop
+addx -1
+addx 2
+addx 1
+noop
+addx 17
+addx -9
+addx 1
+addx 1
+addx -3
+addx 11
+noop
+noop
+addx 1
+noop
+addx 1
+noop
+noop
+addx -13
+addx -19
+addx 1
+addx 3
+addx 26
+addx -30
+addx 12
+addx -1
+addx 3
+addx 1
+noop
+noop
+noop
+addx -9
+addx 18
+addx 1
+addx 2
+noop
+noop
+addx 9
+noop
+noop
+noop
+addx -1
+addx 2
+addx -37
+addx 1
+addx 3
+noop
+addx 15
+addx -21
+addx 22
+addx -6
+addx 1
+noop
+addx 2
+addx 1
+noop
+addx -10
+noop
+noop
+addx 20
+addx 1
+addx 2
+addx 2
+addx -6
+addx -11
+noop
+noop
+noop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/11/11.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,61 @@
+
+const test_input = "11/test_input.txt";
+
+struct Monkey
+    items::Vector{Int}
+    operation::Function
+    test::Function
+    iftrue::Int
+    iffalse::Int
+end
+
+function test_init_monkeys()::Vector{Monkey}
+    # Manual parsing is easier for small numbers of monkeys.
+    [Monkey([79, 98], o -> o*19, i -> i%23 == 0, 2, 3),
+    Monkey([54, 65, 75, 74], o -> o+6, i -> i%19 == 0, 2, 0),
+    Monkey([79, 60, 97], o -> o*o, i -> i%13 == 0, 1, 3),
+    Monkey([74], o -> o+3, i -> i%17 == 0, 0, 1)]
+end
+
+function test_monkeys()::Vector{Monkey}
+    [Monkey([72,97], o->o*13, i->i%19==0, 5, 6),
+     Monkey([55, 70, 90, 74, 95], o->o*o, i->i%7==0, 5, 0),
+     Monkey([74, 97, 66, 57], o->o+6, i->i%17==0, 1, 0),
+     Monkey([86, 54, 53], o->o+2, i->i%13==0, 1, 2),
+     Monkey([50, 65, 78, 50, 62, 99], o->o+3, i->i%11==0, 3, 7),
+     Monkey([90], o->o+4, i->i%2==0, 4, 6),
+     Monkey([88, 92, 63, 94, 96, 82, 53, 53], o->o+8, i->i%5==0, 4, 7),
+     Monkey([70, 60, 71, 69, 77, 70, 98], o->o*7, i->i%3==0, 2, 3)]
+end
+
+function engine(init::Vector{Monkey}; rounds=20)::Vector{Monkey}
+    activity = zeros(Int, length(init));
+    for r = 1:rounds
+        #@show r
+        for (i,m) in enumerate(init)
+            #@show i
+            while length(m.items) > 0
+                activity[i] += 1;
+                it = pop!(m.items);
+                it_ = m.operation(it);
+                it__ = round(Int, it_%(19*7*17*13*11*2*5*3));
+                t = m.test(it__);
+                #println("Inspect item of worry level $it\nNew worry level is $it_\nWorry level div. by 3 is $it__\nThrow item to $(t ? m.iftrue+1 : m.iffalse+1)");
+                if t
+                    @assert m.iftrue+1 != i
+                    push!(init[m.iftrue+1].items, it__);
+                else
+                    @assert m.iffalse+1 != i
+                    push!(init[m.iffalse+1].items, it__);
+                end
+            end
+        end
+        if r % 1000 == 0 || r == 20
+            println(r, " ", activity);
+        end
+    end
+    println(activity, " ", prod(sort(activity)[end-1:end]));
+    init
+end
+
+engine(test_init_monkeys(); rounds=10000);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/11/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,56 @@
+Monkey 0:
+  Starting items: 72, 97
+  Operation: new = old * 13
+  Test: divisible by 19
+    If true: throw to monkey 5
+    If false: throw to monkey 6
+
+Monkey 1:
+  Starting items: 55, 70, 90, 74, 95
+  Operation: new = old * old
+  Test: divisible by 7
+    If true: throw to monkey 5
+    If false: throw to monkey 0
+
+Monkey 2:
+  Starting items: 74, 97, 66, 57
+  Operation: new = old + 6
+  Test: divisible by 17
+    If true: throw to monkey 1
+    If false: throw to monkey 0
+
+Monkey 3:
+  Starting items: 86, 54, 53
+  Operation: new = old + 2
+  Test: divisible by 13
+    If true: throw to monkey 1
+    If false: throw to monkey 2
+
+Monkey 4:
+  Starting items: 50, 65, 78, 50, 62, 99
+  Operation: new = old + 3
+  Test: divisible by 11
+    If true: throw to monkey 3
+    If false: throw to monkey 7
+
+Monkey 5:
+  Starting items: 90
+  Operation: new = old + 4
+  Test: divisible by 2
+    If true: throw to monkey 4
+    If false: throw to monkey 6
+
+Monkey 6:
+  Starting items: 88, 92, 63, 94, 96, 82, 53, 53
+  Operation: new = old + 8
+  Test: divisible by 5
+    If true: throw to monkey 4
+    If false: throw to monkey 7
+
+Monkey 7:
+  Starting items: 70, 60, 71, 69, 77, 70, 98
+  Operation: new = old * 7
+  Test: divisible by 3
+    If true: throw to monkey 2
+    If false: throw to monkey 3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/11/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,27 @@
+Monkey 0:
+  Starting items: 79, 98
+  Operation: new = old * 19
+  Test: divisible by 23
+    If true: throw to monkey 2
+    If false: throw to monkey 3
+
+Monkey 1:
+  Starting items: 54, 65, 75, 74
+  Operation: new = old + 6
+  Test: divisible by 19
+    If true: throw to monkey 2
+    If false: throw to monkey 0
+
+Monkey 2:
+  Starting items: 79, 60, 97
+  Operation: new = old * old
+  Test: divisible by 13
+    If true: throw to monkey 1
+    If false: throw to monkey 3
+
+Monkey 3:
+  Starting items: 74
+  Operation: new = old + 3
+  Test: divisible by 17
+    If true: throw to monkey 0
+    If false: throw to monkey 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/12/12.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,95 @@
+
+import DataStructures: PriorityQueue, enqueue!, dequeue!;
+
+const test_input = "12/test_input.txt";
+const input = "12/input.txt";
+
+const START = -1;
+const END = -2;
+
+const MAX_DIFF = 1;
+
+function read_map(fh::IOStream)::Matrix{Int}
+    lines = readlines(fh);
+    m = zeros(Int, length(lines), length(lines[1]));
+    for (i, line) in enumerate(lines)
+        for (j, char) in enumerate(line)
+            m[i,j] = char - 'a';
+            if char == 'E'
+                m[i,j] = END;
+            elseif char == 'S'
+                m[i,j] = START;
+            end
+        end
+    end
+    m
+end
+
+function find_start_end(m::Matrix{Int})::Tuple{CartesianIndex, CartesianIndex}
+    findnext((==)(START), m, CartesianIndex((1,1))), findnext((==)(END), m, CartesianIndex((1,1)))
+end
+
+function reconstruct_path(parents::Matrix{CartesianIndex{2}}, start::CartesianIndex, endd::CartesianIndex)::Vector{CartesianIndex}
+    v = Vector{CartesianIndex}();
+    current = endd;
+    while current != start 
+        push!(v, current);
+        current = parents[(current)];
+    end
+    reverse!(v);
+    v
+end
+
+function find_path(m::Matrix{Int}; start::Union{Nothing, CartesianIndex}=nothing)::Vector{CartesianIndex}
+    s, e = find_start_end(m);
+    if !isnothing(start)
+        s = start;
+    end
+
+    current_best = zeros(Int, size(m)) .+ 10000;
+    parents = [CartesianIndex((-1,-1)) for i = 1:size(m, 1), j = 1:size(m, 2)];
+    top = PriorityQueue{Tuple{CartesianIndex,Int}, Int}();
+    enqueue!(top, (s, 0), 0);
+
+    valid(x) = x[1] > 0 && x[1] <= size(m, 1) && x[2] > 0 && x[2] <= size(m, 2);
+
+    while length(top) > 0
+        (cb, dist) = dequeue!(top);
+        for mov in [(0,1),(0,-1),(1,0),(-1,0)]
+            nb = cb + CartesianIndex(mov);
+            if !valid(nb)
+                continue
+            end
+            if m[nb] == END && m[cb] >= 24
+                parents[nb] = cb;
+                return reconstruct_path(parents, s, nb)
+            elseif m[nb] == END || (m[nb]-m[cb]) > 1
+                continue;
+            end
+            if current_best[nb] > dist + 1
+                current_best[nb] = dist + 1;
+                parents[nb] = cb;
+                enqueue!(top, (nb, dist + 1), dist + 1);
+            end
+        end
+    end
+    []
+end
+
+function find_any_shortest_path(m::Matrix{Int})::Vector{Int}
+    positions = findall(x -> x == START || x == 0, m);
+    lengths = [length(find_path(m; start=p)) for p in positions];
+    sort!(lengths);
+    lengths
+end
+
+open(input; read=true) do fh
+    m = read_map(fh);
+    for c in eachrow(m)
+        println(c);
+    end
+    @time p = find_path(m);
+    println("PART 1: Path $p with length $(length(p))");
+
+    println("PART 2: All path lengths are $(find_any_shortest_path(m))");
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/12/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,41 @@
+abacccaaaacccccccccccaaaaaacccccaaaaaaccccaaacccccccccccccccccccccccccccccccccccccccccccaaaaa
+abaaccaaaacccccccccccaaaaaaccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccaaaaa
+abaaccaaaacccccccccccaaaaacccccaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccaaaaa
+abccccccccccccccccccccaaaaacccaaaaaaaaaaaaaaaacccccccccccccccccccccccccccaaaccccccccccccaaaaa
+abccccccccccccccccccccaacaacccaaaaaaaaccaaaaaccccccccccccccccccccccccccccaaaccccccccccccaccaa
+abcccccccccccccaacccaaaccccccaaaaaaaaaccaaaaaccccccccccccccccccccccccccccccacccccccccccccccca
+abcccccccccccaaaaaaccaaaccacccccaaaaaaacccccccccccccccccccccccccciiiicccccccddddddccccccccccc
+abcccccccccccaaaaaaccaaaaaaaccccaaaaaacccccaacccccccaaaccccccccciiiiiiiicccdddddddddacaaccccc
+abccccccccccccaaaaaaaaaaaaacccccaaaaaaacaaaacccccccaaaacccccccchhiiiiiiiiicddddddddddaaaccccc
+abcccccccccccaaaaaaaaaaaaaacccccccaaacccaaaaaacccccaaaaccccccchhhipppppiiiijjjjjjjddddaaccccc
+abcccccccccccaaaaaaaaaaaaaaccccccccccccccaaaaaccccccaaaccccccchhhpppppppiijjjjjjjjjddeeaccccc
+abcccccccccccccccccaaaaaaaacccccccccccccaaaaaccccccccccccccccchhppppppppppjjqqqjjjjjeeeaacccc
+abccccccccccccccccccaaaaaaaacccccccccccccccaacccccccccccccccchhhpppuuuupppqqqqqqqjjjeeeaacccc
+abcccccccccccccccccccaacccacccccccccccccccccccccccccccccccccchhhopuuuuuuppqqqqqqqjjjeeecccccc
+abacccccccccccccaaacaaaccccccccccccccccccccccccccccaaccccccchhhhoouuuuuuuqvvvvvqqqjkeeecccccc
+abaccccccccccccaaaaaacccccaaccccccccccccccccccccccaaaccccccchhhooouuuxxxuvvvvvvqqqkkeeecccccc
+abaccccccccccccaaaaaacccaaaaaaccccccccccccccccccaaaaaaaaccchhhhooouuxxxxuvyyyvvqqqkkeeecccccc
+abcccccccccccccaaaaacccaaaaaaaccccccccccccccccccaaaaaaaaccjjhooooouuxxxxyyyyyvvqqqkkeeecccccc
+abccccccccccccccaaaaaacaaaaaaaccccccccaaaccccccccaaaaaaccjjjooootuuuxxxxyyyyyvvqqkkkeeecccccc
+abccccccccccccccaaaaaaaaaaaaacccccccccaaaacccccccaaaaaacjjjooootttuxxxxxyyyyvvrrrkkkeeecccccc
+SbccccccccccccccccccaaaaaaaaacccccccccaaaacccccccaaaaaacjjjoootttxxxEzzzzyyvvvrrrkkkfffcccccc
+abcccccccccccaaacccccaaaaaaacaaaccccccaaaccccccccaaccaacjjjoootttxxxxxyyyyyyvvvrrkkkfffcccccc
+abcccccccccaaaaaacccaaaaaacccaaacacccaacccccccccccccccccjjjoootttxxxxyxyyyyyywvvrrkkkfffccccc
+abcccccccccaaaaaacccaaaaaaaaaaaaaaaccaaacaaacccccaacccccjjjnnnttttxxxxyyyyyyywwwrrkkkfffccccc
+abcaacacccccaaaaacccaaacaaaaaaaaaaaccaaaaaaacccccaacaaacjjjnnnntttttxxyywwwwwwwwrrrlkfffccccc
+abcaaaaccccaaaaacccccccccaacaaaaaaccccaaaaaacccccaaaaacccjjjnnnnnttttwwywwwwwwwrrrrllfffccccc
+abaaaaaccccaaaaaccccccaaaaaccaaaaacaaaaaaaaccccaaaaaaccccjjjjinnnntttwwwwwsssrrrrrllllffccccc
+abaaaaaaccccccccccccccaaaaacaaaaaacaaaaaaaaacccaaaaaaacccciiiiinnnntswwwwssssrrrrrlllfffccccc
+abacaaaaccccccccccccccaaaaaacaaccccaaaaaaaaaaccccaaaaaaccccciiiinnnssswwsssssllllllllfffccccc
+abccaaccccccccccccccccaaaaaaccccccccccaaacaaaccccaaccaacccccciiiinnsssssssmmllllllllfffaacccc
+abccccccccccccccccccccaaaaaaccccccccccaaaccccccccaaccccccccccciiinnmsssssmmmmlllllgggffaacccc
+abcccccccccccccccaccccccaaacccccccccccaaccccccccccccccccccccccciiimmmsssmmmmmgggggggggaaacccc
+abcccccccccaaaaaaaaccccccccccccccccccccccccccccaaaaaccccccccccciiimmmmmmmmmgggggggggaaacccccc
+abccccccccccaaaaaaccccccccccccccccccaacccccccccaaaaacccccccccccciiimmmmmmmhhggggcaaaaaaaccccc
+abccccccccccaaaaaacccccccccccccccccaacccccccccaaaaaacccccccccccciihhmmmmhhhhgccccccccaacccccc
+abccccaacaaaaaaaaaaccccccccccccccccaaaccccccccaaaaaaccccccccccccchhhhhhhhhhhaaccccccccccccccc
+abccccaaaaaaaaaaaaaaccccccccccaaccaaaaccccccccaaaaaacccaaacccccccchhhhhhhhaaaaccccccccccccccc
+abcccaaaaaaaaaaaaaaaccccccccaaaaaacaaaacacaccccaaaccccaaaacccccccccchhhhccccaaccccccccccaaaca
+abcccaaaaaacacaaacccccccccccaaaaaaaaaaaaaaacccccccccccaaaacccccccccccaaaccccccccccccccccaaaaa
+abcccccaaaacccaaaccccccccccaaaaaaaaaaaaaaaaccccccccccccaaacccccccccccaaacccccccccccccccccaaaa
+abcccccaacccccaacccccccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/12/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,5 @@
+Sabqponm
+abcryxxl
+accszExk
+acctuvwj
+abdefghi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/13/13.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,83 @@
+using ParserCombinator
+
+List = Delayed()
+IntOrList() = PInt64() | List
+ListElement() = (IntOrList() + Repeat(E",", 0, 1))
+List.matcher = (E"[" + Repeat(ListElement()) + E"]") |> identity
+
+const Element = Union{Int,Vector};
+const IOL = IntOrList();
+
+function any_to_elem(v::Any)::Element
+    if isa(v, Vector)
+        [any_to_elem(e) for e in v]::Vector
+    elseif isa(v, Int)
+        v::Int
+    end
+end
+
+function compare_lists(a::Element, b::Element)::Int
+    if isa(a, Int) && isa(b, Int)
+        a < b ? -1 : (a == b ? 0 : 1)
+    elseif isa(a, Vector) && isa(b, Vector)
+        for (i, (x,y)) in enumerate(zip(a::Vector, b::Vector))
+            c = compare_lists(x, y);
+            if c != 0
+                return c;
+            end
+        end
+        return compare_lists(length(a), length(b));
+    else
+        if isa(a, Int)
+            a = [a];
+        elseif isa(b, Int)
+            b = [b];
+        else
+            error("unknown types: $a vs $b");
+        end
+        return compare_lists(a, b);
+    end
+end
+
+function sort_lists!(e::Vector{Element})
+    sort!(e; lt=(a, b) -> compare_lists(a, b) < 0)
+end
+
+function parse_list(s::String)::Element
+    r = parse_one(s, IOL);
+    any_to_elem(r[1])
+end
+
+function run_file(f::String)
+    open(f; read=true) do fh
+        v = Int[];
+        m1, m2 = parse_list("[[2]]"), parse_list("[[6]]");
+        lists = Element[m1, m2];
+        i = 1;
+        while !eof(fh)
+            l1 = readline(fh);
+            l2 = readline(fh);
+            _sp = readline(fh);
+            a, b = parse_list(l1), parse_list(l2);
+            push!(lists, a, b);
+            if compare_lists(a, b) < 0
+                push!(v, i);
+            end
+            i += 1
+        end
+        @show (v, sum(v))
+
+        sort_lists!(lists);
+        for (i, l) in enumerate(lists)
+            println(i, "  ", l);
+        end
+
+        i, j = findfirst((==)(m1), lists), findfirst((==)(m2), lists);
+        @show (i, j, i*j);
+    end
+end
+
+println("PART 1 TEST");
+@time run_file("13/test_input.txt");
+println("PART 1 INPUT");
+@time run_file("13/input.txt");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/13/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,449 @@
+[[[],[],8,3],[10]]
+[[[[7],[0,4,6,1]],[[2,1,5,3,6],[]],[3,[10,9,1],2,[10,6,10],7],2,7],[5,[3],7,10,[8,[4,7,1,7,8],[],1,[8,6]]],[5,7,[[5,5,7,2,10],[8,7,10,4,7],[9,4,9,9,1]],[[8],8,5,[7,3,4,6,1],1]]]
+
+[[[5,5,[0,7,6,6,0]],[],0,9],[[[0,7,3,10,5],5],7],[10,[],1,[],5]]
+[[4],[2,[10,[5,7,8,7,0]],[4,8,[1,2],[5]],3,9],[[[3,3,3,5,4],5,[],7,[7,3,10,4,0]],9,[3]],[2,0,6,[9,5],8],[[4,[9,8,6],[],5],3,[7,7,[3,3,6],7,[9,4,0,10,6]],10,[]]]
+
+[[2],[3,[[],[1]],[],[0,[10,7]]],[[]],[7,[6],8,[9,0],[2]]]
+[[[[],7,8]]]
+
+[[],[[],8,5],[4,9,[[8,4,7,6,9],[4]],3,[[0,3,4,3,1]]],[3,5,[[0,6,4],5,[1,5,6],6,[8,7,1,7]]],[1]]
+[[8]]
+
+[[],[[3,3,[7,0,9],1],3],[[[10,7,6],8,0,0],10],[[3,4],[0,10,[1,6,1,5,1],[]]],[[[10,10],[9,7,3]],2]]
+[[10,0,4,[1,1,[4,10,5,7],10]],[[],[3,5,[5,5],[],[1,0,4,9]],0],[[]]]
+
+[[[[10,7,1],0],[7,[4,9,3],[0],[]],[],8],[[[6,3,2],[4,6,0]],[4,2,[0,2]]],[[],1,6,2,[2,[10,10,4,9],0,[7,1,0,7,6]]],[9,3]]
+[[[[4,4,2,2],[5,0]]],[5]]
+
+[[],[[5,6,[],[7]]],[7]]
+[[10,6,9],[[9,4],[5,4,4,[2,2,8],5],10,[[]],9],[]]
+
+[[[],[2,6,[],[4],[0,5,6,7,4]],4,9,3],[],[[[6],7,9],[],9],[[[1,5,0,4],4,[2,9,3,3,7]],1],[10,2,2,[[0,6,8,4],[9,3,8,5],3,5,3]]]
+[[],[3],[[[],[],[10,1,2],[],[1]],0,9,[]]]
+
+[[0,[6,[10,0,0,4],[6,6]],[],7,[8,[2,6,8,6,10],5,7,0]]]
+[[[6,[7,6,9]],8,[4,1,[4,7,2]]],[[],8],[[2,[0],0,8],1,8,[6,4,1,[3,3],6],[[9,8,4,1],[5,7],9]],[[[3],5],2,5],[9,[[8],3]]]
+
+[[],[2,[4,[6,2,10,7,7],[]]],[7,[7,[1,7]],[[9,2,8,10,8]]],[5,[[0,10,10]],[1],1,[[],10,0,[]]]]
+[[[[1],[7,10]],5,9,[[],[1,8,7],0,[2],6]],[],[[7,[],6,[],6],[[1],8,0],[[3,0],[0,7],[2,0,3,6],[9,6,0]],[[0,1,7]]],[0,[7,[1],1],4,10]]
+
+[[7,7,[[],[7]],1,[0,10]],[10,4,8,6,5],[7],[[[2,4,8,7]],[[10,1,6],[6],[5,5,6,8],7,[0,5,2,3,4]]]]
+[[[8],[[4,7],[8,10,0,10,8]],0,8,3],[[9],[8],[[1,2],5,0,[7,0],[1,3,10,8]],[0,4,[3,10,0]],[10,[],[]]]]
+
+[[],[8,[9],9,3,7]]
+[[6,8,[5,4,[],[8],3]],[],[8,[4,[9,3,7,1],[7,1,9,5,7],[7,4,5],2],[9]]]
+
+[[[[0,7],1,2,[7],10]],[6,7,6,[[3,7,2,7],[10]],[2,[9,9,5,7],[0,4,4],[5,8,2]]],[2,2,8,2],[[]]]
+[[],[10,[[0,10,1],7,0,9],6],[[4,6,[1,7,9],7,[5,3]]],[2,[[10,10],[8,0,3,8,2],[6]],2,7],[[6,3,4,1,[4,7,7,2]],0,[[1,3]],[[0,9,3,6],0,[5,6,6,0],10]]]
+
+[[[3],0],[1,1,4]]
+[[6,[8,[2,5,2],[6],2],[1,8]],[3,3,7,[[2,10,1,5],[]],1],[[9,[8,6,7,3],[9,9,6]]],[[[],[9],9,6,2],1,[8,10,2],[],3]]
+
+[[[[1],[3],7,[8,0,7],6],3],[],[8]]
+[[6,7,[4,[8,2,1,5],8]]]
+
+[[8,[[],9,[4,6]]],[9,[10,[8,7,4,1,2],[3,3,2,10,7]]],[4,[[4,5,2],8,3,[3,4,10,5]],10,10,[[1,10,4,10]]],[[8],[[5],[6,1,0],2,10,2],3]]
+[[[10,5],[[0],[7,9,3],[2,7,5,2]],[7,10,[8],6],[[6,6,4,5,9],[3],4]]]
+
+[[3,6],[1,[],3,9,[]]]
+[[9,[],6,[],[[3,8],[6],7]],[[],[0,9,5,[9,1,9]]],[[9,10,[8,3,7]]]]
+
+[[],[1]]
+[[0,[],[5,[],5],[[]],2],[5,7,9],[1]]
+
+[[[[9,9,2,9],[0,6,4,5,2],[8,2,2]],[0,7,4]],[5,9,[0]],[[10,[9,5,10,4],5,0]]]
+[[[[9,6]],[],[[9],10,7,4,[9,0]],5]]
+
+[[[[7,2,1,6,6],9,[1,7,8],8],[5,[3,8,8]],[[5,0],[2,1],[3,0],5,[7,7]],[[],[4,6],[4,6,5,4]]]]
+[[7,7]]
+
+[[9,1,[[5,10,6,7],[4,6,5,10,1]],[[4,7,9],5,[6]]],[4,[2,[2,2,5,3]]],[[3,[4]],[],2]]
+[[7,[0,8,0,[10,8,10]],[1],5]]
+
+[[3,6,6,5],[8,[[4,5,6],5,[8,3,0,1],[10,5,2],[5,0,7]],[],4,[[0],[]]],[2,[4,[6,5,6,9,0],[],[3,0,2,9,8],[10,4,9,5,1]],7],[[[7,3,5,2,7],[2,2,5,6,9],[6],0],[8,8,7,[2,1,3,9]]]]
+[[[8,7,[7,4,8]],[]],[],[],[],[2,[[1,8,5,0]]]]
+
+[3,3,5,9]
+[3,3,5,9,6]
+
+[[],[[[],[3,4,0],9,[],1],0,2,[0,[5,2,6,8],[9,4,8,8]]],[[[10,6],[5,6,4,3],[],5,[4]]],[0],[]]
+[[[5,9,7],2,[[2,0,7],[2]],10],[[[9,6],[3],4,[],[9]],0,[[9,5]]],[1,[[10,4,6,9],5,3],1,[10,[9,7,0],[8]]],[[0,[9,7,5,10,4]],0,0,2],[[[]],7,2]]
+
+[[[1,6,2,5,4],7,[8,8,9,9,[6]],[[],7,[],[10]]],[[[1,0,0,5,5],8,5],[[],1]]]
+[[5],[],[[[7,4,8],9,8],2],[10]]
+
+[[10,1],[[[0]],[]],[[5,[9,1,0],[],8,4],1]]
+[[[[10,0],6,[8,6,7],1,2]],[[[7,3,8],[],[],3,[4,0,6]],[10,[6],9],[[9,1],[],[5,1,3],[],2]],[[1,[2,8,6,6],[6,9],[3,8],[4,10,8]]]]
+
+[[[4,10,8,6],5],[8,[[3,4],[2,0,1,10,9],6,[4,10,10,8]],[9,[2,9,7]],[7,[0,9,6,1,0],6,5]],[]]
+[[3,[[1,10,1,1,8],8,[7,6,0],[6,10,5,3],[2,3,2,2,6]]],[]]
+
+[[[],[[1,6,3,8,9],[7,0,2,4,3],[4,5,3,6],3,[2,2,10,9,0]],3]]
+[[],[[[8,8,10],[10,2,7,8],[1,0,7,4],[2,8,8,2],9],8,10,10,1],[[[3,2,6],[0,2,9,9,10]],[6,[],4,0,[5,4]],[[4,1],0,[],3,5],7,2],[]]
+
+[[[0,[7,1,6,4],[2,3,4]],[],[]],[[1,[8,4,2,9],8,9],6,[8,10]],[5,[[3,10]],5,[]]]
+[[0,10,[],1],[],[4,8],[],[]]
+
+[[[5,3,[0,10,1,1],[],[]]],[6,8,[]],[4,2,[2,0,[1],1]],[],[[[4,8,0],[0,7,9,8,6]],[[0,0],[9,10,3]],[[2,4,2],0,2,10],6,[5,[4],[4,2],[2,4,4,0,10]]]]
+[[[[1,9],[10,2,9,2,3],[8,7,4,8,4]],2,[7],[[0,1,5,2],5,5,10,10]],[[1,10,4]],[5,[],[[3,1,3,6],[7,1,9,1],[0,3,8],6,3]]]
+
+[[2,[]],[[[9,0],[3,9,6,10,9],3,3,5]]]
+[[[0,1,[3,9],9]],[[7,[1,10,3,3,3],2,5],2,8],[10,10,[[0,3,8,0],10,[2,4,0,4],3],[[2,6,4,3,1],4,[8,9],[]],[[],[1,5]]]]
+
+[[[],9]]
+[[],[0,5],[[4,8,[10],3,[8,9,4,4,4]]]]
+
+[[[6,[3,1,1,4]]],[0,[9,[9],6],[[],9,[],0,[6]]],[8,[0,9],[2,10],9],[[8,[1,10],[9,0],[6],9],[4,[],[10,10]],[[4,2,8,8,10]]],[[7,[4],[3,8,0,3,0]],1,[8,[2,8,5,2],[0]],[10,[2,0,2,4,6],2],[1]]]
+[[[7,[],5,[8,8,10]],4,[1]],[[7,10,0],3,[7,[3,10],[3,8,5,0,7]]],[6,[[2,5],8,10,[2,8,5,1],[4,7,2,4,0]],2]]
+
+[[4,0,10,1,[[1,6],2,9,10]],[[[3],[3,0,8,9,7],[5,6]],[[4,2,10,8],[1,9,10,6],6],6,[[5],4,[],[],1]]]
+[[4,[],[8,3],9],[[],[0,8,[6,9,6],[10,6]],4]]
+
+[[5,9],[1,5,6]]
+[[3,[8,[0,5,7,4,2],[4,4],[7,10,3,1]],0,4],[[7,[0,8,6]],[[3],[7,9],[],[3,6,4]],2,4]]
+
+[[10,[]]]
+[[],[7,[[0],[10,4,0,1]],3,[[7,0],[1,3],8,[6,0,3,1],1],[10,5,10,9,[]]],[3,6,4,5,3]]
+
+[[],[[[2,8,1,9,8],[7,0,1,10],[9,0,4,7,6],5],4,[]],[]]
+[[0,5,5],[2],[[]],[7,[[1,0],[4,9],5]]]
+
+[[10,5],[],[4,[],3,0],[3,3,9,[]],[]]
+[[],[[[8],[1],7],4,2,[1]],[1,10,5,[2,3]],[[8],[[5,6,6,3,0],[2,1]],3],[2,7,[10,[],[0]]]]
+
+[[[3,5,[5],[8,8,3,7],9]],[],[0,[],0,3,7],[1]]
+[[2],[[[9,9],[0,7],8,[]],5]]
+
+[[4,8,6],[[5,10],[[2],8,[],4],[[10,7,6,5,10],[3,8,7],[3,1,0,2],[8,8,7,1,5],8]],[6,8,0,[[8],4,[1,0,0],2],[[2,7,6,10,1]]],[1,[0,5]],[2,[],[],4,[[4,5,9],[5],4,[1,1,9]]]]
+[[[4,8,4,[5,0,8],10],0,[[10,2]],4,0],[[5],4,5,[[2],[5,6],[1,2],5,6]],[[[3,5,2,8],[7]],[3,[6],[1,4,6,5],[3,0,6,8,2]],9,2,7]]
+
+[[],[],[7,2],[[]]]
+[[6,[[8,6,4,9,0]]],[[5,[9,6,2,4],[],2],5,7,[[1],10,[0],[8,5,4]]]]
+
+[[],[[[7,8,4,9]],[2,[10,5]]]]
+[[0,2,2],[[[8,6,0,9],[],6,8,[6,1,5]],4,4]]
+
+[[7,7,[4,[2,7,6,8,4],[5,9],8,[6]],[1,1,0,2],1]]
+[[[6,1],[],[]],[[5,9,[0]],[[2,7,6],4,[5,10,1,5],[],7]],[[2,[9,0,9,10]]],[6]]
+
+[[3,[3,3,6,[8,0],[6,4]],2,0,[[5,0,4,1],1,[0,7,6,6,7]]]]
+[[],[5]]
+
+[[[[1,10,1,5],[2,1,0,4,10],[4]],[[0,6,3],[4,1,6],9,7],[[7],[5,6,8],5,4,[10]],1,[0,[9,4],9]]]
+[[],[3,[],5],[]]
+
+[[],[[],[3,5,0,7],[1],2,10],[3,[],0,[[9,0],[0,0,2,5,9],[1,6,2,6]]]]
+[[5,[7,7,[1]],[[],3,[2,8,7],[3,9,6]]],[0,[[7,10,1,3,8],5,[5,4,3,1,9],[2]],2,[[5,10]]]]
+
+[[[[10,3,8],8,3,2,[7]],2,[[5,5,2,4],7],6],[7,0,[6,[4,9,9,5],[3,1,6,2,6],5],[1,4,2,9],[8,8,[10,4,10,9],[3],[2]]],[]]
+[[],[[4,6,[7,6]],[],[]],[[[],0,2,[7,4,0,9],[4]],[],0],[]]
+
+[[5,6,[10,[8,10],[],10,[10,0]],[1,[8,4,6,2]]],[],[[[8,10,10,1]],[],[4,[10,9,7],10]],[[],[[1,10,4,0],[]],[6,9,[4,2,4],7,0],[7,[4],[8,0,7,8,4],[3,5,5,3]]]]
+[[[],[[10,0,3,2]],7]]
+
+[[[[],1,[8,5,9]],2,[[1],[9,3,1,2,2],5,2,[]],9,[3,[],[2,1,7],8,[0,1]]],[[[1,6,1,6,5],[2,10,2,1,7],[0,6,0,4,2]],[],3],[8,10],[[[10,2,7],2,7,[]],5],[[6,1],[8,[],[3],[4]],6,8]]
+[[[],10,6,7,[4,9,[9],6]],[[]],[[],[6],8,0],[[[10],[8,8,3,8],8],[7,[]],[]]]
+
+[[[[10,0,8,1],[7,6,6],[6,9,9,0,10],[7,4,3]],[[9,10,3,4]]],[[1,[0,3]]],[5,1,2,[9,[],[0,4,10,10]],9],[[9]],[7,6,8,0]]
+[[[[4],3,2,[]],[9,[],4,6,[5,1]],2,[]],[[6,[6,10],[],[],[6,6,10]],7,[5,7],[[9],4,[6,10,0,3],[]]],[[2,[1,8]],3,[9,[0,6,10]],[],3]]
+
+[[7],[7,[[7,8],[0,7,1,4]]],[10],[10]]
+[[],[],[[[9,3,4,2],[4,5],1,[8,0,7,8,4]],6]]
+
+[[[4,[],[0,0,3,6],2],9,[],7,0],[[],9,[],[],[0,0,1,1,[5,5]]],[3,10,[8],2,[5,[],5,[2,3],5]],[[[10,4,9],[10,9,10,0],[4,7],[10,2]],3,[0,2],10,1]]
+[[[],6,[],[2,5]],[[[7],[6,6],0,5],[4,4,[8],2,[0]],8,[4],1],[],[8,1,9,[10,[9,7,2,0]],[]],[10]]
+
+[[8,[],2],[[[3,9,5,9,2],[2,3,10,6]],[5,[6,5,10,1],[7,9],[2,10,3,7,10],[4,0,9]],9,0],[1,[[7,6,1,4]],10,9],[],[[[3,8,7,7,6],[2,9,4,5],[10,1,5]],3,[6,8]]]
+[[5]]
+
+[[8,0,3],[[[],[2,5,7],3,7,[5,10]],[8,5],0],[7,[[3],[9],0,9],[],[[],8]]]
+[[8,[4,[2,6],2]],[],[[[5,3,7,8,6],[2,9],2,[],[9,4,8]],5],[9,[[7,10,3,10,1]],10,9,0],[[3,7,[0,5],3,3],0]]
+
+[[],[],[1]]
+[[[2,[9,8,0,1,7]],[9,10]],[10,[[],[9,5],10],7,2,1]]
+
+[[4,[7,8,7,[5,5,1,1],0]],[[1,[9],[0,3,0,8],[5,2],1],1],[[[4,5,3],[3,10,3]],5,5,[[8,0]]],[[[],5,[0],3,7]],[[2,[5,4,1,3],[0,7,4,10,2],1,7]]]
+[[0,[[4,0,8,0]],[[2,2,9,4,2],[],[5,4,3,1],6]],[],[8,8,10,10,3],[[2]],[[9,4,10]]]
+
+[[5,[2,0],10],[9,7,[[],8,[8,1,2]]],[[],[[5,10,7,4],[3,1],[7]],7],[7,8,10,2],[[],[]]]
+[[[7,2],10,2]]
+
+[[1],[[5,2],[[10,3,3,8,7],[],2,5]],[],[[[7,4,8],0,[1],8,6]]]
+[[7,10,[9,[0,5],0,[8],0],4,[[6],0]],[],[],[[0,2,[7,4,9]],[3,6,8,[1]],10]]
+
+[[[6,3],[[7],[1,6,3,5],3,[]],[[10,1,1,5],3,[]]],[[[3,4,6,0],[1],[1,10,4]],[],5]]
+[[],[[],[5],[[]],3,6]]
+
+[[4,[1,0],[[10,2],4,[6,1,0],[4,4,3]],[[10,9,4],4,4,[1,9],[7,0,0]],[]],[[8,3,[8,10],4]],[[1,[],0,9,4],3,5,[]]]
+[[[[7,10,0],8],5,[4]],[],[[6,[10],[6,10,7,5,9],7]],[]]
+
+[[],[2,7,[5,[5,7],[3,8,4,3,7],[]]]]
+[[],[7,9]]
+
+[[3,[],[[5,9,7,2,3]],3,3],[[],9,[4,[7,6,9,5,8],7],9,2],[],[[7,[8,9,7,5],3,[5,2,5,9,1],[7,4,3,10]]]]
+[[[[8,5,6,0,0],[9,7],9],[[1],3,1,4,0]]]
+
+[[2],[0,1,0,4,[10,[1,8,7,5],[2,9,3],5]],[0]]
+[[],[[[9,2,9,0,0],[2,9,1,9],[8,4,4]],[[6,5,8],0,[0]],[10,8,[9,9,4,6],8]]]
+
+[[[4]],[5,[9,[6],[0,2],[],0],[[3,4],[3,6],[7,3]],[[9,7,4,7,6],[8,4,1],[8]],[]],[],[6,2,[[5],9,10],8,0]]
+[[7],[5]]
+
+[[5],[[[8,4,7,2,8],[8,7,3],6,[],6],1,[5,[6,5]],7,7],[[10],[],7,[8],[0]]]
+[[[]],[6],[[],8,7,[3],[4]]]
+
+[]
+[[],[[[6,8,0,8],[],8],[[5,1],7,8],1,10,[8]],[3,5,[[9,6,3]]],[[2],3,[[4,9],3,6,2,[1,0,8,5,4]],7]]
+
+[[[8,[7,9,7,4],4],3,[7]],[[[10,2]],4,4,[4,[7,4],[4],1],5]]
+[[[],[[8,3,5,2,7]],[[],5],[],[9,2]],[5,[5,5,[5]],[]],[0,9,9,[]],[[5,4]],[]]
+
+[[0,1,[1],10,4],[[[10,1,8]],9,0],[3,[0,2],0],[9,0,10],[]]
+[[[[2,1,0,0,4],[],0]],[],[0]]
+
+[[7,7,10,[]],[3,[],[[6,10,7,4],0,9,[0]],[[10,2,7,6],[9],8,4,[3,5,6,0]]]]
+[[],[4,[9,6,6,[0,3,1]]]]
+
+[[0,4,[[0,8,6,4],4,7,10],[8,[10],2,8],2],[6,[[6,3,6]],4,10],[2,6],[],[[],[[2,7,1,1],[10,4,7,1],[6,10,4,0]],6]]
+[[[2]],[[[9,4,5,2],5,7,[],[]]],[10,8],[3,8,[6,[0,10,10,0,2]],[[5,6,6,10],7]]]
+
+[[8,[[7,6],[8,1,7]],[],5,2]]
+[[6,7,[2,7,[7,1,8,5,1],1,5],9]]
+
+[[1,[],1],[],[7,[[2,10],8,[8],[10,1,9,4,10],[1,9,5]],[[9,4,9],[2,2,1,3,4],0,[8,3]],7]]
+[[[4,[10,9,9,2],3,9,4],[1,10,4,8,4],6,4],[7,1,[3,3,9]]]
+
+[[[[2],[6,7,4,1],[9,3],1,[5,0,9,4]]],[[[2,5,0,0,1],[3,3],[9,1],9,1],9]]
+[[],[[1,[3,6,7,4,10],[7,2,6,0,6],[7],6],5,5],[[[5]],2],[[[3,9,4,9,4]]]]
+
+[[[3,[3,0,9],9],[[10,9,1,8]],[6,8,[6,7,5,10,4]]],[[[],2,[],[9,3,8],8],[5,0,2,[],[0,9,4,3]],[[],1,8,1,0],[]],[[[4,7,8,6,2],6,9,[1]]],[4]]
+[[[[],8,10,[6,6]],0,0,[10,[],[0,2,8,3,7],[7,5]],[[0,4,0],3,10,2]],[4,[],0,[],6],[[[7,8,0],[7,5,7],[10,4,3],[1,5,2],9]]]
+
+[[],[[[6,10],7,1,0,[]],[[9],[8,9,9,10,8],0,8],2]]
+[[10,0,4,[[0,2,10],[9,2,4,7,7],[5],[9]],[[3,2],[2,9,10],[3]]],[2,1],[10,[5,[2,8,2,4],6,4],4]]
+
+[[8,[[4],[2,9,10,6],0,4,6],[[7,5,3,0],[9],4,[7,5,10,10]],[]],[]]
+[[[[]],1,[[],[10,7,2,1],[6]],6]]
+
+[[[[1,6,7,3],3],[1,[7,0,6],7,4,[7]],[2,5],0],[[],[[4,5,3,4],5],[7]]]
+[[5],[[],[],5,[[8,3,3]],[[],3,8,9]],[[0,[0,2,9],[2]],[[8],4],[[0,3]],[[6,4,4,3,2]],[[0],[],[0,9,10,1],8,8]],[2,[[],[7,7,0]],[[5,7],[8,2,8,1,5]],[[9,2,6],[1,5,9,1]]],[[[2],[]],[8,7,5,[2]],[[2,1,8,1],5,4,6,[0,5,6]]]]
+
+[[],[1,6,10,1],[[8,9,[3,8]],10,7,[[0,8,6,7,10],[7],[1,0],2],9],[[[4,1,0,10],1,4,[8]],0,[4,10,9]],[8]]
+[[[[4,8,9,3],6],5,[],5],[]]
+
+[[[10]],[[],8],[[[6],7,9,[6,6],10],[8,4]]]
+[[8,5,3,[],2],[8,[8,[0,0],5]]]
+
+[[[1,0,[],[8,8,3,2],0],2,2,[10,[7],[2],7]],[10]]
+[[1],[0,[[6,7],[1,10,7,6],[1,8,7,4],10,5],5],[[4,0,[7,0],[8,3,8,6]],[[2,4,10,8,6],3],8,[]],[[4,[9],[7,4,10],[4]],[3,[6,6],[],5],9,[]],[[[6],[2,1,1,3,5],[2,9,3]],6,[[1],[5,7,5]],[[4,3],[8,2,6,4,6],0,5,[5,8]]]]
+
+[[],[[6,[1,0,0,9],1,6],[[4,9],0,1,7,[2,2,10,7,3]],1]]
+[[],[[[4],1,10],[],4,[[9,4],0],[[9],[10,1,10],10,2]],[8,7]]
+
+[[[],7,[[8,4,9,2],[2],4,9]],[[[0],5,[],10,[]],[3,[1,9,9,2],[9,10,0,0]],[7,9,[8,7],2],[9]],[9,[[9,4,6,8,10],8]],[[[0],5],10]]
+[[7],[0,6,[[6],[],3,[3,8,6,2,8],6]],[9,6,0]]
+
+[[[[4,4,7],[6,7,2,2],[]],1,[[],7,0]],[[5],[2,2,[3]],[6,2,4,[]],[[3,8],1,[8,6,0,10,5],[8,10,6,1]],3],[8]]
+[[0],[[10,[],[10,4,7,3,10]],[[5,9],7,5,8],9],[9,0,5,1],[]]
+
+[[0,0,[[6,10,1,5],[8,0,4],10,[10,9,1,5]]],[[4,[2,1,1,5,4],[5],[]]],[3,7,0,[],10]]
+[[3],[4,5],[6,[4,5,[]],5,4]]
+
+[[[[6],6],10],[]]
+[[[],7,[[4,3],[7,3],1],[4,[7,6,6,3,9],[2,2,0,8],2]],[1,5,[[5]],[[0,2,5,2]]],[[[4,8,10,0,3],[6,1,8,1,4]]],[],[1,[[],[],2]]]
+
+[[9,[]],[7,[[3,0,2],[],10,6,[10,7,8,4,6]]]]
+[[7,6]]
+
+[[8],[2],[6,1],[6,[4],[],[4,8,[5,2],5]]]
+[[],[[[1,9,0,1]],3,5,[6,[3,4,3],5,[6,3,7],[2]]],[5,[[3],0],5,[],5],[7,[[9],10],4,9],[]]
+
+[[[9,[8,5,4,8]]],[3,[7,[6],3],2,[5]],[[[1,8],[6,6,5]],6]]
+[[2,[[2]]],[10,6,3],[[[10,4],0],[],[5],[],[0,[10],[1],[1,2,7]]]]
+
+[[[[],[],6,[10]],[],7],[3,[10,9,2,[]]],[5,[[10,10,2,7,0],6,[]],[8,[0,7]],[[0],1,[9,10],4,2],[]],[]]
+[[[9,[5,4,6,9,5],[10]],[[5,9],0,6,5,10],[5,[2],[4,9,4,9,0],[5,4],[0,1,3,6]],3,[[3,9,7],[6,10,0,0]]],[[7,8,10]]]
+
+[[[3,[4,0,0,9,8]],2,0,[6,[5,7]]],[[9],[],4,0],[6,2,[9],[10,[5,4,9,10],6,4]],[9],[6,6,[[7],[6]],[[8,0],5,10]]]
+[[],[8,1,0],[5],[9,5,[6,[6,10,6]]],[]]
+
+[[8,7,[5,1,[4,1,3],[8,1,0,8,2]],3,0],[[[0,1,3,1,1],[9,7,2,4],4,6,4]],[10,5,7,4]]
+[[7,[]]]
+
+[[0,7],[],[],[0,2],[0,2,[5,5,[4,6,3,10,0],0],[[5,1],[8,0],[5,7,5,0],2,4],[8,[],[10,2,3,4,8]]]]
+[[[8],[2,10,6],9,2,[5,[],5,[6,0,4,5,7],5]],[7,1]]
+
+[[[],[[9,7,1,3],[6,3,2,7,6]],[7,[6,9,5,0,9],3],5,[]],[],[[[3],[0,7,1,7]],[0,[10,6,2,10,4],[5,8,0,6,7],0,[]],6,9],[[[4,6,0,0,2],7,[9,7,7,7,0],8],6,[[],[0,3]],8],[[9,[1,10],2],4,[[0,4,10],[4,7,8]],[[2,0,0,9,8],[4,2,9],[5,10],1,[8,4]],3]]
+[[]]
+
+[[[[6]],4,8,[],6]]
+[[],[1,9,[[],9,[10,7,10,9,9],6,[0,10,1,4]]],[3,[8],2,9],[5,[4,7],[4,[8]],5,6],[[0],[10],[]]]
+
+[[[[5,1,10,5],[2,10,6],1,0,1],[[1],3,[],2,7],4,4,6]]
+[[3,[[7,3,0,6],7,[1,4,5]],[[4,7],[0,6,10,2,9],[],[4,2,1,9,7]],[9,10,[10],1,9],[]],[8,[],[3]],[[[3,2,6,1,0],4,[4,9],[3,1],3],[],[[0,4],[4,2]]]]
+
+[[7,5,1,10],[2],[]]
+[[],[[],7,[],9,[[0,9,4],[8,0]]]]
+
+[[3,9,0],[[[9,0,7,4],[1,6],9],10,[3],9,[0,[4,7,4]]]]
+[[5,3,[1,[8],0,9],1],[[[8],8,8,8,[6,7]],4,0,[4,0,9,[3,8,8,8],10]],[[[],7,[8,8,1,5]],8,3,4]]
+
+[[[9,[8],[10,3,10],7],4,3,6,[8]],[[]],[8,[10,10,[]],[4,[6,9,3,10,6],8,10,2]]]
+[[[[3],[5,0,9],[],2,[4,1]],[7,8,3],[10,[1,4]],[[0,7],[6,4],7,[10,0,0,1]]],[[[5,2],1,[10],10,[3,5,6]],[[],[0,6,2],[0,10,0,1,3]],[[],[1,7]],[1]],[],[],[9,[7],2,[[4,5,4,0],[8,1,1]]]]
+
+[[[],3],[3,[],4],[5,4,6,[]]]
+[[2,[8,2,[4]],5,[5,[9,1],[10,6,10]],9],[10,[5,8,[],[5],[]]],[[],1,[1,[7,6,5,0,4],[6],[5,5,10,5,2]],0]]
+
+[3,9,10,6,3]
+[3,9,10,6]
+
+[[1]]
+[[[[],[],[10,8,6]]]]
+
+[[[5],[10,[3,10,4,1],7],5,[3],[]]]
+[[],[[7],[[7,8,5],[6,10,4],9,[0,10,6]]],[[[8]],[5,[],[2],[6,5,0]],[[10,1],10,[],[9,1]],[5,4,[4],[],10],[5,[7],[10],[2,10]]]]
+
+[[2,9,[[9,7],[],[4,6,3],[0,6,10,2,10]],[[6,1,1,1,4]]],[10,4]]
+[[[],[6,8,1]],[[[7]],5,6,[0,2,2,6],[]],[3],[[4],4,5],[1,[[9,10],[1,5],4,[6,7]],0,6]]
+
+[[[7,9],5],[2,[5,9,7,[7,2,9]],[9,[8,7]]],[3,[[],10,4,[7],3]],[1,[[],5,0],5],[[],[[],5,0,4],2]]
+[[[[4,3,0,10,3],[6,1,10],4,8],[8,[],[8,0],10,[]]],[],[1,9,4],[10,8,[5,[9,8]],3]]
+
+[[6,8,[[1,4,10],0,7,[10,5,10]],[[10,8,9]]],[9,[9]],[9,[3,1,[],[1,1],8],7]]
+[[],[5,8],[7,[7],[[3,6,2],6,0,[2,7],[6]],[10,[2,10,8,6],[2],[],[8,10,10,3,4]],[[8,5,8,8,10],7,1,[10,10,8],[3,5,4,3,3]]],[[[],5,10,[1]],4]]
+
+[[4],[10,6]]
+[[0,10,4,[9,10]],[],[1,8],[9,7,[2,[5,4],[10],[7,1]],0]]
+
+[[[],[5,[4,10,2],4,[10,8,10]],[]],[],[4,[4,6]],[[],[2]]]
+[[1,5,[[4,2,5],[],[1,9,4,7],[10,6,2,3]],[[9,2,0]],0]]
+
+[[2,[8,7,[9,0,0,9],[0,8]]],[],[[3,6],[[1,8,0,5,6],5,2],0,6]]
+[[[3],[[1,6,1,10,0],[7],[9,2,0,5,9],[1,10,5,8],[8,6,2,6,5]],5,1],[]]
+
+[[[1],8,3,7,10]]
+[[[[1],[9,2,0,6],6,[5,4,7],[1,9,4]],7,0,[]],[2,4],[[9,9,[10,5,5],6],3,0,[[1,8],[],10,0],10]]
+
+[[10,4,[8,[3,6,1,1],7,10],[],[[2,6,6]]]]
+[[2,4],[[[2,0,8],[2,0,6,8,3]]],[[[5,1],9,[0,4,6,4,4],8,1],[1],9,[],5],[6,4,[[1,5,7],3],[[9]]],[]]
+
+[[],[[[],4,[9,2,9]],[[4,6,3,6]],[1,8,2],7],[[[3,1,5,5],[]],9,6],[0,4,1,6,0]]
+[[[[0,10,1],[2]],2]]
+
+[[[3],[[],4],1,8,2],[[2,[6,10,1,8,0]],0,[8,[],[10,9,7],[]],2],[[[4,4,2,6],[],7],3,8,10,3],[]]
+[[1,[6,3,[8,6,4,4],7],[7,8,[3]],1,2]]
+
+[[2,[0,8],9],[[[0,3,0,4,8],[2],[10,4,1,4]],[],[5],8,5],[0,[6],10,2,[1]]]
+[[9,10,2,[[0,7,5,0],2,[2,10,9,8]],[[6]]]]
+
+[[[4,3]]]
+[[[[8,9,3,3],[],[10,1,3,1,8],8,7]]]
+
+[[[9,[0,1,7,3,4],9,9],[],[8]],[[0,[9],[3,6,3,0],7],[9,4,0,[8,1,2,8],8],[2,8,[4,5]],[8,0,[9,9,7]]],[[0,[8,6,7,7,4],2],[7,[1,2,7],[7]],9,[[4,3,4,2],[1,7,3,1],9],[7,[5],[9,5,10]]],[]]
+[[8,[0,[3,0],4],6,[[8,6,5,3],[4,7],0]],[[3,[7,0,7,2,6]],[[0,0],[],[0,5,0,9,8]]],[]]
+
+[[4,7,[7],6,[8,[]]],[]]
+[[],[[9,[10]],[10]],[9,1,5,[0,7],[9,6,[6,0,4],[10]]],[[[4],[1,0],1],9,3],[[[9],1,[],[7,0],2],3,[[5,10,9],0,3,[7,9,10,5,0],6],[6,3,[],6,[3,3,6]],[[9],[2,1,7]]]]
+
+[[[[0,5,8,5],[5,5,6,3,6],[]]],[5,4,[],[],[[6,4,3,4]]],[[[9,3],[]]],[]]
+[[[7,[3,6,3,8,2]],6,7,9],[6]]
+
+[[5,[[1],[7,4,10,4],4,[8,3,0,2],[]],5,[9,[8,2,10,4,3],5,6,3],6],[[],[3,7,[5,1,2,1]]],[[[2,3,8,5],[0,4,4],10],2,[[1,4,2],5,8,2,3]]]
+[[[[8,6,8,2],[1,8,4,4],7,[5,4,10,7,4]],[[7,2,5]]],[3,10,[6,[1],[]]],[6,[],3],[[[7,0,0],9,4,3]],[0,[1,[],8],7,3]]
+
+[[[1,6,[7,1,3]],[[8],[8,8,9,1,1]],[[6,6,1,3],[2]]],[[],8,[],3],[],[6],[6]]
+[[[[],[],7],[[9,8,7],3],4]]
+
+[[],[9]]
+[[10,[[10,9,9,1,9]],[[5,5,7,0,4]],9,1],[],[[],5,[6,[3],[1],[1,8],[6,3,3,6]],2],[[[3,1,4,3,2]]],[3,[2,[10]]]]
+
+[[1],[[[0,0,10],[9,1,1,1,4],[7,0,5,3],[2,2],8],[[0,4,6,9,5],8],[6,[6,8],7,[],[8,0,6]],[],[[],7]]]
+[[],[[[6,1,9,8,5]],[[1,0,1,4],2,[],3]],[0,2,0,[[8,5,7,4,6],[5],4,[6,5,6,2,0]],10],[6,7]]
+
+[[[],3,6,[4,1,[5,0,5,3],[3,0],5],[1,1,2]],[3,2,[[1,3,7,9],[5]],6],[6,[],5,2],[3]]
+[[[[0,4,5,0],9,3,10,3],[[4,3,4,9,10],[6,1],[8,10,10,4,3],0]]]
+
+[[3,6,4,7],[5,8,0,[[0,6]]],[],[]]
+[[[[],[3,1,0,7,2],3,[10,3,0,2,8]],3],[0,9,0],[[[8,8,0,9,0],[6,0,5]],[[3,4,9],7]],[],[0]]
+
+[[],[[0,1,[4,1,4,2],[6,5,3],[]],1,[9,3,[10,4,5,0,4]],[[5,7],2],[[8,7]]],[8,4,9]]
+[[8,[7,[10],[2,8,10,9,3],[6,5],3]],[5,5,[[3],[]],6,[1,0,7,8]],[7,[6,5]],[],[10,5,4,[2,0,4,[6,10,4,4],[3,3]],8]]
+
+[[[6],[10,[0,2,5,10,9],2],[[],[0],9,[1,0,5,8]]],[3,[[4],[3],3,[1,4,2,0,0],[]],[[8,3,6,10,7],1],[2,2,5,[6],[0,7]]]]
+[[7],[1,3,[1,2,2],2,3],[5]]
+
+[[[[]],0,[[4,6,4]],0],[],[3,[],[1],[10]],[[1,[2,5]],[[7],[6,10,6,6,6],6],[[0,8,5],[4,0,9]]]]
+[[5,8,2,[0,3]],[6,[[6,4],[7,10,9,10,3],2],2,6],[1,[9,[6,4,1,2],8,[10,2,5,9,8],[]],[]],[],[[[8,2,3],9,[5,6,3,3],4,[4,10]],7]]
+
+[[8,[2,0],[10],2,3],[[3]],[[9,[10,9,9,5,7],2],[[],9,[6,8,5]],[10],8,[]]]
+[[7,10,[2,[0,6,4,0,5]],[4]],[[],[],4],[7,[5,10,2,[0,7,3,9,7]],[[7,2,1,3,5],[7,5,3,1,6],3]],[[[1],6]]]
+
+[[],[[7,[],[5,7]],1,7]]
+[[7,5,4,9],[[5],[[8,2],[1,5],3,4,1],[7,10,4,[],0]]]
+
+[[[8,6,[6,3]]],[9,[],[[5,6,0]],[2,[1,10,10,6]]]]
+[[0,0,[[1,1,10,1,3],2,[7,0,6],3]],[],[0,2],[[3],3,5]]
+
+[[[4,7,[10]],[1,4]],[[2,[4,1,6,0,4]],2,[[],[]],9],[6],[[],[9],7,5],[9,10,[7,[6,0,5,1,3]],2,[]]]
+[[4,[],[[5,4],[6,2,3,4],8,[4,3],7],[9,3,3,0],[[],1,6,2,9]]]
+
+[[5],[6,[]],[]]
+[[],[[1,5,[7,0],[2,7,6,1],10]],[]]
+
+[[5,10,3]]
+[[[7,1],[1,[7,5,9,7]],[0,[7,1,7,9,1],[9,2,9,9,1],5,[9]],[[]],[]],[0,[[9,0,3],[3],1,[1],1],9,[10,6,[],[10,9,1,10,10],[2,2,8]]],[[1,7,4],6]]
+
+[[],[]]
+[[[[6,3,9],[5,5,8,10,4],[7,4,9,1,3]],1,6],[[[8,2,4,5],[],[1,7,7]],0]]
+
+[[0,10,[[4,0],4]],[9,[],[4,9,[10,5,8]],7],[10,[]]]
+[[],[[],7]]
+
+[[[6,5],2,8,7,[[6,2,10,1],1,[2,5,10,7],1,[2,10,7,5]]],[6,9,8],[4,[],[[1,8]],1,[7,[1,0,6,8],[8]]],[[],6,1,[7,[],0,[6,7,8,10,5]]],[[],[],[7,9,[5,10,6,3],[2,10,3],8],7,[9,[0,10],[8,2,6,0,1],[10,1]]]]
+[[[9,[0,9,10,7,4]],6,[6,[8,5,9,6,8],[4,10,6],4,[]],[4,9,7,2,7]],[4],[[],[[4,2,5]],[4,[7],[9,5,8,7,7],[],[10,9,6]]],[10,[],10,[4]],[6,1,3,[[2,1],[1,9,7,3],5,[2,3,5,4,9],6],1]]
+
+[[6],[8,5,[4,[1,10]]]]
+[[1,7,5,9],[],[],[0,9,1],[0,[2,6,10,[10,7,3,5,3]]]]
+
+[[3],[1],[]]
+[[0],[8,[[6,7,6],3,7,[4,5,6,10,1],0]],[[[4],[6,0],0,[8],[8,1]],[[1],4,8]],[8]]
+
+[[[[2,3],5],[[4,2,4,10,3],[4,0,9,4,2],4],[2,[1,5,2,6,7],8,[0,5,1,4,8]],[[3,6,7,10],[6,7,4,7],[9,4,10]],[[9],[4,2]]],[]]
+[[[7,8,[8,2,10,2],[],[2]],3,9,0,1],[[[5]],0,7,[[7],2]],[[2,[],[8,5,4,1],9],5,6,[[1,2,8,0],4],[]],[2,[9,[],[10,10],8,[]],1]]
+
+[[],[],[[[5],[9],5,7],5,[]],[[3,[1,2,6,3],9,[3,2,7],0]],[[[5,9],5,[8,1,7]],[1,1,[7,7,8,10]]]]
+[[[[10,0],[0,7,2]],3,[0,3,2,[7,1,9]],[[10],0,[5]],[[2,8,0,5],[7,3],4,10]],[9,[[]],[[],[1,4,4],7,[0,1,6,7,2],[6,9,0,4,4]],[9,[9]],[6,[4,5,0,8],1,[8,3,1,10],[9]]],[7,[[]],[5,[1,9,6]]]]
+
+[[4]]
+[[5],[[2,[10,7,10,9,10],0]]]
+
+[[[],[[1,8,6,1,6],[3,2,1],2,[10,3,7,1,4],0],3,[3]],[9]]
+[[],[],[[8],[[],5,[1,8,7],9,1],[[7,1,2,4,3],7,[5,7,1,6,6],8,2],10],[4,[6,[8,8,6,7]],1,[[],[5,10,3,2,7]]],[1,[],[1,[0],7,[9,0]]]]
+
+[[8],[2,[[9,2,9,9,10],[3,5,3,4]]],[10,[[10,7,10,0]],10,[[2,6],[4,9,6],[3,4,5,0,2],[]],7]]
+[[4],[3],[],[10]]
+
+[[[[0],7,[1,1,10,2,0]],2,[[10,5,10]]],[[[6],[4,4,6]],[3,[]],9,[[8,3,3],[6],[9,5,7,7],8],10],[]]
+[[6],[[[3,10]],[]],[8,10,[],9]]
+
+[[5,5,[],9]]
+[[[[5,6,6,3]],2,[[4],0,7,2]],[[],[[10,5],[],[5],[8,1,0,3,2],3],[[7,3,0],5,0,4,[9,1]]]]
+
+[[],[[2],7,4],[2,9,10],[[[],[7,4,4,7,3]],[]]]
+[[9],[]]
+
+[[[10,5,4,1,8],7,[5],[8]]]
+[[0,10,[]],[],[0,6,[7,[4],[],[9]]],[4]]
+
+[[[8],[10],9,9]]
+[[3,[[1,0,5,1,5]]]]
+
+[[[4,5,10],[7,[10,3,1],[2,6],10],[[6,0,8,9,6],4,[]],[]],[9,[],10]]
+[[],[7],[10,10,[6]],[[[2,4],[6,2,2],0],6],[[[2,3,0,0,2],[6,5,7,2],2,4],6,6]]
+
+[[1],[[]],[[[9,1,9,5],[6],[9,3,5,2,6],9,[]],6,[],[[2],9,[8,3,1,3,1],[3,10,6]],[[0,9,1,8,2]]]]
+[[[8],[[7],[7],5],5,5],[4,[[5,9,10],[]],[[4,7,5,1]],[[10,1,7]],4],[5,[[4,8,4],7,0],[2],[],[8,0,[5,8],[8,5,7,2,8],4]]]
+
+[[[0,[3,3,10],[],[0,9],5]],[[4,[],[7,2,5],[0,7],[0,10]]],[],[[[1,8]],[[9,7]],5,[[9,1,0,1],5,5,5,[10]],[[9,4,6,6],4,4,[2,6,9,4,7]]],[4]]
+[[[[10,8,4,0],[9,10,1]],[],[],[[9,8,4,6],2,9],4],[[2,[6,7,8],10,[],[10,4,3,9]],[5,[9]],5,[6,[10],[7,3,6]],[]],[],[[[5,7],[9,7,7,6,9],[9,10,5],8],[[],3,[0,5,0]],3,6,6],[9,[7]]]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/13/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,23 @@
+[1,1,3,1,1]
+[1,1,5,1,1]
+
+[[1],[2,3,4]]
+[[1],4]
+
+[9]
+[[8,7,6]]
+
+[[4,4],4,4]
+[[4,4],4,4,4]
+
+[7,7,7,7]
+[7,7,7]
+
+[]
+[3]
+
+[[[]]]
+[[]]
+
+[1,[2,[3,[4,[5,6,7]]]],8,9]
+[1,[2,[3,[4,[5,6,0]]]],8,9]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/14/14.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,186 @@
+
+mutable struct PS
+    s::String
+    pos::Int
+end
+
+function initialize(s::String)::PS
+    PS(s, 1)
+end
+
+function parse_coord(ps::PS)::Tuple{Int,Int}
+    e = findfirst((==)(','), ps.s[ps.pos:end])
+    x = parse(Int, ps.s[ps.pos:ps.pos+e-2]);
+    ps.pos = ps.pos + e;
+    e = something(findfirst((==)(' '), ps.s[ps.pos:end]), length(ps.s)-ps.pos+2);
+    y = parse(Int, ps.s[ps.pos:ps.pos+e-2]);
+    ps.pos = ps.pos + e - 1;
+    (x, y)
+end
+
+function parse_sep(ps::PS)::Bool
+    if ps.pos >= length(ps.s)
+        false
+    else
+        @assert ps.s[ps.pos:ps.pos+3] == " -> "
+        ps.pos += 4;
+        true
+    end
+end
+
+function parse_coords(ps::PS)::Vector{Tuple{Int,Int}}
+    poss = Vector{Tuple{Int,Int}}();
+    while true
+        push!(poss, parse_coord(ps));
+        if !parse_sep(ps)
+            break
+        end
+    end
+    poss
+end
+
+function parse_all_coords(fh::IOStream)::Vector{Vector{Tuple{Int,Int}}}
+    vs = Vector{Vector{Tuple{Int,Int}}}();
+    for l in eachline(fh)
+        push!(vs, parse_coords(initialize(l)));
+    end
+    vs
+end
+
+const EMPTY = 0;
+const ROCK = 1;
+const SAND = 2;
+
+function run_matrix_2(v::Vector{Vector{Tuple{Int,Int}}})
+    SAND_POINT = (500,0)
+    minx = min(SAND_POINT[1], minimum(minimum(t[1] for t in vv) for vv in v));
+    maxx = max(SAND_POINT[1], maximum(maximum(t[1] for t in vv) for vv in v));
+    miny = min(SAND_POINT[2], minimum(minimum(t[2] for t in vv) for vv in v));
+    maxy = max(SAND_POINT[2], maximum(maximum(t[2] for t in vv) for vv in v));
+
+    maxx += div((maxy-miny)+1, 1);
+    minx -= div((maxy-miny)+1, 1);
+
+    m = zeros(Int8, maxx-minx+1, maxy-miny+1+2);
+    m[begin:end, end] .= ROCK;
+
+    for line in v
+        last = line[1];
+        for p in @view line[2:end]
+            a, b = CartesianIndex(last .- (minx-1, miny-1)), CartesianIndex(p .- (minx-1, miny-1));
+            @assert abs(last[1]-p[1]) == 0 || abs(last[2]-p[2]) == 0
+            if a > b
+                a, b = b, a;
+            end
+            m[a:b] .= ROCK;
+            last = p;
+        end
+    end
+
+
+    show_cave(m);
+
+    # part 2
+    println(" === PART 2 === ");
+    pos0 = SAND_POINT .- (minx-1, miny-1);
+    down, left, right = (0,1), (-1,1), (1,1);
+    X, Y = size(m);
+    isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
+
+    count = 0;
+    pos = pos0;
+    while true
+        if m[CartesianIndex(pos .+ down)] == EMPTY
+            pos = pos .+ down;
+            continue;
+        elseif m[CartesianIndex(pos .+ left)] == EMPTY
+            pos = pos .+ left;
+            continue
+        elseif m[CartesianIndex(pos .+ right)] == EMPTY
+            pos = pos .+ right;
+            continue;
+        else
+            count += 1;
+            if pos == pos0
+                break;
+            end
+            m[CartesianIndex(pos)] = SAND;
+            println(" ==== $count ==== ");
+            pos = pos0;
+            continue;
+        end
+    end
+    show_cave(m);
+    @show count;
+end
+
+function run_matrix(v::Vector{Vector{Tuple{Int,Int}}})
+    # Not very efficient...
+    SAND_POINT = (500,0)
+    minx = min(SAND_POINT[1], minimum(minimum(t[1] for t in vv) for vv in v));
+    maxx = max(SAND_POINT[1], maximum(maximum(t[1] for t in vv) for vv in v));
+    miny = min(SAND_POINT[2], minimum(minimum(t[2] for t in vv) for vv in v));
+    maxy = max(SAND_POINT[2], maximum(maximum(t[2] for t in vv) for vv in v));
+
+    m = zeros(Int8, maxx-minx+1, maxy-miny+1);
+
+    for line in v
+        last = line[1];
+        for p in @view line[2:end]
+            a, b = CartesianIndex(last .- (minx-1, miny-1)), CartesianIndex(p .- (minx-1, miny-1));
+            @assert abs(last[1]-p[1]) == 0 || abs(last[2]-p[2]) == 0
+            if a > b
+                a, b = b, a;
+            end
+            m[a:b] .= ROCK;
+            last = p;
+        end
+    end
+
+    M0 = copy(m);
+    down, left, right = (0,1), (-1,1), (1,1);
+    X, Y = size(m);
+    isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
+
+    count = 0;
+    pos0 = SAND_POINT .- (minx-1, miny-1);
+    pos = pos0;
+    while true
+        if !isvalid(pos .+ down)
+            break;
+        elseif m[CartesianIndex(pos .+ down)] == EMPTY
+            pos = pos .+ down;
+            continue;
+        elseif !isvalid(pos .+ left)
+            break;
+        elseif m[CartesianIndex(pos .+ left)] == EMPTY
+            pos = pos .+ left;
+            continue
+        elseif !isvalid(pos .+ right)
+            break;
+        elseif m[CartesianIndex(pos .+ right)] == EMPTY
+            pos = pos .+ right;
+            continue;
+        else
+            count += 1;
+            m[CartesianIndex(pos)] = SAND;
+            println(" ==== $count ==== ");
+            pos = pos0;
+            continue;
+        end
+    end
+    show_cave(m);
+    @show count;
+end
+
+function show_cave(m::Matrix{Int8})
+    for r in eachrow(m')
+        println(r);
+    end
+end
+
+open("14/test_input.txt"; read=true) do fh
+    ac = (parse_all_coords(fh));
+    run_matrix(ac);
+    run_matrix_2(ac);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/14/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,151 @@
+506,104 -> 511,104
+504,96 -> 509,96
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+499,35 -> 504,35
+511,23 -> 516,23
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+503,38 -> 508,38
+520,104 -> 525,104
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+499,28 -> 499,29 -> 513,29 -> 513,28
+504,23 -> 509,23
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+499,28 -> 499,29 -> 513,29 -> 513,28
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+508,98 -> 513,98
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+507,20 -> 512,20
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+510,127 -> 514,127
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+492,104 -> 497,104
+492,35 -> 497,35
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+528,127 -> 532,127
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+516,127 -> 520,127
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+495,32 -> 500,32
+493,14 -> 505,14 -> 505,13
+522,127 -> 526,127
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+493,14 -> 505,14 -> 505,13
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+525,125 -> 529,125
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+513,104 -> 518,104
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+519,121 -> 523,121
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+495,102 -> 500,102
+500,20 -> 505,20
+490,42 -> 504,42 -> 504,41
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+509,102 -> 514,102
+513,125 -> 517,125
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+490,42 -> 504,42 -> 504,41
+498,100 -> 503,100
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+489,38 -> 494,38
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+496,38 -> 501,38
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+519,125 -> 523,125
+501,154 -> 501,155 -> 507,155
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+499,104 -> 504,104
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+501,154 -> 501,155 -> 507,155
+503,17 -> 508,17
+516,123 -> 520,123
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+505,100 -> 510,100
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+500,93 -> 500,83 -> 500,93 -> 502,93 -> 502,90 -> 502,93 -> 504,93 -> 504,85 -> 504,93 -> 506,93 -> 506,83 -> 506,93
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,140 -> 498,142 -> 493,142 -> 493,150 -> 504,150 -> 504,142 -> 503,142 -> 503,140
+506,130 -> 506,132 -> 502,132 -> 502,137 -> 516,137 -> 516,132 -> 511,132 -> 511,130
+516,102 -> 521,102
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+522,123 -> 526,123
+485,45 -> 485,47 -> 483,47 -> 483,54 -> 492,54 -> 492,47 -> 489,47 -> 489,45
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+499,28 -> 499,29 -> 513,29 -> 513,28
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+512,100 -> 517,100
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+497,23 -> 502,23
+524,107 -> 524,111 -> 522,111 -> 522,118 -> 534,118 -> 534,111 -> 528,111 -> 528,107
+489,67 -> 489,58 -> 489,67 -> 491,67 -> 491,61 -> 491,67 -> 493,67 -> 493,59 -> 493,67 -> 495,67 -> 495,64 -> 495,67
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+501,98 -> 506,98
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+498,168 -> 498,158 -> 498,168 -> 500,168 -> 500,162 -> 500,168 -> 502,168 -> 502,163 -> 502,168 -> 504,168 -> 504,160 -> 504,168 -> 506,168 -> 506,159 -> 506,168 -> 508,168 -> 508,163 -> 508,168 -> 510,168 -> 510,163 -> 510,168 -> 512,168 -> 512,167 -> 512,168 -> 514,168 -> 514,161 -> 514,168 -> 516,168 -> 516,167 -> 516,168
+502,102 -> 507,102
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
+487,80 -> 487,75 -> 487,80 -> 489,80 -> 489,72 -> 489,80 -> 491,80 -> 491,76 -> 491,80 -> 493,80 -> 493,71 -> 493,80 -> 495,80 -> 495,76 -> 495,80 -> 497,80 -> 497,75 -> 497,80 -> 499,80 -> 499,70 -> 499,80 -> 501,80 -> 501,78 -> 501,80 -> 503,80 -> 503,70 -> 503,80
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/14/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,2 @@
+498,4 -> 498,6 -> 496,6
+503,4 -> 502,4 -> 502,9 -> 494,9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/15/15.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,97 @@
+
+using ParserCombinator
+
+const Line = E"Sensor at x=" + PInt64() + E", y=" + PInt64() + E": closest beacon is at x=" + PInt64() + E", y=" + PInt64() + Eos();
+
+struct Point
+    x::Int
+    y::Int
+end
+
+function distance(p::Point, q::Point)::Int
+    abs(p.x-q.x) + abs(p.y-q.y)
+end
+
+struct Beacon
+    sensor::Point
+    beacon::Point
+    dist::Int
+end
+
+function parse_line(s::String)::Beacon
+    es = parse_one(s, Line);
+    p, q = Point(es[1]::Int, es[2]::Int), Point(es[3]::Int, es[4]::Int)
+    Beacon(p, q, distance(p, q))
+end
+
+function parse_lines(f::String)::Vector{Beacon}
+    v = Vector{Beacon}();
+    open(f; read=true) do fh
+        for l in eachline(fh)
+            push!(v, parse_line(l));
+        end
+    end
+    v
+end
+
+function point_is_within_closest(p::Point, b::Beacon)::Bool
+    distance(p, b.sensor) <= b.dist && p != b.beacon
+end
+
+function point_is_beacon(p::Point, bs::Vector{Beacon})::Bool
+    any(b -> b.beacon == p, bs)
+end
+
+function point_is_covered(p::Point, bs::Vector{Beacon}; ignorebeacon=false)::Bool
+    any(b -> point_is_within_closest(p, b), bs)
+end
+
+function n_covered_points(bs::Vector{Beacon}, y::Int)::Int
+    minx = minimum(min(b.sensor.x, b.beacon.x)-b.dist for b in bs);
+    maxx = maximum(max(b.sensor.x, b.beacon.x)+b.dist for b in bs);
+
+    count = sum(point_is_covered(Point(x, y), bs) for x = minx:maxx);
+    count
+end
+
+function find_distress_beacon(bs::Vector{Beacon}, minc=0, maxc=20)::Set{Point}
+    # Check borders of sensor's coverage area - as there is only one point to check,
+    # it must be directly outside a sensor's coverage area.
+    v = Set{Point}();
+    isvalid(p) = p.x >= minc && p.x <= maxc && p.y >= minc && p.y <= maxc;
+    for b in bs
+        @show b
+        for x = b.sensor.x-b.dist:b.sensor.x+b.dist
+            for dir = [-1, 1]
+                y = dir*b.sensor.y + abs(b.dist - abs(b.sensor.x-x));
+                p = Point(x+sign(x-b.sensor.x), y);
+                if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
+                    push!(v, p);
+                    continue;
+                end
+                if x == b.sensor.x
+                    p = Point(x, y+dir);
+                    if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
+                        push!(v, p);
+                        continue;
+                    end
+                end
+            end
+        end
+    end
+    v
+end
+
+function tuning_frequency(p::Point)::Int
+    p.x*4000000+p.y
+end
+
+bs = parse_lines("15/input.txt");
+println(n_covered_points(bs, 2000000));
+db = find_distress_beacon(bs, 0, 4000000);
+@show (db, map(tuning_frequency, collect(db)))
+
+bs = parse_lines("15/test_input.txt");
+println(n_covered_points(bs, 10));
+db = find_distress_beacon(bs);
+@show (db, map(tuning_frequency, collect(db)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/15/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,27 @@
+Sensor at x=3391837, y=2528277: closest beacon is at x=3448416, y=2478759
+Sensor at x=399473, y=1167503: closest beacon is at x=1188862, y=2000000
+Sensor at x=3769110, y=2896086: closest beacon is at x=4076658, y=2478123
+Sensor at x=900438, y=3835648: closest beacon is at x=-435606, y=3506717
+Sensor at x=2913762, y=3937542: closest beacon is at x=2964244, y=3612685
+Sensor at x=3646459, y=3446878: closest beacon is at x=3264675, y=3635510
+Sensor at x=1182092, y=2135147: closest beacon is at x=1188862, y=2000000
+Sensor at x=3213897, y=2710772: closest beacon is at x=3448416, y=2478759
+Sensor at x=3242113, y=3984214: closest beacon is at x=3264675, y=3635510
+Sensor at x=2809237, y=3782833: closest beacon is at x=2872059, y=3592616
+Sensor at x=2962421, y=37354: closest beacon is at x=3358601, y=-1111474
+Sensor at x=3456740, y=2458922: closest beacon is at x=3448416, y=2478759
+Sensor at x=1799203, y=3569221: closest beacon is at x=2872059, y=3592616
+Sensor at x=3907873, y=3898376: closest beacon is at x=3264675, y=3635510
+Sensor at x=3481951, y=2453964: closest beacon is at x=3448416, y=2478759
+Sensor at x=1120077, y=2963237: closest beacon is at x=1188862, y=2000000
+Sensor at x=2901181, y=3029961: closest beacon is at x=2872059, y=3592616
+Sensor at x=3111105, y=3361570: closest beacon is at x=2964244, y=3612685
+Sensor at x=2533601, y=3956413: closest beacon is at x=2872059, y=3592616
+Sensor at x=108898, y=2275290: closest beacon is at x=1188862, y=2000000
+Sensor at x=3501591, y=2414995: closest beacon is at x=3448416, y=2478759
+Sensor at x=3035657, y=3700769: closest beacon is at x=2964244, y=3612685
+Sensor at x=1286795, y=298997: closest beacon is at x=308571, y=-434280
+Sensor at x=200812, y=3470019: closest beacon is at x=-435606, y=3506717
+Sensor at x=2550124, y=1556776: closest beacon is at x=1188862, y=2000000
+Sensor at x=3955070, y=601908: closest beacon is at x=4076658, y=2478123
+Sensor at x=3565419, y=2355172: closest beacon is at x=3448416, y=2478759
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/15/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,14 @@
+Sensor at x=2, y=18: closest beacon is at x=-2, y=15
+Sensor at x=9, y=16: closest beacon is at x=10, y=16
+Sensor at x=13, y=2: closest beacon is at x=15, y=3
+Sensor at x=12, y=14: closest beacon is at x=10, y=16
+Sensor at x=10, y=20: closest beacon is at x=10, y=16
+Sensor at x=14, y=17: closest beacon is at x=10, y=16
+Sensor at x=8, y=7: closest beacon is at x=2, y=10
+Sensor at x=2, y=0: closest beacon is at x=2, y=10
+Sensor at x=0, y=11: closest beacon is at x=2, y=10
+Sensor at x=20, y=14: closest beacon is at x=25, y=17
+Sensor at x=17, y=20: closest beacon is at x=21, y=22
+Sensor at x=16, y=7: closest beacon is at x=15, y=3
+Sensor at x=14, y=3: closest beacon is at x=15, y=3
+Sensor at x=20, y=1: closest beacon is at x=15, y=3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/16/16.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,147 @@
+
+using ParserCombinator
+
+const PValveList = (E"s " + Repeat(p"[A-Z]{2}" + Repeat(E", ", 0, 1)) + Eos()) | (E" " + p"[A-Z]{2}" + Eos());
+const PValveSpec = E"Valve " + p"[A-Z]{2}" + E" has flow rate=" + PInt64() + P"; tunnels? leads? to valve" + PValveList;
+
+struct ValveSpec
+    name::String
+    flowrate::Int
+    tunnels::Vector{String}
+end
+
+function parse_valve_line(s::String)::ValveSpec
+    vs = parse_one(s, PValveSpec);
+    ValveSpec(String(vs[1]), vs[2]::Int, [String(s) for s in vs[3:end]])
+end
+
+struct Peer
+    valve::ValveSpec
+    dist::Int
+end
+
+struct Node
+    valve::ValveSpec
+    routes::Dict{String, Peer}
+end
+
+function build_graph(lines::IOStream)::Dict{String,Node}
+    l = [Node(parse_valve_line(s), Dict()) for s in eachline(lines)];
+    Dict(n.valve.name => n for n in l)
+end
+
+function update_connections(neigh::Node, dist::Int, mine::Dict{String, Peer})::Int
+    count = 0;
+    for (s, p) = mine
+        if s == neigh.valve.name
+            continue
+        end
+        if !(s in keys(neigh.routes)) || neigh.routes[s].dist > p.dist+dist
+            pp = Peer(p.valve, p.dist+dist);
+            neigh.routes[s] = pp;
+            count += 1;
+        end
+    end
+    count
+end
+
+function populate_graph(g::Dict{String,Node})
+    for (id, valve) in g
+        for neigh in valve.valve.tunnels
+            # Insert neighbors with distance = 1.
+            valve.routes[neigh] = Peer(g[neigh].valve, 1);
+        end
+    end
+
+    count = 1;
+    # While information propagates through the graph, keep updating.
+    while count > 0
+        count = 0;
+        for (id, node) = g
+            for (id2, node2) = node.routes
+                if id == id2
+                    continue
+                end
+                count += update_connections(g[id2], node2.dist, node.routes);
+            end
+        end
+        @show count
+    end
+end
+
+# Sort key
+"""Return the total flow expected for node `node`, assuming it is opened at `time`, and the best path from it
+is followed (this works recursively).
+"""
+function expected_total_flow(time::Int, node::Node, g::Dict{String,Node}, opened::Vector{String}=[]; level=-1)::Tuple{String,Int,Int}
+    if level == 0
+        return ("", -1, -1);
+    end
+    if in(node.valve.name, opened)
+        return ("", -1, -1);
+    end
+    self = (30 - time - 1) * node.valve.flowrate;
+    push!(opened, node.valve.name);
+    opts = [(vn, p.dist, expected_total_flow(time+1+p.dist, g[vn], g, opened; level=level-1)[3]) for (vn, p) in node.routes if p.valve.flowrate > 0];
+    if level == 7
+        @show opts
+    end
+    pop!(opened);
+    _, bestix = findmax(t -> t[3], opts);
+    (opts[bestix][1], opts[bestix][2], opts[bestix][3]+self)
+end
+
+"""
+Starting at AA, check which node is best by exploring all possible paths up to a certain depth,
+visiting nodes by preference.
+"""
+function trace_best_path(g::Dict{String,Node}; init="AA")
+    opened = String[];
+    active_pressure_relief = 0;
+    pressure_relieved = 0;
+    time = 0;
+    last = init;
+    while length(g) > length(opened)
+        @show (time, last, opened)
+        next, dist, score = expected_total_flow(time, g[last], g, opened; level=7);
+        @show (next, dist, score);
+
+        if in(next, opened)
+            break;
+        end
+
+        pressure_relieved += (dist+1) * active_pressure_relief;
+        println("Relieving $(dist+1) x $active_pressure_relief...");
+        active_pressure_relief += g[next].valve.flowrate;
+
+        push!(opened, last);
+        last = next;
+        time += dist + 1;
+    end
+    pressure_relieved += (30 - time) * active_pressure_relief;
+    println("Relieving $(30-time) x $active_pressure_relief...");
+    println("Total relief: $pressure_relieved");
+end
+
+function print_graph(g::Dict{String,Node})
+    for (id, n) = g
+        println("=== $id === ");
+        println(" flowrate: $(n.valve.flowrate)");
+        println(" neighbors:");
+        for (id2, neigh) = n.routes
+            println("   $id2 => $(neigh.dist)");
+        end
+    end
+end
+
+open("16/test_input.txt"; read=true) do fh
+    g = build_graph(fh);
+    populate_graph(g);
+    @time trace_best_path(g);
+end
+
+open("16/input.txt"; read=true) do fh
+    g = build_graph(fh);
+    @time populate_graph(g);
+    @time trace_best_path(g);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/16/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,52 @@
+Valve JZ has flow rate=0; tunnels lead to valves IR, LY
+Valve KD has flow rate=0; tunnels lead to valves NJ, ZS
+Valve VW has flow rate=0; tunnels lead to valves IT, VH
+Valve HS has flow rate=0; tunnels lead to valves OC, PN
+Valve EU has flow rate=19; tunnel leads to valve GQ
+Valve XF has flow rate=0; tunnels lead to valves WL, QD
+Valve DD has flow rate=8; tunnels lead to valves GQ, YY, JV, SK
+Valve TA has flow rate=0; tunnels lead to valves NJ, VJ
+Valve IR has flow rate=9; tunnels lead to valves JZ, WI, VJ, GC, WG
+Valve SS has flow rate=17; tunnels lead to valves SI, IZ, RK, WI
+Valve SG has flow rate=0; tunnels lead to valves NV, NJ
+Valve IT has flow rate=0; tunnels lead to valves LL, VW
+Valve CP has flow rate=24; tunnels lead to valves HN, ZK, EJ
+Valve SK has flow rate=0; tunnels lead to valves LL, DD
+Valve IS has flow rate=0; tunnels lead to valves AA, LL
+Valve HN has flow rate=0; tunnels lead to valves FF, CP
+Valve VH has flow rate=10; tunnels lead to valves QO, VW, RV, PN
+Valve JV has flow rate=0; tunnels lead to valves DD, RK
+Valve ZS has flow rate=0; tunnels lead to valves KD, LL
+Valve UC has flow rate=25; tunnels lead to valves JD, IV
+Valve WI has flow rate=0; tunnels lead to valves SS, IR
+Valve UR has flow rate=0; tunnels lead to valves QD, LY
+Valve GC has flow rate=0; tunnels lead to valves AA, IR
+Valve YY has flow rate=0; tunnels lead to valves DD, AA
+Valve IV has flow rate=0; tunnels lead to valves ZK, UC
+Valve BM has flow rate=0; tunnels lead to valves SA, WL
+Valve JD has flow rate=0; tunnels lead to valves IZ, UC
+Valve WL has flow rate=12; tunnels lead to valves EF, BM, EJ, XF
+Valve AA has flow rate=0; tunnels lead to valves NV, YY, GC, IS, QO
+Valve WG has flow rate=0; tunnels lead to valves LL, IR
+Valve GQ has flow rate=0; tunnels lead to valves EU, DD
+Valve SI has flow rate=0; tunnels lead to valves SS, NJ
+Valve KH has flow rate=13; tunnels lead to valves SA, ON
+Valve PC has flow rate=22; tunnel leads to valve ON
+Valve QD has flow rate=14; tunnels lead to valves XF, UR
+Valve IZ has flow rate=0; tunnels lead to valves SS, JD
+Valve QO has flow rate=0; tunnels lead to valves AA, VH
+Valve SA has flow rate=0; tunnels lead to valves BM, KH
+Valve NV has flow rate=0; tunnels lead to valves AA, SG
+Valve ZK has flow rate=0; tunnels lead to valves CP, IV
+Valve ON has flow rate=0; tunnels lead to valves PC, KH
+Valve PN has flow rate=0; tunnels lead to valves HS, VH
+Valve RV has flow rate=0; tunnels lead to valves NJ, VH
+Valve RK has flow rate=0; tunnels lead to valves SS, JV
+Valve OC has flow rate=18; tunnel leads to valve HS
+Valve EF has flow rate=0; tunnels lead to valves LY, WL
+Valve VJ has flow rate=0; tunnels lead to valves TA, IR
+Valve LL has flow rate=5; tunnels lead to valves ZS, IT, SK, IS, WG
+Valve FF has flow rate=0; tunnels lead to valves HN, LY
+Valve LY has flow rate=21; tunnels lead to valves EF, FF, UR, JZ
+Valve EJ has flow rate=0; tunnels lead to valves WL, CP
+Valve NJ has flow rate=6; tunnels lead to valves RV, KD, SG, SI, TA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/16/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,10 @@
+Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
+Valve BB has flow rate=13; tunnels lead to valves CC, AA
+Valve CC has flow rate=2; tunnels lead to valves DD, BB
+Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
+Valve EE has flow rate=3; tunnels lead to valves FF, DD
+Valve FF has flow rate=0; tunnels lead to valves EE, GG
+Valve GG has flow rate=0; tunnels lead to valves FF, HH
+Valve HH has flow rate=22; tunnel leads to valve GG
+Valve II has flow rate=0; tunnels lead to valves AA, JJ
+Valve JJ has flow rate=21; tunnel leads to valve II
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/17/17.jl	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,135 @@
+using StaticArrays;
+
+const test_input = "test_input.txt";
+
+const rocks = Vector{Matrix{Int}}([[1 1 1 1], [0 1 0; 1 1 1; 0 1 0], [0 0 1; 0 0 1; 1 1 1], [1;1;1;1][:,:], [1 1; 1 1]]);
+
+const ChamberWidth = 7;
+const InitialVOff = 3;
+const Line = MVector{ChamberWidth, Bool};
+
+const Chamber = Vector{Line};
+
+function show_chamber(c::Chamber)
+	for l in reverse(c)
+		println(String(map(x -> x ? '@' : '.', l)));
+	end
+end
+
+@enum Direction begin
+	L
+	R
+end
+
+function parsechar(c::Char)::Direction
+	if c == '<'
+		L
+	elseif c == '>'
+		R
+	end
+end	
+
+function parse_input(f::String)::Vector{Direction}
+	open(f; read=true) do fh
+		l = readline(fh);
+		map(parsechar, collect(l))
+	end
+end
+
+function would_overlap(r::Matrix{Int}, left::Int, up::Int, c::Chamber)::Bool
+    if left+size(r, 2)-1 > ChamberWidth || left < 1
+        println("lateral stop");
+        return true;
+    end
+    if up > length(c)
+        return false;
+    end
+
+    lines_overlap = length(c) - up + 1;
+    zs = zeros(Bool, ChamberWidth);
+    for l = 1:lines_overlap
+        cl = c[end-l+1];
+        rl = r[end-l+1,:];
+        rlc = Line(zs);
+        rlc[left:left+size(r, 2)-1] .= rl;
+        if any((>)(1), Int.(cl) .+ Int.(rlc))
+            @show (cl, rlc)
+            return true;
+        end
+    end
+    false
+end
+
+function move_rock(r::Matrix{Int}, d::Direction, left::Int, up::Int, c::Chamber)::Tuple{Int,Int,Bool}
+    newl, newu = left, up;
+
+    println("Jet pushes $d");
+    if would_overlap(r, left + (d == L ? -1 : +1), newu, c)
+        # Lateral move didn't work, just ignore
+        #
+    else
+        println("  ok");
+        newl = left + (d == L ? -1 : 1);
+    end
+
+    if would_overlap(r, newl, up-1, c)
+        return (newl, up, true);
+    else
+        println("Rock falls 1");
+        newu = up-1;
+    end
+
+    (newl, newu, false)
+end
+
+function merge_rock(c::Chamber, r::Matrix{Int}, left::Int, up::Int)
+	z = zeros(Bool, ChamberWidth);
+	for i = 1:(up-length(c)+size(r, 1)-1)
+		push!(c, Line(z));
+	end
+
+        for i = 0:size(r, 1)-1
+            cl = c[up+i];
+            rl = r[end-i, :];
+            rlc = Line(z);
+            rlc[left:left+size(r, 2)-1] .= rl;
+            cl .|= rlc;
+        end
+end
+
+function handle_fall(jets::Vector{Direction}; maxi=2022)::Int
+	c = Chamber();
+	rs = Iterators.cycle(rocks);
+	jets = Iterators.cycle(jets);
+	jetst = 0;
+	i = 0;
+	for rock = rs
+		i += 1;
+                @show i
+                show_chamber(c);
+		# Coordinates relative to floor.
+		# Left is position of left-most edge, up position of bottom part.
+                left, up = 3, length(c)+4+(i == 1 ? 1 : 0);
+		settled = false;
+		for j = 1:3
+			jet, jetst = iterate(jets, jetst);
+			left, up, settled = move_rock(rock, jet, left, up, c);
+			@assert !settled;
+		end
+		while !settled && up > 1
+			jet, jetst = iterate(jets, jetst);
+			left, up, settled = move_rock(rock, jet, left, up, c);
+		end
+		# Update chamber image
+		merge_rock(c, rock, left, up);
+		show_chamber(c);
+		if i == maxi
+			break
+		end
+	end
+        println("---");
+	show_chamber(c);
+	length(c)
+end
+
+handle_fall(parse_input("17/test_input.txt"); maxi=10);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/17/input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,1 @@
+>>>><>>>><>>><<<<>>><<<>>>><>>>><<<<>>><<>>>><<<><><<<>>>><<>><>>>><<><<>><<>><><<>><>>><>>>><>>><>>>><<><><>>><<<><<<<>>><<<><<>>>><<>>><>>><<<>><<>>><>><<>><<<<><<<<>>><<>>><<<<><>>>><<>>>><>>><<>>><<>>><><<<<>><<><<<<>>><>>>><<<><<<<><<<>>><>>>><<>>>><>>>><><<<<>><<>>><<<>><<<<>><<<><<<<>><>>><<>>><<<<>>>><<<<>>>><<<<>><<>>><<<><<<>><>>>><<>><<<>>><<<<>>>><<<<>>><<<<>>><<<<><<>><>><<<<>>><>>>><<<<>><<<>><<<><<<<><<>>>><<<<>>>><<<>>>><<<<>><<>>><>><<<<>>><>>>><<<>>>><<<>><<<>><><<<><<>>><<<<>><<<<><<>>>><>>>><<<><><<>>>><<<>><<<>>>><<<>>><<<<><<><<>>><<<<><<<>><<<<>>>><<<<><<<<>><<>>>><<>>>><<<<>><<>><<<<>>>><<<><>><<<>>>><<<<><<<>><<<<>><<<>><<<<>>>><<<>><>>><<<<>>><>>>><<<>>>><>><<<>>><>>>><<<>>><>>><><<>>>><>>><<<<><<<<>><<>>>><<<<>>><<<>>>><>><<<><<<<>>>><<<<>>>><<<>>>><<>>><>>>><<<><<><<<<>>><<<<>>>><>>><<<<>><<><><<<><<>><<<<>>><<><<>><<><<<>>><<<>><<<<>><<<<><<<>>><>><>><<<<>>><<><<<<>>><>>>><>>>><<<<>>><<>><>>><<><>>><<<<>>><<<<><<<>>><<>><>>><<<<><<>>><<>><<<<><<>><<>>>><>>>><<>><<>>>><<<><><<<<><<<<>>><<<>>><<<>>><><<<<>><<<>>>><<<><<><<<<>>><<>>>><<><<>>>><<<>>>><<<><<<<>><<<<>>>><<<>>>><<<<><>><<<>>>><>><<<>>><<<<><<<<>>><<<<>><<>>><<<<><<<>>><<>><<<>>><<>><<>>>><<<>><>>><<<<>>><<<>>>><<<<>>>><<>>>><<<<><>>><<<>>><<<><<>><>>>><<><<><<<<><<>><<>><>>>><<<>><<<<>>>><<<>>>><<<><><<><<<<><<><<<<>>>><<<<><>>>><<>>><<<<>>>><<>><<>><<>>>><<<<>><<<>><><<<<>>><>>>><<<>><<<<><<<<><<<><>><<<>><<<<><<>>>><<<<>>><>>><<<<>>><<>>>><<<<>>>><<<<>><<<<>>><<<>>>><<<<>>><<<>><<<>>><<>>>><<<<><<>><<<><>><<<<>>><<<<><<<>><<<>>>><<<<>>><<<<><>><>>>><<<<>>><<<<>><><<>><><<<><<<<><<>><>><<>>><<<>><<>>>><<>>><<<<>><<<<>>>><<<>><<>><><<<<><<<<><<<>>>><<>><<>>><<<>>><<><<><<<>><<><<<<>><>>><<<><<>>>><<<<>><<>><<<>>>><<<<>>>><<><<>>><<>><<>>>><>><<<>><<>>>><<<><><<><<<<><<<><>>><><<><><<>><>><<>>>><<>>>><>>>><<<<>>><>>>><>>><<><>>>><<<<><<<<>><<><<<>>>><>><><>>><<<>>><>>><>><<>>><<<><<<>>><<<<>><<<>>><<>><<<>><<>>>><<<<>><<<><>>>><<<<>>>><<>>><<<<>>>><<<><<>>>><<>>><<<>>><<<>>><>>><>><>>><<<<>>><<>>><<>><<>>>><<<<>>><><<<>>>><><<<<><><<<<><<><<<>>>><<<>>><>><<<>>>><<<<>>><<<<>><<<<>>><>>>><<><>>>><<<<><>>><>>><<<<>>>><<<><>><<><<<>><<<<>><<<<><<<>>>><<>>><<><<<<>><>><>>><<<>>><<<><>>>><><<>>><<>>><<>>>><>><><<<<>><<>><<<<>><<<<>>><>><>><<<><<<<><<<>><<>>><<<<>>><<>>><<<<>>>><>>>><<<<><<<<>>>><<>>><><<><<>>>><<<<>>><<<<>>><<<>>>><<<>><<<<>>><>>>><>><<<>>>><>><<>><<><<>>><>>><<<>>>><><<<>>>><<<><>>>><<<>><<<<>>><<<><<>>><<<>><<<><>>>><<<>><<<>>>><<<<>>>><>><<<>>><<>>><<<>><<<<><>><<>>>><<>><<>><>><<<>>><>><<<<>>><<<<>>>><>><>>><<<>>>><<<<>><><<<><<<<>>><<>>>><<<><<<><<<>>>><<<><<<>><<<<>>><<<<><<<<>><<<<><<<>><>>>><<<>><>><<<><><<<>><<<>>><<<<>>>><<<>><<><>>>><><<<><><>><<>>><>><<<<>>>><<><>><<<<><<>>>><<<>>>><>>><<<>>><<<<><<<<>>><>><<<<>><><>>>><><><>>>><>><<>><<<<>>>><<<><>>><<>>>><>><<<<>>>><<<<><<>>>><>>>><<<<><<<>>><>>>><<>><<<<>><<<<>><><<><<<<><<><<<>><<>><>>><><<>><<<<>><<<<>>><<<>>><<<>>><<><<>><<<<>>>><<<>>><<<<>>>><<><<<<>>><<<<>>><<>>><<>>><<<>>><<<<>>>><>>><<<>>>><<<><><><<>><<>><<<<>>><>>><<<>><>>><<<>>><<<>>><<<<>><<<<>>>><<<>>><<<><<>>><<<>>>><<>><>><<>>>><<<<>>><<>><<><<<>>>><>><<<>>>><<<><<<<>>>><<<<>>><>>>><<<<>>><<>>><>>>><<>>>><<<><<>>>><<><<<><<>>><<<>><<<><<>><<<<>>>><<<<>>><>>>><<<>>><<<<>>><>>><<<<>><<<>>>><<<<><<>>>><<<>>><>><<<>>>><<<<>>>><<<><>><<<>><<<>><><<<><<>><<<>><<<>><>>><<<><>>>><<<>><>><>>><<<<>><<>>><<>>>><><<<<>>><<>><<<>>>><<>><<<<><>>>><<<><<><<><<<>>>><>>><>><<>>>><<>>><<><><<<<>><<>><<<<>>><>>><<<><<<<><>>>><>>>><<>>><<<><<<>>><<<<>><<<>>>><><><<<<><<>>>><>><<<<><<<<>><<>>>><<<>>><<>>>><<<<>>><>><>><<<<>><<<>>><<<<>>>><<<>>>><><<<>>><><>>>><<<<>>><<<><<><<<<>>>><<><<<><<<>>><<<<>>><<<<>>><>>>><<<<><>><<>>><<<>>>><<<><<><<<>>><><<<>>><<<<><><>>>><>><>><<<>><<<><>>>><>>><<<><>><<>>><<><<<<>>>><<<>><<<>><<<>>><<<>><>>>><<>><>>>><<>><>>>><<>>><<>>>><<>><>><>>><<<<>><<>>>><<<<>>><>>><>>><<<<>><<>>><<<<>>><<<<>>><<>>><<<><<<><><<<<>>><<<>>>><><<<><<<>><>>>><<<<>>>><<<>>><<><<>>>><<<><<>>><<<><<<>>><>><<<<><<<>><>><<>>><<>><<<><>>><<>>>><<>>><<<<><<<<>><<<>><>>><<<<><>><<<<>><<<<><<>><>>>><<<<><<<>>><<>>>><<<>><<<><<>>>><<<<>>><<<<>>><<<>>><>><<<<>>><<>>>><>><<>>><<><<<>>>><<<>>>><<>>><<<>>>><<<>>><<<>><<<><<>>><<<>><><<>>><<<><<><<<><<<>><>>>><<>><<><<<><<<<>>>><>>><<<><<>><<>>><<<><<<<>>>><<>>><>>>><<<<><<<<><<>><<>>><<<<>>><><><<<><<<>><<<>>><<>>>><<>>><<>>><<<>>><<><<<<>>><<<>>><><<<<>><<>>>><<<<>>><<>><<>>>><><<<>><>>><<<>><<<><<<>>><<<><<<>>><<<<>>>><<>><<<><>>>><<<<>>>><<<<>><>>>><<><<<>>>><<<>>><<>>><<<<><<<<>>><>>><<<>>><><<<><<>><<>><<<>>><<<>>>><<<>>>><<>>>><<>>><>><<<<>>>><<>><<<>>><<<>>><>>><<<<><<>>><>>>><<<<>>><>><<<<><<<<>>><<<>>>><>><<<<>><<<>>>><<<>>>><>>><<<>><<<>>>><<>>><<<>>>><<<<><<<>><<<><<>>><<<<>>><<<<><>>>><<>>><<><>>>><<>>>><<>>>><>>>><>>>><>>><<<<><<<>><<<><<<<>>>><<<<>><>><<>><<>><<<>>>><<><>>><<<<>>>><<>>><<>>><>>>><>><<<<>><<<<>><<>>><<><<<>>><<<<>><<<<><<>>><<<<><<><<>>><<>>><>>>><<>>>><<<<><>>>><<<<>>>><<<<>>>><<>>>><<<<>>><<>><<<>>><<<>>>><<<><<<<>>><>>><<>>>><><<<<>>><<<>><<<>>><<>>>><<>>><>><<<<>>>><<<<>>><>>><<<>><<>>>><<<>><<<><<<>><<<<>>><<<>><<<>><<<><><<<<>><<>>>><>>><<<>>>><<<>>><<>>><>><<<>>><>><<>>><<<<>><<<>>>><<<<><<<<>><>><<><<<>><<>>><>>><<<><<<<><<<<>>>><<>>>><<<<>>><><<<>>>><>>><<<>>>><>>><<<>>><>>><<<><<<><<<>>>><<<<>>>><>>>><>>><<<>>><<<>><<<<><>>><<<<>><><<<<><<<>>><<<>>>><>>><<>>>><<<>>><>>>><<>>><<<<>>>><>>>><<>>>><<>>><<<<>><<<<>>>><>>>><<<>>>><>>><<><<<><>>>><<<<><>>>><<<><<<><<<><>>><<<<>>>><<<<>>>><>>><<<>>><<>>><<<<>>><<<>><<><<<><><<<<>>>><<<<><<<>>>><<<<>><<<<>>>><<<><<<<>>><<><><<<<>>><<<>>><>>>><<<><<<>><<>>>><<<>><<<>>><<>><<>><<<>>><<><<>><>>><<<<>><><<<><<><><><<<<>>>><<<<><<<><<>>><><<>>>><>><<<<><<>>><>>>><<<<>>><><<>>>><<>>><<<<>>><<<<>>>><<<><<<<>>><<<>><<<<>>><<<><<<><<>><><<>><<<<>><>>>><<<<>><<<>><<<<>>><<<<>>><>><>><<<>><<<><<<<><>><<>><<<<>><<<<>>>><<><<><>>><<>>><<<<>>><<<>>><<><<>>>><<<>>><<<<>>>><<>><<<<>>>><<>><<<><<<>>><<>>><<<<>>><>>>><>>><>>><>>>><>>>><>>><<>><>>><<>><<><<<<>>><>>><<<>><<<<>>><>>>><<>><>><><<<><<<<>><<<>>><<<><<><<<<>><<<<><>>><<<>>><<>><>>><<><<<<>><<>><<<><<>><<>>>><<><<<>>>><<<<>><<<>>><><<>>><><<<<><<<>><<>><><<<<>>>><<>><<<>><<>>><<<<>>>><<<><<<<>>><<>><<>>>><<<<>><<>><<<<><<<>><>>><<<<>><<<<>>>><>>><>>>><<>>><>><>>>><><<<<>><<<<>><>>><<>>>><<<<>>>><>>>><<<><<<><<<<><<<<><<<<>>>><<>>><<>>>><<<<><>>>><>>><<<>>><<<<><<<<>>><<<><<<<>>>><<<<>>><><<>>><<>>><<>>>><<<><<<<>>>><<<>>><<<<>>><<<>>>><<>>>><<<><<<><<<><>><<<<>>>><<<<>>>><>><<<<><<<<><<<>>>><<<<><<>>><<<<>><>><<<><<<<>><<<><>>>><<<<>>><<<<>>>><<>>><<><<<>>>><<<<>>>><<>><<<<>>><<<<>>><<><<<<><<<<>><<<<>>><<<<>>><<<><<<>><<><<<<>>><><<<<><><<<<><<<>>>><<<<><<<<>><<<<>>>><<<<>>>><<>><><<<<>><<<<>>>><<<>><<<<><><<<<><>>>><<<>><>><<>><<<>>>><>>>><>>><<<>>>><><<<<>>>><<<>>><<><<<<>>><<<><<<<>>>><<<<>>>><>>><<><>>><>>><>><>>>><>>>><<<>>>><>>>><<><<>>><<<<><<<>><>>><<<>><<<>><<<>>>><<><<<>>><<<<>>>><<>>>><<<>>><<<<>><<>><>>>><<<><<<>>><>>><><<<<>>>><<<>>>><<>>>><<>><><<<<>>>><<><<<<>>>><<<>>>><><>>><<<<>>>><>>>><<>>><>><<<><<>>>><<><<<<><>>><<><<<>>>><<<>>><<<>><<<>><<>>>><<<<>>><<<<>>>><<>>>><<<<>><<<<>>><<<<><<<<>><<>><<>>>><<<<>><<>>><>>>><><<><>>><<><<<><>>><<><<>><<>>>><<<>><<>>><<<<>>><<<<><<<<><>>>><<>>>><<<<>>>><>>>><><<>><<<<>><<<>><<>><<<<><<>><<<><>><<<>>>><>>>><<<>>>><<<>>><><<<>>>><<<<>>>><<<>>>><<<>><<>>>><>><<<>><>><<<><<<<>>><<<>>>><<><>>>><>>><<>>><>>>><<<<>>>><<<>><<>><<<>><<<<>><<<><<>><<>>><<>>><<<><<>>>><<<>>><<>><><<<<>><<<<>><>>>><<>>>><><>><>>>><<<<>><<<<>><<<<>>>><<>>>><<>>>><<<><<>>><><<>><<<>><>>><<>>><>>><<><>>><<>><<<<>>><<<>><<<><<<>>><<<<>>><>><<<>>><<<><>>><<><<<<><<<<>><>>><>>>><>>>><>>>><<<>>><<<<>>>><>>><<>>><>>><<<<>><<<>><<<<>><<><<<>><<<>>><<<<>><>>>><>>><<<<>><<<<>><<<<>><>>>><>><<>>>><<>>><<<<>>><<<<><<<>>><<>>>><<>><<>><<<><<>>>><<<>>>><>>><><<>>>><<>>><>>><<>>><>>>><<<<>><<>>><<<>><<>><<>>><>><>><<<<>>>><<>><<<>>>><>><<<<><<<<>>><<<<>>>><<<>>><<>>><<<<>>><>><>>><<>>><>>><<<<><<><<><<><<<><<<>>>><><<<<>>>><<<<>>><>>>><>>><<<<>>><>><<<<><<<><>>>><<<>>><>>><<<<>>>><<><<<<><<><<>>><<>><<<<><<>>>><<<>>>><<<>>><><<>>>><<>>>><>>><<<>>><>>>><>><<<>>><><<<<>>><<>>><<<<>>><><>><<<>>><<><<<<>>><<>>>><>>><<<<>>>><<<<><<<>><<>>><<<>><<<<>><>>><<<>>><>>>><<<<><<>>><<>>><<<<>>>><<>>>><<>>>><<<<>><<<>>><><<<>>>><>>>><<<<><<<>>>><<<<>>><>><<>><<<<>><<<<><<>><>>>><<>><<<>>>><>>><<>>><<<<>><<<>>><<>><>>>><<<<>>><>><>>><<<<>>>><<<<><<<<>>>><<>>><<<<><>><<>>>><<<<><<<>><<<>><<<<><<<<><<><<>><>><<<><<><<>><>>><>>>><<<<>>><>>><>>>><<<>>>><<<<><<<<>>>><>>>><>>><<<<>>>><<<<>><<>><<<>>>><<<<><>><<<>>><<>><><<>>>><<>>>><>>>><><<<<>>>><<>><<<>><<<<>><<>>><<<><<<><>><><<><<<>><<>><<<>><>>>><>>><<>>><<<<>>>><<<<>>><<<<><>>>><<>>>><<><<<>>>><<<<>>><<<><<<>><>>>><<><<<<>>><<<>>><<<<>><>>>><<>>><<><>><<<>>>><<<><<<<><<<>>>><<<<>><<>>>><>>><<>>><<>>>><<<<><<>>>><<<<>>>><<<<><<>>>><<<<>>>><<>>><<<>><<>>><<<<>>><>>><<><<<<><<<<>><<<>>>><>><<<>>><<<>><<<><<<><>>><<<>>>><<<><<<><<>>><>><<<>>><<<>>>><<<>>>><>>>><<<>>><<<<>>>><<><<><<<<>><<<><>>>><<>>><<>><<<<>><<<><<<>><<<>>>><<<><>>><<<><<<<>>><<>>>><<><>><<>>>><<<<><<<><<<<><<<>><<><>><>><<>>>><>>>><<<><>>><<>><<<<>><><<<>>><<>>><<>>>><<<>><<>>>><><<<<>><><<<<>>><<>><>>><<>>>><<<>>><<<<>>><>>>><<<<><<<<>>><<<><<>>><><<<><<>><>>><>><<<<>>>><>>><>>>><<<<>>>><<<>><<<<>><>>><<<>>>><>>>><<>>><<>>>><<<<>>>><<<>>>><>>>><>><<<<>>>><>><<<<>>>><<<<>>><<<>><<<>>>><<<><<<<><<>>><<<>>>><<>><<>>>><<>>><<<>>>><<>>>><<>>>><>>>><><<<>><<><<><>>><><<<>>>><>>><><<>>><<<<>>><<>>>><<<>>><<<<><<<><>><<<<>><<<>><<<>><<>>><<<><<<>><<>><<><<><<<<>>><<>>><<<<>>><>>><<<>>><<>>><<<>><><<<<>>>><>><<<>><<<>>>><<>><<>>><>>><<<<>>>><<>>><><<<>>><>>><>><<<<>>>><>>><>>><<>>>><<>><><<>><<<<><<>>>><<<>>><>>>><<<<>><<<<><<<>><<>>>><>>><<>>>><<>><<>><<<>>><<<><<<<>>><>>>><<<>>>><<<<>>><<>>>><<>>>><<<<>><<<<>><<<><>>><<>><<>>>><>><<<<>><>>>><<<>>><<<>>><<>>>><<<>>>><>><<<><<<<>><>>>><>>><<<<>>><<<>>><<<><<<<>>>><<<<><<>>><>>>><>>><>><>><<<<>>><<>>>><<<><<<<><<<>><<<<>><>><<<>><<<<>>>><><<<><<<><<>>>><<<>><<>>>><><>>><>><<<<>>>><<>>>><<<<>>>><<>>><<<<>>>><<<>>><<<>><><<>><><<><>><<>>>><<<<><<<<>>><<<<>><<>><<<<><<<
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/17/test_input.txt	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,1 @@
+>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/Manifest.toml	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,274 @@
+# This file is machine-generated - editing it directly is not advised
+
+julia_version = "1.8.0"
+manifest_format = "2.0"
+project_hash = "69d40d1bac8d62804bfde605664d857b595497cd"
+
+[[deps.Adapt]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "195c5505521008abea5aee4f96930717958eac6f"
+uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
+version = "3.4.0"
+
+[[deps.ArgCheck]]
+git-tree-sha1 = "a3a402a35a2f7e0b87828ccabbd5ebfbebe356b4"
+uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197"
+version = "2.3.0"
+
+[[deps.Artifacts]]
+uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
+
+[[deps.AutoHashEquals]]
+git-tree-sha1 = "45bb6705d93be619b81451bb2006b7ee5d4e4453"
+uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
+version = "0.2.0"
+
+[[deps.BangBang]]
+deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
+git-tree-sha1 = "7fe6d92c4f281cf4ca6f2fba0ce7b299742da7ca"
+uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
+version = "0.3.37"
+
+[[deps.Base64]]
+uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
+
+[[deps.Baselet]]
+git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e"
+uuid = "9718e550-a3fa-408a-8086-8db961cd8217"
+version = "0.1.1"
+
+[[deps.BenchmarkTools]]
+deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"]
+git-tree-sha1 = "d9a9701b899b30332bbcb3e1679c41cce81fb0e8"
+uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
+version = "1.3.2"
+
+[[deps.Compat]]
+deps = ["Dates", "LinearAlgebra", "UUIDs"]
+git-tree-sha1 = "00a2cccc7f098ff3b66806862d275ca3db9e6e5a"
+uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
+version = "4.5.0"
+
+[[deps.CompilerSupportLibraries_jll]]
+deps = ["Artifacts", "Libdl"]
+uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
+version = "0.5.2+0"
+
+[[deps.CompositionsBase]]
+git-tree-sha1 = "455419f7e328a1a2493cabc6428d79e951349769"
+uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
+version = "0.1.1"
+
+[[deps.ConstructionBase]]
+deps = ["LinearAlgebra"]
+git-tree-sha1 = "fb21ddd70a051d882a1686a5a550990bbe371a95"
+uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
+version = "1.4.1"
+
+[[deps.DataAPI]]
+git-tree-sha1 = "e08915633fcb3ea83bf9d6126292e5bc5c739922"
+uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
+version = "1.13.0"
+
+[[deps.DataStructures]]
+deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
+git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0"
+uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
+version = "0.18.13"
+
+[[deps.DataValueInterfaces]]
+git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
+uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
+version = "1.0.0"
+
+[[deps.Dates]]
+deps = ["Printf"]
+uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
+
+[[deps.DefineSingletons]]
+git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c"
+uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52"
+version = "0.1.2"
+
+[[deps.Distributed]]
+deps = ["Random", "Serialization", "Sockets"]
+uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
+
+[[deps.Future]]
+deps = ["Random"]
+uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
+
+[[deps.InitialValues]]
+git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3"
+uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
+version = "0.3.1"
+
+[[deps.InteractiveUtils]]
+deps = ["Markdown"]
+uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
+
+[[deps.IteratorInterfaceExtensions]]
+git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
+uuid = "82899510-4779-5014-852e-03e436cf321d"
+version = "1.0.0"
+
+[[deps.JSON]]
+deps = ["Dates", "Mmap", "Parsers", "Unicode"]
+git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e"
+uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
+version = "0.21.3"
+
+[[deps.Libdl]]
+uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
+
+[[deps.LinearAlgebra]]
+deps = ["Libdl", "libblastrampoline_jll"]
+uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
+
+[[deps.Logging]]
+uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
+
+[[deps.MacroTools]]
+deps = ["Markdown", "Random"]
+git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2"
+uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
+version = "0.5.10"
+
+[[deps.Markdown]]
+deps = ["Base64"]
+uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
+
+[[deps.MicroCollections]]
+deps = ["BangBang", "InitialValues", "Setfield"]
+git-tree-sha1 = "4d5917a26ca33c66c8e5ca3247bd163624d35493"
+uuid = "128add7d-3638-4c79-886c-908ea0c25c34"
+version = "0.1.3"
+
+[[deps.Mmap]]
+uuid = "a63ad114-7e13-5084-954f-fe012c677804"
+
+[[deps.OpenBLAS_jll]]
+deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
+uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
+version = "0.3.20+0"
+
+[[deps.OrderedCollections]]
+git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
+uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
+version = "1.4.1"
+
+[[deps.ParserCombinator]]
+deps = ["AutoHashEquals", "Printf"]
+git-tree-sha1 = "3a0e65d9a73e3bb6ed28017760a1664423d7e37c"
+uuid = "fae87a5f-d1ad-5cf0-8f61-c941e1580b46"
+version = "2.1.1"
+
+[[deps.Parsers]]
+deps = ["Dates", "SnoopPrecompile"]
+git-tree-sha1 = "b64719e8b4504983c7fca6cc9db3ebc8acc2a4d6"
+uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
+version = "2.5.1"
+
+[[deps.Printf]]
+deps = ["Unicode"]
+uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
+
+[[deps.Profile]]
+deps = ["Printf"]
+uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
+
+[[deps.Random]]
+deps = ["SHA", "Serialization"]
+uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
+
+[[deps.Requires]]
+deps = ["UUIDs"]
+git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
+uuid = "ae029012-a4dd-5104-9daa-d747884805df"
+version = "1.3.0"
+
+[[deps.SHA]]
+uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
+version = "0.7.0"
+
+[[deps.Serialization]]
+uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
+
+[[deps.Setfield]]
+deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"]
+git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac"
+uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
+version = "1.1.1"
+
+[[deps.SnoopPrecompile]]
+git-tree-sha1 = "f604441450a3c0569830946e5b33b78c928e1a85"
+uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c"
+version = "1.0.1"
+
+[[deps.Sockets]]
+uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
+
+[[deps.SparseArrays]]
+deps = ["LinearAlgebra", "Random"]
+uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
+
+[[deps.SplittablesBase]]
+deps = ["Setfield", "Test"]
+git-tree-sha1 = "e08a62abc517eb79667d0a29dc08a3b589516bb5"
+uuid = "171d559e-b47b-412a-8079-5efa626c420e"
+version = "0.1.15"
+
+[[deps.StaticArrays]]
+deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"]
+git-tree-sha1 = "ffc098086f35909741f71ce21d03dadf0d2bfa76"
+uuid = "90137ffa-7385-5640-81b9-e52037218182"
+version = "1.5.11"
+
+[[deps.StaticArraysCore]]
+git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a"
+uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
+version = "1.4.0"
+
+[[deps.Statistics]]
+deps = ["LinearAlgebra", "SparseArrays"]
+uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
+
+[[deps.TableTraits]]
+deps = ["IteratorInterfaceExtensions"]
+git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
+uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
+version = "1.0.1"
+
+[[deps.Tables]]
+deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"]
+git-tree-sha1 = "c79322d36826aa2f4fd8ecfa96ddb47b174ac78d"
+uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
+version = "1.10.0"
+
+[[deps.Test]]
+deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
+uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
+
+[[deps.Transducers]]
+deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"]
+git-tree-sha1 = "c42fa452a60f022e9e087823b47e5a5f8adc53d5"
+uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999"
+version = "0.4.75"
+
+[[deps.UUIDs]]
+deps = ["Random", "SHA"]
+uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
+
+[[deps.Unicode]]
+uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
+
+[[deps.ZygoteRules]]
+deps = ["MacroTools"]
+git-tree-sha1 = "8c1a8e4dfacb1fd631745552c8db35d0deb09ea0"
+uuid = "700de1a5-db45-46bc-99cf-38207098b444"
+version = "0.2.2"
+
+[[deps.libblastrampoline_jll]]
+deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
+uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
+version = "5.1.1+0"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2022/Project.toml	Sat Dec 02 12:22:41 2023 +0100
@@ -0,0 +1,6 @@
+[deps]
+BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
+DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
+ParserCombinator = "fae87a5f-d1ad-5cf0-8f61-c941e1580b46"
+StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
+Transducers = "28d57a85-8fef-5791-bfe6-a80928e7c999"
--- a/Manifest.toml	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-# This file is machine-generated - editing it directly is not advised
-
-julia_version = "1.8.0"
-manifest_format = "2.0"
-project_hash = "a9c9254dd6533f580c6a736737f716edb529b934"
-
-[[deps.Adapt]]
-deps = ["LinearAlgebra"]
-git-tree-sha1 = "195c5505521008abea5aee4f96930717958eac6f"
-uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
-version = "3.4.0"
-
-[[deps.ArgCheck]]
-git-tree-sha1 = "a3a402a35a2f7e0b87828ccabbd5ebfbebe356b4"
-uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197"
-version = "2.3.0"
-
-[[deps.Artifacts]]
-uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
-
-[[deps.AutoHashEquals]]
-git-tree-sha1 = "45bb6705d93be619b81451bb2006b7ee5d4e4453"
-uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
-version = "0.2.0"
-
-[[deps.BangBang]]
-deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
-git-tree-sha1 = "7fe6d92c4f281cf4ca6f2fba0ce7b299742da7ca"
-uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
-version = "0.3.37"
-
-[[deps.Base64]]
-uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
-
-[[deps.Baselet]]
-git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e"
-uuid = "9718e550-a3fa-408a-8086-8db961cd8217"
-version = "0.1.1"
-
-[[deps.BenchmarkTools]]
-deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"]
-git-tree-sha1 = "d9a9701b899b30332bbcb3e1679c41cce81fb0e8"
-uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
-version = "1.3.2"
-
-[[deps.Compat]]
-deps = ["Dates", "LinearAlgebra", "UUIDs"]
-git-tree-sha1 = "00a2cccc7f098ff3b66806862d275ca3db9e6e5a"
-uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
-version = "4.5.0"
-
-[[deps.CompilerSupportLibraries_jll]]
-deps = ["Artifacts", "Libdl"]
-uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
-version = "0.5.2+0"
-
-[[deps.CompositionsBase]]
-git-tree-sha1 = "455419f7e328a1a2493cabc6428d79e951349769"
-uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
-version = "0.1.1"
-
-[[deps.ConstructionBase]]
-deps = ["LinearAlgebra"]
-git-tree-sha1 = "fb21ddd70a051d882a1686a5a550990bbe371a95"
-uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
-version = "1.4.1"
-
-[[deps.DataAPI]]
-git-tree-sha1 = "e08915633fcb3ea83bf9d6126292e5bc5c739922"
-uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
-version = "1.13.0"
-
-[[deps.DataStructures]]
-deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
-git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0"
-uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
-version = "0.18.13"
-
-[[deps.DataValueInterfaces]]
-git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
-uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
-version = "1.0.0"
-
-[[deps.Dates]]
-deps = ["Printf"]
-uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
-
-[[deps.DefineSingletons]]
-git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c"
-uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52"
-version = "0.1.2"
-
-[[deps.Distributed]]
-deps = ["Random", "Serialization", "Sockets"]
-uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
-
-[[deps.Future]]
-deps = ["Random"]
-uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
-
-[[deps.InitialValues]]
-git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3"
-uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
-version = "0.3.1"
-
-[[deps.InteractiveUtils]]
-deps = ["Markdown"]
-uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
-
-[[deps.IteratorInterfaceExtensions]]
-git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
-uuid = "82899510-4779-5014-852e-03e436cf321d"
-version = "1.0.0"
-
-[[deps.JSON]]
-deps = ["Dates", "Mmap", "Parsers", "Unicode"]
-git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e"
-uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
-version = "0.21.3"
-
-[[deps.Libdl]]
-uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
-
-[[deps.LinearAlgebra]]
-deps = ["Libdl", "libblastrampoline_jll"]
-uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
-
-[[deps.Logging]]
-uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
-
-[[deps.MacroTools]]
-deps = ["Markdown", "Random"]
-git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2"
-uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
-version = "0.5.10"
-
-[[deps.Markdown]]
-deps = ["Base64"]
-uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
-
-[[deps.MicroCollections]]
-deps = ["BangBang", "InitialValues", "Setfield"]
-git-tree-sha1 = "4d5917a26ca33c66c8e5ca3247bd163624d35493"
-uuid = "128add7d-3638-4c79-886c-908ea0c25c34"
-version = "0.1.3"
-
-[[deps.Mmap]]
-uuid = "a63ad114-7e13-5084-954f-fe012c677804"
-
-[[deps.OpenBLAS_jll]]
-deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
-uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
-version = "0.3.20+0"
-
-[[deps.OrderedCollections]]
-git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
-uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
-version = "1.4.1"
-
-[[deps.ParserCombinator]]
-deps = ["AutoHashEquals", "Printf"]
-git-tree-sha1 = "3a0e65d9a73e3bb6ed28017760a1664423d7e37c"
-uuid = "fae87a5f-d1ad-5cf0-8f61-c941e1580b46"
-version = "2.1.1"
-
-[[deps.Parsers]]
-deps = ["Dates", "SnoopPrecompile"]
-git-tree-sha1 = "b64719e8b4504983c7fca6cc9db3ebc8acc2a4d6"
-uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
-version = "2.5.1"
-
-[[deps.Printf]]
-deps = ["Unicode"]
-uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
-
-[[deps.Profile]]
-deps = ["Printf"]
-uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
-
-[[deps.Random]]
-deps = ["SHA", "Serialization"]
-uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
-
-[[deps.Requires]]
-deps = ["UUIDs"]
-git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
-uuid = "ae029012-a4dd-5104-9daa-d747884805df"
-version = "1.3.0"
-
-[[deps.SHA]]
-uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
-version = "0.7.0"
-
-[[deps.Serialization]]
-uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
-
-[[deps.Setfield]]
-deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"]
-git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac"
-uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
-version = "1.1.1"
-
-[[deps.SnoopPrecompile]]
-git-tree-sha1 = "f604441450a3c0569830946e5b33b78c928e1a85"
-uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c"
-version = "1.0.1"
-
-[[deps.Sockets]]
-uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
-
-[[deps.SparseArrays]]
-deps = ["LinearAlgebra", "Random"]
-uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
-
-[[deps.SplittablesBase]]
-deps = ["Setfield", "Test"]
-git-tree-sha1 = "e08a62abc517eb79667d0a29dc08a3b589516bb5"
-uuid = "171d559e-b47b-412a-8079-5efa626c420e"
-version = "0.1.15"
-
-[[deps.StaticArraysCore]]
-git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a"
-uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
-version = "1.4.0"
-
-[[deps.Statistics]]
-deps = ["LinearAlgebra", "SparseArrays"]
-uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
-
-[[deps.TableTraits]]
-deps = ["IteratorInterfaceExtensions"]
-git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
-uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
-version = "1.0.1"
-
-[[deps.Tables]]
-deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"]
-git-tree-sha1 = "c79322d36826aa2f4fd8ecfa96ddb47b174ac78d"
-uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
-version = "1.10.0"
-
-[[deps.Test]]
-deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
-uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
-
-[[deps.Transducers]]
-deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"]
-git-tree-sha1 = "c42fa452a60f022e9e087823b47e5a5f8adc53d5"
-uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999"
-version = "0.4.75"
-
-[[deps.UUIDs]]
-deps = ["Random", "SHA"]
-uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
-
-[[deps.Unicode]]
-uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
-
-[[deps.ZygoteRules]]
-deps = ["MacroTools"]
-git-tree-sha1 = "8c1a8e4dfacb1fd631745552c8db35d0deb09ea0"
-uuid = "700de1a5-db45-46bc-99cf-38207098b444"
-version = "0.2.2"
-
-[[deps.libblastrampoline_jll]]
-deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
-uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
-version = "5.1.1+0"
--- a/Project.toml	Mon Dec 19 21:49:38 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-[deps]
-BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
-DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
-ParserCombinator = "fae87a5f-d1ad-5cf0-8f61-c941e1580b46"
-Transducers = "28d57a85-8fef-5791-bfe6-a80928e7c999"