Start catching up after vacation.

This commit is contained in:
2021-12-19 19:01:52 -08:00
parent aa1bc0ee49
commit 1f286b293e
17 changed files with 1816 additions and 3 deletions

67
Cargo.lock generated
View File

@@ -7,15 +7,53 @@ name = "advent2021"
version = "0.1.0"
dependencies = [
"itertools",
"pathfinding",
"thiserror",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "fixedbitset"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e"
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "indexmap"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "integer-sqrt"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770"
dependencies = [
"num-traits",
]
[[package]]
name = "itertools"
version = "0.10.3"
@@ -25,6 +63,29 @@ dependencies = [
"either",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "pathfinding"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a64bfa665d8821a903701c7bb440e7f72b1f05387b390cc23f498cc23148099"
dependencies = [
"fixedbitset",
"indexmap",
"integer-sqrt",
"itertools",
"num-traits",
"rustc-hash",
]
[[package]]
name = "proc-macro2"
version = "1.0.32"
@@ -43,6 +104,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "syn"
version = "1.0.82"

View File

@@ -5,4 +5,5 @@ edition = "2021"
[dependencies]
itertools = "0.10.3"
pathfinding = "3.0.5"
thiserror = "1.0"

25
data/day12a.txt Normal file
View File

@@ -0,0 +1,25 @@
bm-XY
ol-JS
bm-im
RD-ol
bm-QI
JS-ja
im-gq
end-im
ja-ol
JS-gq
bm-AF
RD-start
RD-ja
start-ol
cj-bm
start-JS
AF-ol
end-QI
QI-gq
ja-gq
end-AF
im-QI
bm-gq
ja-QI
gq-RD

7
data/day12t1.txt Normal file
View File

@@ -0,0 +1,7 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end

10
data/day12t2.txt Normal file
View File

@@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc

812
data/day13a.txt Normal file
View File

@@ -0,0 +1,812 @@
470,705
331,196
1241,728
1034,161
181,850
999,484
480,680
798,33
226,86
475,226
113,287
770,702
47,35
848,312
1129,402
179,326
766,404
1258,717
470,494
723,434
418,291
100,298
994,316
423,434
985,292
721,261
528,572
595,567
909,665
411,292
1056,291
1051,434
311,484
462,312
187,273
715,567
114,819
634,861
79,318
912,344
1144,845
152,745
201,464
840,185
291,100
1084,31
1255,434
909,229
895,827
557,29
441,159
661,193
826,215
535,70
974,767
254,739
512,189
868,75
1076,9
700,86
684,515
356,422
348,344
605,341
360,586
383,824
239,393
751,12
253,229
403,759
166,273
1196,819
406,301
343,102
1119,618
333,892
711,789
283,70
418,603
380,714
756,255
20,375
1145,794
642,180
1140,273
984,451
763,619
196,427
869,159
460,96
35,548
512,709
1231,318
1163,21
465,275
32,187
212,296
718,835
1036,42
1002,672
108,492
321,892
294,0
252,350
377,733
1196,822
316,344
254,519
1168,49
1158,745
142,49
130,504
397,56
718,186
463,170
482,463
1032,752
649,193
512,158
895,501
1150,122
537,833
915,434
790,262
1058,539
764,44
512,861
493,296
472,422
44,86
1101,592
671,276
977,2
822,621
179,668
415,46
1067,154
895,169
475,728
231,434
156,103
1176,72
113,607
301,851
927,824
346,870
892,603
610,86
1114,19
295,353
402,350
1118,145
201,318
681,732
338,792
855,733
202,364
125,430
1140,285
917,309
1309,542
10,540
246,499
1038,178
209,609
242,16
10,214
20,519
276,173
540,520
192,582
681,891
830,680
600,44
895,848
1009,219
425,442
1049,185
994,166
1034,733
453,240
605,833
154,71
141,607
840,494
131,87
1084,86
1193,592
1163,166
847,724
329,318
567,46
850,798
554,255
817,598
723,658
1027,70
1154,103
822,273
704,290
985,72
386,593
1015,353
907,435
867,847
711,835
415,718
903,343
252,539
574,310
295,801
156,733
1173,395
736,218
700,360
865,144
1044,240
708,628
354,262
1298,42
987,250
857,430
184,185
1066,14
130,894
917,585
882,596
156,791
868,296
1248,29
1300,354
1180,504
542,385
710,850
172,407
1064,310
962,166
458,504
992,295
517,667
95,12
484,299
523,390
865,733
326,82
1300,91
69,728
470,548
1015,541
141,735
278,756
1237,140
642,714
728,71
1064,666
1128,477
301,403
677,159
340,266
984,812
972,792
212,374
828,463
987,810
1109,318
212,178
1275,548
1016,894
962,128
840,548
10,149
933,833
80,411
1136,883
676,766
421,632
242,786
131,721
274,189
407,576
80,35
393,361
425,421
184,397
1101,196
1154,411
529,878
711,518
1223,270
579,459
343,838
428,415
933,733
930,628
55,294
1226,336
378,721
435,553
546,492
1019,100
763,684
1076,885
1150,772
276,876
574,51
25,610
117,644
410,563
311,838
192,817
626,696
1309,352
604,18
1036,705
782,124
338,464
502,774
1243,882
950,756
1232,593
25,284
853,173
1295,614
1144,534
44,534
1118,312
954,515
410,747
806,348
1193,644
1248,59
700,836
247,318
1121,739
681,715
1185,430
759,103
459,504
981,292
1131,668
798,64
728,39
251,435
688,187
326,451
828,351
654,869
723,712
1300,680
442,598
1310,645
688,222
994,344
277,833
309,318
26,184
711,387
418,515
1109,436
274,705
1131,813
618,614
229,298
388,128
411,366
125,464
3,362
131,173
1216,772
830,540
572,115
922,576
830,214
520,184
895,718
808,203
443,847
729,453
781,240
1078,794
1282,144
196,390
502,203
992,711
557,588
934,828
1010,632
212,520
174,11
976,630
1066,147
913,822
731,459
213,93
244,270
306,791
254,155
103,103
671,52
1128,271
1010,262
62,708
412,556
5,193
294,446
828,95
201,458
838,271
47,859
314,628
425,473
571,654
994,540
567,841
236,575
141,287
197,621
480,206
868,534
435,822
62,59
363,346
1056,739
201,10
994,680
907,135
974,743
1168,64
380,180
247,103
1225,747
841,287
79,352
295,161
393,306
864,646
1158,149
348,128
348,469
189,739
199,285
318,711
888,794
1109,458
1068,108
463,724
397,822
1255,294
917,185
272,716
706,466
979,644
887,460
1053,838
1131,226
1173,787
979,196
557,865
441,735
1290,519
1044,576
1222,854
989,165
107,723
1238,155
67,460
1238,71
1213,726
443,47
316,166
711,105
498,273
70,102
65,585
475,442
599,789
32,873
1012,379
623,609
10,91
569,147
1067,814
580,798
321,2
209,196
967,410
1230,411
1282,870
731,87
736,859
294,894
546,402
334,630
559,12
651,196
65,261
1149,598
473,492
393,452
629,491
480,763
1202,44
1261,61
1056,519
992,127
972,430
740,562
344,290
882,479
45,644
1193,302
1113,273
58,525
718,865
400,515
1084,479
1074,603
835,450
316,728
480,373
1154,733
892,575
1097,129
353,59
1136,688
1128,422
547,619
587,182
962,344
622,707
626,198
1154,483
75,135
277,161
894,406
278,534
951,609
711,152
70,550
738,432
907,759
882,534
923,327
933,229
383,294
25,3
1009,851
507,614
174,883
295,129
276,428
446,86
318,767
703,859
1094,710
480,688
1184,124
336,127
923,567
790,184
1285,284
152,579
599,742
1197,287
639,500
467,273
785,495
300,262
855,285
277,285
267,567
403,459
1179,56
1029,801
551,103
1289,159
415,515
97,596
1109,884
885,227
166,534
213,129
927,70
472,623
1113,49
480,354
166,397
1034,721
629,610
376,590
442,411
676,861
1230,859
1068,878
278,590
49,161
899,528
759,791
1071,169
1230,758
1032,380
271,387
974,711
0,197
70,400
806,856
987,698
1038,380
395,460
793,107
376,828
405,152
78,301
256,550
1113,497
892,274
853,721
783,865
397,166
579,87
243,154
454,280
999,500
898,502
55,600
621,161
786,894
1144,808
192,134
1126,285
196,245
1290,833
1223,501
847,276
835,452
1228,523
653,542
413,250
1200,490
278,304
813,365
582,855
633,735
520,710
398,344
1145,122
740,332
1131,529
544,180
1039,61
363,548
981,740
830,521
674,865
736,676
300,632
671,170
572,299
185,607
907,459
1196,72
687,285
196,19
55,434
999,813
288,754
446,646
981,154
587,460
323,810
1126,497
110,714
512,326
830,354
1232,301
266,240
172,487
1208,152
618,280
766,714
721,633
316,680
987,523
147,614
672,380
467,173
253,665
840,189
673,878
944,754
278,75
1163,813
927,294
1310,197
1183,865
47,488
152,315
472,477
770,371
388,766
108,44
863,294
629,715
1043,775
924,593
1179,838
703,655
1213,596
985,766
830,11
1031,721
623,285
130,448
380,628
72,739
84,749
977,729
318,183
229,227
687,733
179,564
415,270
606,138
1274,280
295,541
1054,550
610,836
239,583
524,894
383,600
1102,808
830,883
828,543
686,845
252,544
832,490
1109,10
1009,267
869,765
822,360
928,716
1118,817
1063,103
10,680
497,813
295,609
1230,310
1042,145
1144,397
70,494
226,31
378,466
401,441
592,29
257,838
366,754
174,540
1253,49
78,593
903,576
764,828
382,716
793,499
1063,576
316,878
1128,417
1298,266
520,262
10,354
388,576
403,435
393,451
626,750
610,58
279,721
358,574
239,400
1010,184
1253,845
415,67
867,47
1032,75
1156,519
254,827
582,603
360,696
1071,311
246,666
353,851
838,477
320,182
835,220
1282,24
200,280
57,845
504,856
741,182
242,430
291,794
fold along x=655
fold along y=447
fold along x=327
fold along y=223
fold along x=163
fold along y=111
fold along x=81
fold along y=55
fold along x=40
fold along y=27
fold along y=13
fold along y=6

21
data/day13t.txt Normal file
View File

@@ -0,0 +1,21 @@
6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0
fold along y=7
fold along x=5

102
data/day14a.txt Normal file
View File

@@ -0,0 +1,102 @@
SHPPPVOFPBFCHHBKBNCV
HK -> C
SP -> H
VH -> K
KS -> B
BC -> S
PS -> K
PN -> S
NC -> F
CV -> B
SH -> K
SK -> H
KK -> O
HO -> V
HP -> C
HB -> S
NB -> N
HC -> K
SB -> O
SN -> C
BP -> H
FC -> V
CF -> C
FB -> F
VP -> S
PO -> N
HN -> N
BS -> O
NF -> H
BH -> O
NK -> B
KC -> B
OS -> S
BB -> S
SV -> K
CH -> B
OB -> K
FV -> B
CP -> V
FP -> C
VC -> K
FS -> S
SS -> F
VK -> C
SF -> B
VS -> B
CC -> P
SC -> S
HS -> K
CN -> C
BN -> N
BK -> B
FN -> H
OK -> S
FO -> S
VB -> C
FH -> S
KN -> K
CK -> B
KV -> P
NP -> P
CB -> N
KB -> C
FK -> K
BO -> O
OV -> B
OC -> B
NO -> F
VF -> V
VO -> B
FF -> K
PP -> O
VV -> K
PC -> N
OF -> S
PV -> P
PB -> C
KO -> V
BF -> N
OO -> K
NV -> P
PK -> V
BV -> C
HH -> K
PH -> S
OH -> B
HF -> S
NH -> H
NN -> K
KF -> H
ON -> N
PF -> H
CS -> H
CO -> O
SO -> K
HV -> N
NS -> N
KP -> S
OP -> N
KH -> P
VN -> H

18
data/day14t.txt Normal file
View File

@@ -0,0 +1,18 @@
NNCB
CH -> B
HH -> N
CB -> H
NH -> C
HB -> C
HC -> B
HN -> C
NN -> C
BH -> H
NC -> B
NB -> B
BN -> B
BB -> N
BC -> B
CC -> N
CN -> C

100
data/day15a.txt Normal file
View File

@@ -0,0 +1,100 @@
4474378939294561989629896994983437978985699596253525532314671357192283111874776269135656912429997578
7219771638623996974474331969734641552892111142431138735944711231631835799842996212331146124475743238
2961148417649542737169677941564183516932969881196199629267699818691135791971999512361149183535329621
9871881628922851313992884355318183839744114854999945898819527955613877899148971997483443895124972749
1919361485782789198624931971845488739823696439544194485467971198599719115839184879611199597989117999
1762668465318987168679928273548752326493925445898712574999271872149411413954567149128321356713711996
9758891114897878442978961731916935611295376892731655257822281645887798623165679892842795149121794562
8794174313234999832712179769998559998319429239188767268151198118491878742622198897183212759541967655
2988678541317271143977933951868179839261219262553692783314191948932847911897935195171794197173989921
7937619183351979421629995717138359299237763666982678128915583393591966489388882278897968133587978187
1771288861854197689291788182899974391348865254618377682157212997376757227474976188287284936469139151
9183171919381592591722911886147813851975446285895928831495379146316888188317259118133391938222425326
8999178115764971149712252879912618793998823997753599775883399792278112838295641244444695117892369594
1873895726139973829121992299149664519785161871191838821669115381988745189919982189161288151474919995
4984136373971951668595392799193993899717185589797683743651997948311187535129949925427154914977164128
9999159992495621281598156294198291771196656252551198178355135412329871819929964915836591711989341781
7448271118737319391897193945577185237289149161185958425793253988117519337798691129411823525491989579
1912877398736652997252949361587894888177859385896119191174915547635924182517149861596823312348516838
7411916158128158526295478182717158294634384119891189918596922443111778313519369151918184392138369342
3989641959996582997942999622814729287794974299321769978698859937138824918999289852969229264591966121
8248393694679143264483712911924992583617814177146997918231121311389144659299451133991759578899318192
3927235872389919653155979999938328728187786191428826154721811577636987639937191152179849749966459891
1948525667811945875973719911429986557611991729719152988893663912242325911951514496896839921798125311
4987111141491841355858599711851255968675598926996649953727649597973995225881919322173123485832889187
1365195963998349531975969939812311357919355589887113191872918217753311788481269124528221117399621391
2618399161117299311163167989995957247641824731167387813331889776165824292119925999974397616419172118
6291632879111763162218245818574896537571235342881933628446932929988162198918431515299983116383625972
4989885351975368919517881131331939647361285982389886925914714583162935321262181334119131787812193875
4299299298919624924959969574186387338111585431643179184399993147111734367892182112528965596812136913
1913417117824121122119581991583716146219291199512144882994343791853825968313288116386929568382564187
1111259582212962927119928188628297964251334111125433112968386513986892961393919529268118897941692493
2715119997271968941687778579456127393214439129136886489627687923892484915195916991318729518168291959
2291724998124331715461758417591991226316441238978117126961397713993893999191415391189914953491293518
6651599814824738431585179992975983597917279992953923879142789688619729867911998791486584911598218845
2918442247528921633279871699883197935812912988473973121391419422515181381798846124621198681771116747
7172399883999223589838199921288236965432928913987668795869711289579187827728254357182673543399455211
3569393618413195995391741993182111311863518792867229192811659349495352298888119612596629417295412514
3998347219684977173226832679351211849496942187999476517196156923911939957433439827199611519926291969
9977828541228662797249561538682143142912917199521133659429132814291869965747141895918621158384181577
3967357136159726912989158186141497914658884759161819339941915817318261777142291971767934513151711191
8778541261893461761951522343928625399856964371891169438911911122822912841986768693517712511587843892
3833315936351459473456192583978135792776752315117136132357898139879939295549611194156997971187878978
2999641761928943389161333525895439191749829143634997999562535389149495518993726784548236849917137469
4214435519912859292367198497751599991519199621895696677722866184996118129977367158899387561811918658
7231114979829829321158658131391759347796376211984948269698619841398767854635929631175398998618572335
9313714946993197143176667115892291898319189491659939292999929988795125299947811314219729882911991887
2431979557916685876176288971223844899949112179913119728153582922392676827594238311846859276898923985
2298182669623428768512173915565236181839119711668131839772497512198294739345891359413973166631273169
8252112361839197878358752854282389886943817597211988118627211731273149928198939566118122128841996531
2337699983275712849656128989981911537185958574583845722121193117562892294498614395491592899933659212
7835143227123429411997859131228998886319979718665139818711399818999495433364914764241123721713998422
2342981165371313441558921141193218916711873656679413979634321347456287987891354613188158163526439664
9968695782986491149112599371175397912721977143321762942839646919197966291866914197298621385251921577
3998992498311799137251321139836993298621918948485199967815255118632159287218116971357568151411518924
1888767584516918979116831969684198131139152419142419199229931716585258963961725216716375611191148939
8679972994968135896941454213273618172633413893517415398811979928196388336225492953687951759799299494
9268198998268358914731411728913143173989653793437178974319158741943243387571241681357965185312759759
4514415891598969983119893138887691162819199829581939189129625117153997172489929659441995563665252756
9761151889796191211989125275371563715891139933695658126189249913196967329183393395969219863889676661
2938315992611197591948197275927991961719112797199755413492386942224942718236489121713581914899162893
4395774214496174235572725299871291344821199963513129911973529221391842392121228344796144961395373279
7169235111278731299349194879561642927221385965252469499129166943949261126118955691946896131632763991
4182586898216472291721495499162914796616976593699934121197795791198151975744258153997558688681125324
2771241899369961675639292111153329919298919888341935788379952838991529795168864334579341944353139918
1929719796991998842893188199974443739822392912715991758633111534282888557598811717116422289319174234
8227445999711199165256581394711919882435899194112272635796122499955738435681954751995754828785863335
8729951893951458193176413529119379912287122558862639638362659118815726858589241612424874965948595588
8511215326829698921879251514193578281912679118343826143217429129999127819784588298767727133549889612
6382942339132989347621977329997789611123946187243171299917261115375998629792191171457419111628551833
5196411177129652468443166759257467191294653897926186178359322737194158687342924625234616743421831915
3119774454627842122238898938198398383523128289373178928124148914919779921881813499178793921224852955
7531169319889954774375677294553282895191113131163599175439212797364869867596793921132718138441171912
6731921588989796739221366138283466411951368178219585181184473112811174364385961459883733385891993199
4574139868545716129662294787788295397897183864953171131197921294921216787929998139387985941459997892
9114942724959127928293995753431994317864268467596979991595123389116539473212431173289917364566915973
9341929934129358191797626852989194781281961649194523995992215232749181878422232253289971438754945431
9711152565169547161792212418146438141573599572942189811381975633231484186771811384619293994316987371
6131964633192235767728441171994861691529178511919117275411839951991266231998851948696438627996557551
3148296295114114748119216197997581912166946469723628251179241221245394648451897828498337979132867349
5619591141279131179181294531676498187714322291293127899492999728165269816922513816979398883981987125
9291461484772577319579551995948438439426145159466288861499231447345317187441884819168882981519468534
7168729632153199693784461154421624968914968952182817868119431781278811691271694391273878312657379273
9946766299185992112985121571599989161421889915736923711827194941719778878516511122132169474883348691
9856269294522977396615891811325159414911139194979131992323319999997799632878319169846119312295884989
4478951999896991194591814281651647293997171866357947886291688317199128157536483298223818685997392164
6118292371386186497793385499159998311132592238538673922123742571831885763912281733919347629811931136
1559539789584621626699998299699573848437397472896218368568884152614411988211446699867863392231178582
3955545111973721673191918166186131172392954394391219111256767119175548689756115339875111299664124644
8532211187629552833266327798975958598213391751421237299429191278411695787897851286879811159917618734
2929979895191915513867778943916115416353324189939545761426692999878281933282414635716916418195731288
1752488277292284446514194696663537222777119194745592921911172268969679581894751682321198962925794788
9137893929311663938849971741824143649379956797731399631858279684249888929391696496889397231156431327
1867976767614781682191913943361471819244932778711517643998163299119525998895828969289556719268691861
7964834798931319884983618211814386951383713141581986214139319531157939294721187371941194911787999195
9136759325819523117222783968949195359947999675194157265271519931694932993191618368533937986955857334
1253987569539135869579376395211977798915817921811334441166659757918483967813112499681797768695123417
1194831387932819991127838412992226682976224442219982251828819129911478993471543959236282538182799247
9183416999951935493911137611615966391419988372968197976193987713623716848299299431993223458419679991
4962689198187192592599439628128214183938152641919458516294432194147333651495386497911639332152979188
8798649298935671297823969873452881511219118163995469811846217496897676246893511198571281879831529181

10
data/day15t.txt Normal file
View File

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

145
src/bin/day12.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::collections::{HashMap, HashSet, VecDeque};
use thiserror::Error;
#[derive(Debug, Error, PartialEq)]
enum Oopsie {
#[error("Bad line found: {0}")]
BadLine(String),
}
const TEST1_DATA: &str = include_str!("../../data/day12t1.txt");
const TEST2_DATA: &str = include_str!("../../data/day12t2.txt");
const REAL_DATA: &str = include_str!("../../data/day12a.txt");
struct Graph<'a> {
edges: HashMap<&'a str, HashSet<&'a str>>,
}
impl<'a> Graph<'a> {
fn add_edge(&mut self, from: &'a str, to: &'a str) {
match self.edges.get_mut(from) {
None => {
let mut new_set = HashSet::new();
new_set.insert(to);
self.edges.insert(from, new_set);
}
Some(set) => {
set.insert(to);
}
}
}
fn paths(&self) -> Paths<'_> {
Paths {
graph: self,
state: VecDeque::from([vec!["start"]]),
}
}
}
struct Paths<'a> {
graph: &'a Graph<'a>,
state: VecDeque<Vec<&'a str>>,
}
fn count<T: PartialEq>(items: &[T], item: &T) -> usize {
let mut num = 0;
for x in items.iter() {
if x == item {
num += 1;
}
}
num
}
fn still_valid(items: &[&str]) -> bool {
let mut counts = HashMap::new();
for item in items.iter() {
if item.chars().all(|x| x.is_lowercase()) {
if counts.contains_key(item) {
counts.insert(item, 2);
} else {
counts.insert(item, 1);
}
}
}
let mut caught_two = false;
for count in counts.values() {
if caught_two && count > &1 {
return false;
}
if count > &1 {
caught_two = true;
}
}
true
}
impl<'a> Iterator for Paths<'a> {
type Item = Vec<&'a str>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(possible) = self.state.pop_front() {
match possible.last() {
None => panic!("Internal error; empty path in queue"),
Some(&"end") => return Some(possible),
Some(v) => {
for x in self.graph.edges.get(v).unwrap_or(&HashSet::new()) {
if x == &"start" {
continue;
}
if !x.chars().all(|x| x.is_lowercase()) || count(&possible, x) < 2 {
let mut copy = possible.clone();
copy.push(x);
if still_valid(&copy) {
self.state.push_back(copy);
}
}
}
}
}
}
None
}
}
impl<'a> TryFrom<&'a str> for Graph<'a> {
type Error = Oopsie;
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
let mut graph = Graph {
edges: HashMap::new(),
};
for line in value.lines() {
match line.split_once('-') {
None => return Err(Oopsie::BadLine(line.to_string())),
Some((left, right)) => {
graph.add_edge(left, right);
graph.add_edge(right, left);
}
}
}
Ok(graph)
}
}
fn main() {
let test1 = Graph::try_from(TEST1_DATA).unwrap();
let test2 = Graph::try_from(TEST2_DATA).unwrap();
let real = Graph::try_from(REAL_DATA).unwrap();
println!("Test #1 count: {}", test1.paths().count());
println!("Test #2 count: {}", test2.paths().count());
println!("Real count: {}", real.paths().count());
}

141
src/bin/day13.rs Normal file
View File

@@ -0,0 +1,141 @@
use core::num::ParseIntError;
use std::str::FromStr;
use thiserror::Error;
const TEST_DATA: &str = include_str!("../../data/day13t.txt");
const REAL_DATA: &str = include_str!("../../data/day13a.txt");
#[derive(Debug, Error, PartialEq)]
enum Oopsie {
#[error("Couldn't parse point based on this string: {0}")]
InvalidPoint(String),
#[error("Couldn't parse fold based on this string: {0}")]
BadFold(String),
#[error("Couldn't parse number: {0}")]
ParseIntError(#[from] ParseIntError),
}
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
struct Point {
x: usize,
y: usize,
}
impl FromStr for Point {
type Err = Oopsie;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.split_once(',') {
None => Err(Oopsie::InvalidPoint(s.to_string())),
Some((xstr, ystr)) => {
let x = usize::from_str(xstr)?;
let y = usize::from_str(ystr)?;
Ok(Point { x, y })
}
}
}
}
enum Fold {
AlongX(usize),
AlongY(usize),
}
impl FromStr for Fold {
type Err = Oopsie;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.strip_prefix("fold along ") {
None => Err(Oopsie::BadFold(s.to_string())),
Some(line) => {
if let Some(num) = line.strip_prefix("x=") {
return Ok(Fold::AlongX(usize::from_str(num)?));
}
if let Some(num) = line.strip_prefix("y=") {
return Ok(Fold::AlongY(usize::from_str(num)?));
}
Err(Oopsie::BadFold(s.to_string()))
}
}
}
}
fn parse_file(contents: &str) -> Result<(Vec<Point>, Vec<Fold>), Oopsie> {
let mut reading_points = true;
let mut points = Vec::new();
let mut folds = Vec::new();
for line in contents.lines() {
if line.is_empty() {
reading_points = false;
continue;
}
if reading_points {
points.push(Point::from_str(line)?);
} else {
folds.push(Fold::from_str(line)?);
}
}
Ok((points, folds))
}
impl Point {
fn fold(&mut self, fold: &Fold) {
match fold {
Fold::AlongY(value) => {
if &self.y > value {
let difference = self.y - value;
self.y = value - difference;
}
}
Fold::AlongX(value) => {
if &self.x > value {
let difference = self.x - value;
self.x = value - difference;
}
}
}
}
}
fn fold(vec: &mut Vec<Point>, fold: &Fold) {
for point in vec.iter_mut() {
point.fold(fold);
}
vec.sort_unstable();
vec.dedup();
}
fn main() -> Result<(), Oopsie> {
let (mut test_points, test_folds) = parse_file(TEST_DATA)?;
fold(&mut test_points, &test_folds[0]);
println!("{} test points: {:?}", test_points.len(), test_points);
fold(&mut test_points, &test_folds[1]);
println!("{} test points: {:?}", test_points.len(), test_points);
let (mut real_points, real_folds) = parse_file(REAL_DATA)?;
fold(&mut real_points, &real_folds[0]);
println!("{} real points after first fold", real_points.len());
for instr in real_folds[1..].iter() {
fold(&mut real_points, instr);
}
let max_x = real_points.iter().map(|x| x.x).max().unwrap();
let max_y = real_points.iter().map(|x| x.y).max().unwrap();
for y in 0..=max_y {
for x in 0..=max_x {
if real_points.contains(&Point { x, y }) {
print!("#")
} else {
print!(" ")
}
}
println!()
}
Ok(())
}

183
src/bin/day14.rs Normal file
View File

@@ -0,0 +1,183 @@
use std::collections::HashMap;
use thiserror::Error;
const TEST_DATA: &str = include_str!("../../data/day14t.txt");
const REAL_DATA: &str = include_str!("../../data/day14a.txt");
#[derive(Debug, Error, PartialEq)]
enum Oopsie {
#[error("Bad transform declaration: {0}")]
BadTransform(String),
#[error("No data found?!")]
NoData,
}
struct Transform {
lead: char,
follow: char,
inject: char,
}
impl TryFrom<&str> for Transform {
type Error = Oopsie;
fn try_from(s: &str) -> Result<Self, Self::Error> {
match s.split_once(" -> ") {
None => Err(Oopsie::BadTransform(s.to_string())),
Some((from, to_str)) => Ok(Transform {
lead: from.chars().next().unwrap(),
follow: from.chars().nth(1).unwrap(),
inject: to_str.chars().next().unwrap(),
}),
}
}
}
fn read_file(contents: &str) -> Result<(String, Vec<Transform>), Oopsie> {
let mut lines = contents.lines();
let mut transforms = Vec::new();
let base_str = match lines.next() {
None => return Err(Oopsie::NoData),
Some(x) => x.to_string(),
};
for line in lines {
if line.is_empty() {
continue;
}
transforms.push(Transform::try_from(line)?);
}
Ok((base_str, transforms))
}
type Pair = (char, char);
type TransformDictionary = HashMap<Pair, [Pair; 2]>;
fn build_transform_dictionary(mut transforms: Vec<Transform>) -> TransformDictionary {
let mut result = HashMap::with_capacity(transforms.len());
for transform in transforms.drain(..) {
result.insert(
(transform.lead, transform.follow),
[
(transform.lead, transform.inject),
(transform.inject, transform.follow),
],
);
}
result
}
type State = HashMap<Pair, usize>;
macro_rules! insert_update {
($dict: expr, $key: expr, $value: expr, |$x: ident| $body: expr) => {
match $dict.get_mut(&$key) {
None => {
$dict.insert($key, $value);
}
Some($x) => *$x = $body,
}
};
}
fn build_initial_state(base: &str) -> State {
let mut state = HashMap::new();
let mut chars = base.chars().peekable();
while let Some(c1) = chars.next() {
match chars.peek() {
None => break,
Some(c2) => insert_update!(state, (c1, *c2), 1, |v| *v + 1),
}
}
state
}
fn step(base: &State, transforms: &TransformDictionary) -> State {
let mut result = HashMap::new();
for (pair, count) in base.iter() {
match transforms.get(pair) {
None => insert_update!(result, *pair, *count, |v| *v + count),
Some([p1, p2]) => {
insert_update!(result, *p1, *count, |v| *v + count);
insert_update!(result, *p2, *count, |v| *v + count);
}
}
}
result
}
fn steps(base: &State, steps: usize, transforms: &TransformDictionary) -> State {
let mut result = base.clone();
for i in 0..steps {
println!("At step {}, length is {}", i, result.len());
result = step(&result, transforms);
}
result
}
fn counts(polymer: &State) -> HashMap<char, usize> {
let mut char_counts = HashMap::new();
for ((c1, c2), count) in polymer.iter() {
insert_update!(char_counts, *c1, *count, |v| *v + count);
insert_update!(char_counts, *c2, *count, |v| *v + count);
}
char_counts
}
fn score(map: &HashMap<char, usize>) -> usize {
let high = map.values().max().unwrap();
let low = map.values().min().unwrap();
(high - low) / 2
}
fn main() -> Result<(), Oopsie> {
let (test_base, test_transforms) = read_file(TEST_DATA)?;
let (real_base, real_transforms) = read_file(REAL_DATA)?;
let test_initial = build_initial_state(&test_base);
let real_initial = build_initial_state(&real_base);
let test_transform_dict = build_transform_dictionary(test_transforms);
let real_transform_dict = build_transform_dictionary(real_transforms);
println!("test base: {:?}", test_initial);
println!("one step: {:?}", step(&test_initial, &test_transform_dict));
println!(
"four steps: {:?}",
steps(&test_initial, 4, &test_transform_dict)
);
println!(
"Length at 10 steps: {:?}",
steps(&test_initial, 10, &test_transform_dict).len()
);
println!(
"Counts at 10 steps: {:?}",
counts(&steps(&test_initial, 10, &test_transform_dict))
);
println!(
"Score at 10 steps: {:?}",
score(&counts(&steps(&test_initial, 10, &test_transform_dict)))
);
println!(
"Real score at 10 steps: {:?}",
score(&counts(&steps(&real_initial, 10, &real_transform_dict)))
);
println!(
"Real score at 40 steps: {:?}",
score(&counts(&steps(&real_initial, 40, &real_transform_dict)))
);
Ok(())
}

128
src/bin/day15.rs Normal file
View File

@@ -0,0 +1,128 @@
use pathfinding::directed::dijkstra::dijkstra;
use advent2021::map::{Graph, Oopsie};
const TEST_DATA: &str = include_str!("../../data/day15t.txt");
const REAL_DATA: &str = include_str!("../../data/day15a.txt");
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
struct Risk(usize);
impl TryFrom<char> for Risk {
type Error = Oopsie;
fn try_from(value: char) -> Result<Self, Self::Error> {
value
.to_digit(10)
.map(|x| Risk(x as usize))
.ok_or(Oopsie::BadCharacter(value))
}
}
impl Risk {
fn inc(&mut self) {
self.0 = if self.0 == 9 { 1 } else { self.0 + 1 };
}
}
#[derive(Clone, Debug)]
#[allow(dead_code)]
struct Path {
points: Vec<(usize, usize)>,
cost: usize,
}
fn shortest_path(graph: &Graph<Risk>) -> Path {
let target_x = graph.width - 1;
let target_y = graph.height - 1;
let result = dijkstra(
&(0, 0),
|(x, y)| {
graph
.neighbors(*x, *y)
.into_iter()
.map(|p| ((p.x, p.y), p.value.0))
},
|(x, y)| x == &target_x && y == &target_y,
);
if let Some((points, cost)) = result {
Path { points, cost }
} else {
panic!("Couldn't find a result.");
}
}
fn embiggen(graph: &Graph<Risk>) -> Graph<Risk> {
let region8 = graph.clone();
let mut region9 = region8.clone();
region9.points_mut().for_each(|x| x.value.inc());
let mut region1 = region9.clone();
region1.points_mut().for_each(|x| x.value.inc());
let mut region2 = region1.clone();
region2.points_mut().for_each(|x| x.value.inc());
let mut region3 = region2.clone();
region3.points_mut().for_each(|x| x.value.inc());
let mut region4 = region3.clone();
region4.points_mut().for_each(|x| x.value.inc());
let mut region5 = region4.clone();
region5.points_mut().for_each(|x| x.value.inc());
let mut region6 = region5.clone();
region6.points_mut().for_each(|x| x.value.inc());
let mut region7 = region6.clone();
region7.points_mut().for_each(|x| x.value.inc());
Graph::from_subgraphs(
5,
5,
&[
region8,
region9.clone(),
region1.clone(),
region2.clone(),
region3.clone(),
region9.clone(),
region1.clone(),
region2.clone(),
region3.clone(),
region4.clone(),
region1.clone(),
region2.clone(),
region3.clone(),
region4.clone(),
region5.clone(),
region2.clone(),
region3.clone(),
region4.clone(),
region5.clone(),
region6.clone(),
region3.clone(),
region4.clone(),
region5.clone(),
region6.clone(),
region7.clone(),
],
)
}
fn main() -> Result<(), Oopsie> {
let test_graph: Graph<Risk> = Graph::from_file_data(TEST_DATA)?;
let real_graph: Graph<Risk> = Graph::from_file_data(REAL_DATA)?;
println!("Test shortest path: {:?}", shortest_path(&test_graph));
println!("Real shortest path: {:?}", shortest_path(&real_graph));
let embiggened_test = embiggen(&test_graph);
println!(
"Larger test shortest path: {:?}",
shortest_path(&embiggened_test)
);
let embiggened_real = embiggen(&real_graph);
println!(
"Larger real shortest path: {:?}",
shortest_path(&embiggened_real)
);
Ok(())
}

View File

@@ -269,7 +269,7 @@ impl<'a> ProblemInput<'a> {
.map(build_local_iterator)
.multi_cartesian_product()
.map(|x| HashMap::from_iter(x.iter().cloned()))
.filter(|x| reasonable_assignments(x));
.filter(reasonable_assignments);
for assignments in possibles {
if self.assignments_validate(&assignments) {

View File

@@ -13,8 +13,18 @@ pub enum Oopsie {
pub struct Graph<T> {
data: Vec<T>,
width: usize,
height: usize,
pub width: usize,
pub height: usize,
}
impl<T: Clone> Clone for Graph<T> {
fn clone(&self) -> Self {
Graph {
data: self.data.clone(),
width: self.width,
height: self.height,
}
}
}
impl<T: TryFrom<char, Error = Oopsie>> Graph<T> {
@@ -59,6 +69,39 @@ impl<T: TryFrom<char, Error = Oopsie>> Graph<T> {
}
}
impl<T: Clone> Graph<T> {
pub fn from_subgraphs(num_wide: usize, num_high: usize, graphs: &[Graph<T>]) -> Graph<T> {
let inner_width = graphs[0].width;
let inner_height = graphs[0].height;
let width = num_wide * inner_width;
let height = num_high * inner_height;
let mut data = Vec::with_capacity(width * height);
for y in 0..height {
for x in 0..width {
let graph_x = x / inner_width;
let idx_x = x % inner_width;
let graph_y = y / inner_height;
let idx_y = y % inner_height;
data.push(
graphs[(graph_y * num_wide) + graph_x]
.get(idx_x, idx_y)
.unwrap()
.value
.clone(),
);
}
}
Graph {
data,
width,
height,
}
}
}
impl<T> Graph<T> {
pub fn size(&self) -> usize {
self.width * self.height