Compare commits

..

10 Commits

21 changed files with 2840 additions and 8 deletions

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

1
input/day09.txt Normal file

File diff suppressed because one or more lines are too long

52
input/day10.txt Normal file
View File

@@ -0,0 +1,52 @@
5678543238765121087216787432128921016563210454323433
4169654119654037892107894549017430457654782369412812
3018767001843246543210787678186543368945691078908903
2189678914980158934345698187098901275632100165001894
3434589125678767891016521096167872984789321874112765
7823678034569876780123434545252766543215476903233456
6910167012423495679654321032341057630306985012945101
5401986543410584508765678211352348921437894123876298
4323877892543673210104569300235496530890123434565387
3210967871652598789213075410145687432765210123432456
0101454960701659654322186703456710101854321076501201
1012343459898741023763099812769823478923212987655652
4323012321101232212854210129876012569012503234234743
5011001410765540101940110238787112876503414105109892
6722340543894691001233221045698108976434565696589321
9821059652023782317874536789587012885325676787678780
9778968701110678498965945893496543494018989801210690
8769878889231589567767893672109824323561234892309541
1454399998342490430850104589678012012370348763458032
0141287107654321521943213212565503123987659654567123
1230236256565410101237870101419654598543210508948910
2340145348978321253210965432308765687696501417654323
3986501567899010344789876323219454766787432321078890
5677432450987432455670189410012349845696501434569701
0548901321976501964563208231987210036723109621435652
1239678100823457877854010145676210129814918730898543
4310369234710165756905423210122305610905825623567678
3423456765600874543814554761201456723876734514410569
2102109894321984562323669854398556894985232305320438
3076521003965433871234778034567647895894101476761023
4585412312870122930129872129867634456783230585872310
5694303456781211123123401256798521065656187694965432
6783201019892100054076540346543438980521090123456501
0340112387653456963981639457832523671439876101219602
1258903490144327870190128768901214512112725614308712
2569876589231016983278787434980108903003014525456893
1876767676546781074349896523076587654394523496327854
0945778789035690165234765014123496543487621087018969
1239869876124789234105676543287017012567634589829678
9018756765453210785411085010196528921298565676543549
8723605034301305696532398923483437430143476589762138
7634514125212154387783437654589016521052187679854023
6501323896521093210598568943078723632367098512763210
7432454787436789765677678732189654045458963403892001
8901343474345658894389589823476902102167872354301123
7623676543216743001210438214567813458054961065689054
5012389012109812123309321301054324569123452876548765
4589438729001901014578010102344567078212556989231076
3676567438782342145665430230133898167901665476102989
2109652145699654398765421321212101237810174345603478
1078743034328765219876323478903894376521089298714565
2167634145410898701101210569816765489432100107623434

8
input/day10_example.txt Normal file
View File

@@ -0,0 +1,8 @@
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732

1
input/day11.txt Normal file
View File

@@ -0,0 +1 @@
6563348 67 395 0 6 4425 89567 739318

140
input/day12.txt Normal file
View File

@@ -0,0 +1,140 @@
AAAAAAMMMMMMMMMMMMMMMMMMCCCCCCCCACAYYYYYYYYYYYYYYYYWWJWWIIIIIIIIIIIIIIIIIIIIIFVFMMMMMMMMMYRRYRRRRRNXXNAANIIIIIEEEEEEEEEEEEEEERRRRRRRRQQQQQCQ
AAAAAAAAMSMMMMMMMMMMMMMMMCCCCCCCCCYYYYYYYYYYYYYYYYYWWWWWWWIIIIIIIIIIIIIIIIIIFFFFFFMMMMMMMYYRYRRNNNNNNNNNNNNNIEEEEEEEEEEEEEEERRRRRRRFQQQQQQQQ
AAAAAAAFSSSMMMMMMMMMMMMXMCCCCCCCCCUCYYYYYYYYYYYYYYYWWWWWWWWIIIIIIIIIIIIIIIIIFFFFFFFMMMMYYYYYYYYNNNNNNNNNNNNIIIIEEEEEEEEEEEEERRRRRRRQQQQQQQQQ
AAAAAASSSSSSMMMMMMMMMMMXXXCCCCCCCCCCYYYYYYYYYYYYYYYYWWWWWWWIIIIIIIIIIIIIIIIFFFFFFFIMMMYYYYYYYYNNNNNNNNNNNNNNIIIIIEEEEEEEEEEEERRRRRRQQQQQQQQQ
AAAAASSSSSSSSMMMMMMMMMXXXXXCCCCCCPCCYYYYYYYYYYYYYYYYWWWWWWWWIPPIIIIIIHHHIHIFFFFFFFIMMMYYYYYYYYNNNNNNNNNNNNNNNNNIEEEEEEEEEEEERRRRRRROQQQQQQQQ
AAASSSSSSSSSMMMMMMMMMXXXXXXCCCCCCPPYYYYYYYYYYYYYYYYWWWWWWWWWIPPIIIIIHHHHHHIFFFFIIXIIMMYYYYYYYYYYNNNNNNNNNNNNNNNNERREEEEEEEEWWRRRRRRQQQQQQQQQ
AAAVSSSSSSSMMMMMMMMMMMXXXXXCCCCCVCYYYYYYYYYYYYYYYYWWWWWWSWWWWPPIIIIHHHHHHHHHFFFIIIIIIIIIYYYYYYYYNNNHNNNNNNNNNNNNRREEEEEEEEEEERUROORQQQQQQQQB
AAAAKKSSSSSSMMMMMMMMMMXXOXCCCCCCCCYYYYYYYYYYYYYYWWWZWWWWWWWPPPPPIPHHHHHHHHHHFFFFIIIIIIIRYYYYYYYNNNNNNNNNNGNNNNRRRRREEEEEEEEEEEUUUUQQQQQQQQQQ
AAAKKKKKSSSSMMMQQQMMMXOOOOCCCCCCCCCYYYYZZYZYYYYYYZZZZWPWPPWPPPPPPPPHHHHHHHHFFFFFFIIIIIIIIYYYYYYYYYNUNNNNNGNNNNNRRREEEEEEEEEENEUUUUQQQQQUQXXX
AAAKKKDDQQQQQQQQQQQQMXOOOOOOOCCCCCSYYOOZZZZZYZYYZZZZZPPPPPPPPPPQQPHHHHHHHHHFFFFFFIIIIIIIIIIYYYYYYNNNNNNWWWNNNNNRRRRREEEEEEEGNNWUUUQQQUUUUUXX
HHHKKDDDDDQQQQQQSSSQSXOOOOOOCCCCCSSSYYOZZZZZZZYYZZZZPPPPPPPPPPQQQVEEEFHHHHHFFFFIIIIIIIIIIIYYYYYYYNYNNNNWWWNNNNNZRRRRREEENNNNNNNUUUUUUUUUUUUX
HHHHHDDDBDQQQQQQSSSSSOOOOOOOOOCCSSSSSZZZZZZZZZZZZZZZPPPPPPPPPPPQQQEEEEBHHHFFFFFFIIIIIIIIIIYYIYIYYYYYYYWWWWWWWNXZZZZZRREENNNNNNNNUUUUUUUUUUUU
HHDDDDDDDDQDQQQQQSSSSOOOOOOOOOOOOOZZZZZZZZZZZZZZZZZZZPPPPPPPPPPQQQQEEEHHHFFFFFFFIIIIIIIIIIIIIYIYYYYYYYYWWWWWWWZZZZZZZRRENNNNNNNNUUUUUUUUUUUU
HHDDDDDDDDDDQQQQSSSOOOOOOOOOOOOOOOTZZZZZZZZZZZZZZZZZZPPPPPPPPPQQQQQEEEEFFFFFFFFFIIIIIIIIIIIIIIIYYYYYYYYYWWWWWZZZZZZZZZCDDNNNNNNNUUUUUUUUUUUU
HHDDDDDDDDDQQQQQSSSSOSOOOOOOOOOOOOOZAZZZZZZZZZZZZZZZZZPPPPPPPPQQQQQQEEEEFFFFFFFFIIIIIIIIIIIIIIIYYYYYKKKKKKKWWZZZZZZZZTCDDDNNNNNNNUUUUUUUUUUU
HHHHKQQQQQDQQQQSSSSSSSSSOOOOOOOOOAOAAAZZZZLZZZLZZZZZZZPWPPWWPWWQQQQQEEEEFFFFFFFFIIIIIIIEWIITTTIYYYYYCCCKKKWWZZZZZZZZZTCCDNNNNNOUUUUUUUUUUUUU
HHHHKQQQQQQQQQQQSUSSSSUSOOOOOOOOOAAAAAZZZLLLLZLLLZZZZZPWWPWWWWWQQQQEEEEEFFFFFFEEECEEIIIEEEEEETTYTGYYYKCCKKWWWZZZZZZZZTCCNNNNNNOOUUUUUUUUUUUZ
HHHKKKQQQQQQQQQQQUSSSUUUOOOOOOUAAAAAAZZZZZLLLLLLLZZZWWWWWWWWWWWQQQQEEEEEEFFFFEEEEEEEEIEEEEEEETTTTGGGTKKKKKWWWWZZZZZZZCCCCCCCNNNUUUUUUUUUUUZZ
HKKKKQQKQQQHHQQQQUUUUUUOOOUOXUUUUAAAAAZZZZLLLLLLLZZWWWWWWWWWWWWWQQQEEEEEEFFFFEEEEEEEEIEEEEEETTTTTGGGTKKQKQQQQWZZZZZZZCCCCCCCNNNNUUUUUUUUUWZZ
KBKKKKQKQQQHHQQQUUUUUUUUUOUUUUUUAAAAAAAAAALLLLLLLZZWWWWWWWWWWWWWQQQEEEEEEFFFFEEEEEEEEEEEEEEEEEETGGGGQQQQQQQQWWWZZZZZFCCCCCCNNNNUUUUUUUUUWWWW
KKKKKKKKKQQHHHHQUUUUUUUUUUUUUUUUUUUUAAAALLLLLLLLLZZJWWWWWWWWMWWFFFFEEEEEEFFEFEEEEEEEEXEEEEEEETTTGTTGGQQQQQQQWWWWZZZZCCCCCCCNNNNUUUUUUUCUWWWW
KKKKKKKKQQKHHHHQQUUUUUUUUUUUUUUUUUUAAAAALLLLLLLLLLJJWLLWWWWWWWWFFFFEEVVVEEEEEEEEEEEEEEEEEEEEETTTTTTTGZQQQQQVQWWWWWECCCCCCCXXNNNXXUUUUUCUCWWW
KKKKKKKKKKKHHHHHHUUUUCCUUUUUUUUUUUUAAAAAAUUUULLLLLLJJWWWWWWWFFFFFFFVVVVEEEEEEEEEEEEEEEEEETTETTTTTTTTQQQQQQQQQXWWWCCCCCCCCXXXXXXXXUUUUUCCCCWW
KKKKKKKKKKKKHHHHHHUUUUCCCUUUUUUUUUUUAAAAAUUULLLLLLLLLCWWWWWCCCCCFFVVVVVVEVEEEEEEEEEEEEEEETTTTTTTQQQQQQQQQQQQQQQWWCCCCCCCCCXXXXXXXXUUUUTTTWWW
KKKKKKKKKKKKHHHHHHHHCCCCCCUUUUUUUUUUAAAAUUUUUUULLLLCCCCCCCCCCCCZZZVVVVVVVVVEEEEBEEEEEEEEEEETTTTTQQQQQQQQQQQQQQZWWZZCCCCCCCCCXXXXUUUUUTTTTWWT
KKKKKKKKKKKKHHHHHHHCCCCCCUUUUUUUUUTTTTAUUUUUUUULUULCCCCCCCCCCCCZZZVVVVVVVVVEEEEBBEEEEEEEEEEETTTTQQQQQQQQQQQQQQZWZZZZCCCCCCCVVVXUUUUUTTTTTTTT
KKKKKKKKKKKHHHHHHHHCCCCCCUUUUUTUTUTTTTTUUUUUUUUUUUQQQCCCCCCCCCZZZZVZVVVVVVVVVVEBBBEEEEEEEEETTXXQQQQQQQQQQQQQQZZZZZZZZZCCCCCVVVVUUUUUUTTTTTTT
KKKKKKKKKKKHHHHHHHHCCCCUUUUUTTTTTTTTTTTTTUUUUUUUUQQQQCCCCCCCCCZZZZZZVVVVVVVVVVVBBBBBBEEEEETTTXXXXXXQQQQQQQQQZZZZZZZZZZZCCVVVVVVVVUUUUTTTTTTT
KKKKKKKKGKHHHHHHHHHHZZCUUUUUTTTTTTTTTTTTUUUUUUUUQQQQQCCCOOOOOCZZZZZZVVVVVVVVVBBBBBBBBEEEEETXXXXXXXXQQQQQQQQQQZZZZZZZZDDDCVVVVVVVVVUUUTTTTTTT
KKKKKKKKKHHHHHHHHHCCCCCCUUUUTTTTTTTTTTTTUUUUUUUUQQQCCCCCOOOOOZZZZZZZZVVVVBVVVVBBBBBBBNENEETTXXXXXXQQQQQQQQQQZZZZZZZDZDDDDVVVVVVVUUUUUUUUTTTT
KKKKKKKKHHHHHHHHHHHBCCCBBBBUBTTTTTTTTTTTTUUUUUUUQQQQQCCCOOOOOZOOOOOOOZEEVVTBBBBBBBBBNNNNNTTTXXXXXXQQQQQQQQQQNZZQZZZDDDDDDVVVVVPVUUUUUUUTTTTT
KKKKKKEEHHHHHHHHHHBBBBBBBBBBBTTTTTTTTTTTUUUUUUUUQQQCCCCCOOOOOOOOOOOOOZEEUUBBBBBBBBBBNNNNTTTTTXXXXCQQQQKKQQQQZZZQZZZDDDDDDVVVVVPUUUUUUUUTTTTT
PPKKKKEEHHHHHHHHHHBIIBBBBBBBBTTTTTTTTTUTUUUUUUUUOOOOOOOOOOOOOOOOOOOOOOOEUBBBBBBBBBBBBNNTMTTTTXXXCCCCKGKKKKKKZZZZZZDDDDDDJVGGPPPPPPUUUUUUTTTT
HPPKEEEEHHHHHHHHIIBIIIIIBBBBBBTTTTTTTUUUUUUUUUUUOOOOOOOOOOOOOOOOOOOOOOOEBBBBBBBBBBBBBCCTTTTTTCCCCCCKKKKKKKKZHHHZZZDDDDDDPGGGPPPPPPUUUUUTTTTT
HPEEEEEEEHHHHHHHIIIIIIIIIBBBBBTTTTTUUBBBBUUUUUUUOOOOOOOOOOOOOOOOOOOOOOOYYBBBBBBBBBBBBBCTCCCCCCCCCCCKKKKKKKKKHHHZZZDDDOOPPPPPPPPPPPUUUTTTTTTT
SSSEEEEEEHHHHHHHIIIIIIIIBBBBBBTTTTTUUUBBBUUUUUUUOOOOOOOOOOOOOOOOOOOOOOODDBBBBBBBBBVVBCCCCCCCCCCCCCCKHHHHKKKZHHHZZEOOOOOOOPPPPPPPPUUUUTTTTTTT
SSSEEEEEEEEHHIIIIIIIIIIIIIIIIBBBTBTUBUBBBUUUUUUUOOOOOOOOOOOOONNZZZOOOOODQBBBBBBBBBVVKVVVVCCCCCCCCCCCHHHHKKKKHHHTZZOOOOOOOMMMPBPPPUAAATTTTTTT
SSSSSSSEEEEEIIIIIIIIIIIIIIIIBBBBBBBBBBBBBHHHHHHHOOOOOOOOOOCNNNNNZZOOOOODDDBBBBBBBVVVVVVVVCCCCCCCCCCKHHHHKKKKHHHHHHHHHHHOMMMPPPPAPQQQQTTTTTTT
SSSOSSSSEEEIIIIIIIIIIIIIIISIBSSBBBBBBBBSSSHHHHHHOOOOOOOOOOCNNNNNNNZVDDDDDDDABBBBBAVVVVVVCCCCCCCCCCCCHHHHKKKKHHHHHHHHHHHMMMMMPPAAPQQQZZZZZZZZ
SSSSSSVVEEEIIIIIIIDIIIIIISSSSSSSBBBBBBBBHHHHHHHHOOOOOOOOOONNNNNNNNZVVDDDDDDABBBBBBUUVVVVVVCCCCCCCCCKHHHHKKKHHHHHHHHHHHHMMMMMPAAAAQQQZZZZZZZZ
SSSSESEEEEEEIIIIDDDIIICICCSSSSSMMSBBBSFHHHHHHHHHOOOOOOOOOONNNNVVVVVVDDDDDDDDBBBBBBUUVVVVVVCCCCCCCCCKHHHHKKKHHHHHHHHHHHHMMMMMAAAAAQQQZZZZZZZZ
SSSEEEEEEEMMIDDDDDDDDDCCCSSSSSSSSSSSSSFHHHHHHHHHOOOOOOOOOOKKVVVVVVVVVDDTTTTYBBUUUUUUVVVVVVCVCCCCKKKKHHHHKKKHHHHHHHHHMMMDDDDAAAAAAQQQZZZZZZZZ
SSEEEEEEEMMDDDDDDDDDDDCCCSSSSSSSSSSSSSSHHHHHHHHHHHHHHHDDEEKVVVVVVVVVVDTTTTTYYBUUUUUUUVVVVVVVVCCKKKKKHHHHKKKHHHHHHHHHMMMDDDDDDAAAAQZZZZZZZZZZ
SSEEEEEEEEMDDDDDDDDDDDDDDSSSSSSSSSSSSSHHHHHHHBHHHHHHHHFEEEKVVVVVVVVVDDKKTTTYEUUUUUEEEEVEEEVCCCCCCKKRHHHHHHHHHHHHHHHHDDDDDDDDDDDAAZZZZZZZZZZZ
EEEEEEEEEEMDDDDDDDDDDDDDSSSSSSSSSSSSSSSSHHHHHHHHHHHHHHWWWWWWWVVVVVVVVKKTTTPEEEEUEEEEEEEEECCCCCCCCCCCHHHHHHHHHHTTTTBDZDDDDDDDDDRAAZZZZZZZZZZZ
CCEEEEZEEMMMMMMDDDDDDDDRSSSSSSSSSSSSSSSSSRHHHHHHHHHHFFWWWWWWWVVVVVVVVVKKTTEEEEEEEEEEEEEEEVCDDCCCCCCCRRHHHHHHHHTTTTTDDDDDDDDDDRRAAZZZZZZZZZZZ
CCECCEZZMMMMCMDDDDDDDDDRRRWSSSSSSSSPSSDSDDHHHHHHHHHHQQWWWWWWWWWWVVVVPTTTTTEEEEEEEEEEEEEEEVVDDCCCCCCCCRHHHHHHHHTTTTDDDDDDDDDZZZZZZZZZZZZZZZWW
CCCCCCMMMMCCCDDDDDDDDDJJJWWWWSSSSSSSSSDDDDHHHIIHHHHHQFWWWWWWWWWWVVVVVVTTTTTEEEEEEEEEEEEUEDDDDDDCCCCMXXHHHHHHHHTTTTDDDDDDDDDZZZZZZZZZZZZZZZWW
CCCCCCMMMMZCCDDDDDDDDUJJJWWWWSSSSSSSSDDDDHHHYDIIHIFFFFWWWWWWWWWWVVVVMTTTTTTTEEEEEEEEEEEEEDDDDCCCCCXXXXHHHHHHHHTTTTTDDDDDDDDZZZZZZZZZZZZKKWWW
CCZZZZDDDDZCCDDDDDDDDDJJJWXWWWSSSSSSSDDDDDHDDDIIIIIFCFWWWWWWWWWWVVVVMTTTTTTTEEEEEEEEEEEEZDDDDCCCXXXXXXHHHHHHHHTTTTTDDDDDDDDZZZZZZZZZZZZKKKWW
ZZZZZZZDDZZCDDDDDDDDDUJJJWWWWLSSSSSHDDDDDDDDDDDDIIFFFFWWWWWWWVVVVVVVVTTTTTTTTEEEEEEEEEEEZDDDDDXXXXXXXXHHHHHHHHTTTTTTDDDDDDDZZZZZZZZZZZZKKKKK
ZZZZZZZZZZZCDDDDDDDPMMJJJWOOLLBLSSSSDDDDDDDDDDDDDFFFFFWWWWWWWVVVVVVVHHTHTTTTTEEEEEEEEEEDDDDLLLLXXXXXXXXXXXXZXXTTTTTDDDDDDDDZZZZZZZZZZZZKKKKK
ZZZZZZZZZZZBBDDDDDDMMMJJJHLLLLLLLLSDDDDDDDDDDDDDDFFFFFFLWWWWAVVVVVAAAHHHHTTTTEEEEEEEEELDDDDLLLLLXXXXXXXXXXXXXTTTTTTTDDDDDDDZZZZZZZZZZZZKKKKK
ZZZZZZZZZZRRRDDDDDCMMMMMMLLLLLLLLLLDDDDDDDDDDDDDDFQFIFLLWWWWAVAVAAAAAHHHHHTTTEEEEEEEEELLLLLLLLLLLXXXXXXXNXXXXTTTTTTTDDDDDDDZZZZZZZZKKKKKKKKK
ZZZZZZZZZZZRRRRDDDCMMMMMMLLLLLLLLLLLDDDDDDDDDDDDCCCQAAAAWWWWWWWWAAAAAAAAHTTTTTEEEEEEEELLLLLLLLLLXXXXXXXXNXXXTTTTTTTTDTDDDDQQQZZZZZZKKKKKKKKM
JJJJJZZZZZRRRRRRMMMMMMMMMMELLLLLLLLLLLDDDDDDDDWWWWWWWWAAAWWWWWWWAAAAAAAAHHHHCTCEEGEEEEOLLLLLLLLLXXXXXXXXXTTTTTTTTTTTTTTQQQQQQZZZZZZKKKKKKKKM
JJJJJZZJZZRRRRRRMMMMMMMAAEELLLLLLLLLLDDDDDDDDDWWWWWWWWAAAWWWWWWWAAOAAAAAHHHHCCCGGGGGEEOLLLLLLLLLLLXXXXFXXAKTTATTTTTTTTTQQQQQQZZZZZZKMKKKMKKM
JJJJJJJJVRRRRRRMMMMMMMMMAALLLLLLLLLLLLLDDDDFCCWWWWWWWWAAAWWWWWWWAOOOOAAOHHHHCCCGCGCCCCCLLLLLLLLLLLXXXXXXAAAAAAAAAATTTTTTQQQQQQQQMKMMMMMKMMMM
XJJJJJJVVVRRRRRRMMMMMMMMAALLLLLLLLLLLLLDDDCCCCWWWWWWWWWWWWWWWWWWOOOOOOOOHHHHCCCCCCCCCCLLLLLLLLLLLLAAXXXXAAAAAAACAATTTTTQQQQQQQQQMMMMMMMMMMMM
XXXXJJVVVVRRRRRMMMMMMMAMAAALLLLLLLLLLLLWDDDCCCWWWWWWWWWWWWWWWWWWOOOOOOOHHCHHCCCCCCCCCCCLLLLLLLLAAAAAAAAAAAAAAAAAAATTTTTQQQQQQMQMMMMMMMMMMMMM
XXXJJVVVVVVVRRRMMMMMMMAAAAAAAALLLSLLLLWWDDRCCCWWWWWWWWWWWWWWWWWWOOOOOOOHHCCCCCCCCCCCCCCCLLLLLLLAAAAAAAAAAAAAAAAAAATTTTTQQQQQQMMMMMMMMMMMMMMM
XXXXXVVVVVVVVVVVRVVMMAAAAAAAALLLLSLLLLLLLQCCCCWWWWWWWWWWWWWWWWWWOOOOOGOOCCCCCCCCCCCCCMMLLLLLLAAAAAAAAAAAAAAAAAAAAAAAATVQQQQQMMMMMMMMMMMMMMMM
XXXXXVVVVVVVVVVVVVVMAAAAAAAAAASSLSLLLLLLQQXCCCWWWWWWWWWWWWWWWWWWOOOOOOOOOOCCCCCCCCCCCCLLLLLLGAAAAAAAAAAAAAAAAAAAAAAAAVVVQQVMMVVMMMMMMMMMYYMM
XXXXXVVVVVVVVVVVVVVMAAAAAAAAAAASSSFFFFLLQQQQHCWWWWWWWWWWWWWWWWWWFFFFFFFFOOOCCCCCCCCCCCXLLXXXAAAAAAAAAAAAAAAAAAAAAAAAAVVVQVVVVVVMMMMMMMMMYYYM
XXXXXXXVVVVVVVVVVVVVOOAAAAAAASSSSSFFNNLSQQQQQCWWWWWWWWWWWWWWWWWWFFFFFFFFOOVCCCCCCCCCCXXXXXXXXAAAAAAAAAAAAAAAAAAAAVVACIVVQVVVVVVVVMMVMWWYYYYM
XXXXXXXVVVVVVVVVVVVOOOAAAAAAASSSSSSFNNNNNQQQQQQQQQQWWWWWWWWWWWWWFFFFFFFFOOVCCCCCCCCCCXXXLLXXXAAAAAAAAAAAAAAAAAADCVCCCVVVVVVVVVVVVVVVMWWWYMMM
XXXXXXVVVVVVVVVVVVVVOOAAAAAASSSSSSSSNNNNLLQQQQQQQQQQQQFFFWWWWWWWFFFFFFFFVOVCCCCCCCCXXXXLLLLXXAAAAAAAAAAAAAAAADDDCCCCVVVVVVVVVVVVVVVVVWWWWMMM
XXXXXXVVVVVNNVZVXXXXXXRRRAAAISSSSSSSSNNNNNQHNQQQQQQQQQQQQQQFFAFFFFFFFFFFVVVVCCCCCCCXXXXLLLLLLLKKAAAAAAXAAAAAADDDCCCCVVVVVVVVVVVVVVVVEEWWWWMM
XXXXXXTTVVVVVTXXXXXXXXXXRRRASSSSSSSSSSNNNNNNNQQQQQQQQQQQQQQQQQFFFFFFFFFFVVVVCVCCCCXXJJJLLLLFWKKWWWAAAXXXAAAADDCCCCCCCCVCVVVVVVVVVVVVEWWWWWWM
XXXXXXTTTTTTTTXXXXXXXXXRRRRRRRSSSSNNNNNNNUNNNNQQQQQQQQQQQQQQQHFFFFFFFFFFVVVVVVVVCCCXJJJJJLLFWWWWWWAAXXXXXXAAADCCCCCCCCCCVVVVVVVVVVVVEXWWWWWW
XXXXXTTTTTTTTTXXXXXXXXXRRRRRRRSSSSNNNNNNNNNNNJQQQQQQQQQQQQQQHHFFFFFFFFFFFFFFTVTVVCJJJJJJJJJFWWWWWAAJXXXXXXXACCCCCCCCCCCVVVVVVVVVVVVVVXXWWWWW
YXXXTTTTTTTTTTTXXXXXWXRRRRRRRSSSNSNNNNNNNNNNNJJJQQQQQQQQZQQQQQFFFFFFFFFFFFFFTTTTVVVJVJJJJJJWWWWWWWAWXXXXXXXUUUCCCCCCCCCVUVVVVVVVVVVXXXWWWWWW
YXXXTTTTTTTPTTTXXXXXXRRRRRRRRRNNNNNNNNNNNNNVVVJVVVQQQQQQQQQQVQFFFFFFFFFFFFFFTTTTVVVVVVJJJJJJWWWWWWWWWXXXXXUUUUUCCCCCCCCVVVVVVGVOVXXXXXXXWWWW
YXTTTTPPPTPPPPXXXXXXXRRRRRRRRRRNNNNNNNQNNNYVVVJVVVVVQQQQQQQQQQHHWWWWWBFFFFFFTTTTVBBBVJJJJPJWWWWWWWWWWXXXXXXXUUUWCCCCCCCCVCCVGGVOXXXXXXXXWWWW
YTTTTTPPPPPPPPNXUXXXXRRRRRRRRRRNNNNQQQQNNVVVVVVVVVQQQQQQQQQQQQHWWFFFFFFFFFFFTTTBVVBBBOOJJJWWWWWWWWWXXXXXXXXHUUWWWCCCCCCCCCCCGGVOXXXXXXXXXGGG
YTTTTTPPPPPPPPPXUUXXXPRRRRRRRRRNNNNQQQQQVVVVVVVVVVQQQQQQQQQQQQHRRFFFFFFFFFFFBBBBBBBBOOWWWWWWWWWWWWWWWWWXXXXXUUWPBCCCCCCCCCCCGGGVXVXXXXXGGGGG
TTTTTTPPPPPPPPPXUUXXXPPPPRRRRRRQQFNNQQQQQVVVVVVVVVQQQQQQQQQQQQQQWFFFFFFFFFGGBBBBBBBOOOOWWWWWWWWWWWWWWWWWXXXPPPPPBCCCCCCCCCCCGGVVVVXXXXXGGGGG
MTTTTTTPPPPPPUUUUUPXPPPPPRRRRRRQQQQQQQQQQQVVVVVVVDQQQQQQQQQQQQQAAFFFFFFFFFGGGBBBBBBWWWWWWWWWWWWWWWWWWWWWTTTBBPPBBBCCCCCLCCCCGVVVVUXXXGGGGGGG
MMTTTTTPYPPPPUUUUUPPPPPPPPRRRRQQQQQQQQQQQQVVVVVDDDQRQQGPPAAAAAQAAFFFFFFFFFBGBBBBBBWWWWWWWWWWWWWWWWWWWWWWTTUUBBBBBBCCCBBBCCCCCVVVUUGGGGGGGGGG
MTTTTTTPYPPPPUUUUPPPPPPPPPPPRRQQQQQQQQQQQQQVJVVPPPRRQGGPPAAAAQQAAFFFFFFFFFBBBBBEUBBWWWWWWWWWWWWWWUUUWWUTTTUJBBBBBBBBBBBBBBDCVVVUUUUUUGUUUQQG
MTTTTTTPPPPPUUUUPPPPOOPRPPRRRRRQQQQQQQQQQQQQQQPPPPRRQQGPPPPPAAAAAAAAAAAAABBBBEEEUBWWWWWWWWWWWEWEWUUUWUUUUTUUUUBBBBBBBBBBBBBIVVVVUUUUUUUUUQQQ
RRRTTTPPPPPPPUUUUUPPPOPRRRRRRRJQQQQQQQQQQQQQPPPPPPRRRGGGPPPAAAAAAAAAAAAAAEBBCEEEUEEEFWWRRRWRREEEEBUUUUUUUUUUUUBBBBBBBBBBBBBBVVVUUUUUUUUUEQQS
ZZRTZZPPPZZZUUUZUUPOOORRRRJRRJJQQQUQQQQQQQQQQQPPPPPPPPGGPPPAPAAAAAAAWAXAAAAAAEEEEEEUBWWWWRRRREEEEBUUUUUUUUUPUUBBBBBBBBBBBBBBVVVUUUUUUUUUUQQS
ZZRTZPPPZZMZUUZZZZPEORRRRRJJRJJQQQUUQQQQQXQQQQPPXXXXPPPPPPPPPPAAAAAAWAAAAAAAAAEEEEEEBWWRRRRREEEEUUUUUUUUUUUUUUUBBBBBBBBBBBBBVVVUUYUUUUUUUQQQ
ZZZZZZZZZZZUUZZZZZEEEERJJJJJJJJJUUUUUQQXXXXQQQXXXXXXPPPPPPPPPPPPAAAAAAAAAAAAAAAEEEEEBBBBRRREEEEEUUUUUUUUUUUUUUUUBBBBBBBBBBBBVVVVUUUUUUUYYQQQ
ZZZZZZZZZZZZZZZZZZEZGEJJJJJJJJJJUJUUUUEXXXXXXXXXXXXXPXPPPPPPPAPAAAAAAAAAAAAAAAEEEEEEBBBEEEREEEEEUEUUUUUUUUUUUUUUBBBBBBBBBBBBVVUUUUUUUUUUYQQQ
ZZZZZZZZZZZZZZZZZZZZJJJJJJJJJJJJJJEUUUEEXXDDDDXXXXXXXXPPPPPPPAAAAAAAAAAAAAAAEEEEEEEEBBBEEEEEEEEEEEUUUUUUUUUUUUMUBBBBBBBBBBBBVVVVUUUUUUUUYQQQ
TZZZZZZZZZZBBBZZAAAAJJJJJJJJJJJJJEEEEEEXXDDDDDDDDXXTXTTPPPPPPPAAAAAAAAAAAAAAAEEEEEEEEBBBEEEEEEEEEEUUUUUUUUUUUUMBBBBBBBBBBBBBVVVVVUUUUUUUQQQQ
TZZZZZZZZZMMBBBZZAAALJJJJJJJJJJJJEEEEEEDXDDDDDDBBTTTTTBPPPPEPEEEAAAASAAAAAAAAEEEEEEEEBBEEEEEEEEEUUUUUUUUUUUUUUUBBBBBBBBBBBBBVVVVUUUUPUUZZZZZ
TTTZZZZZZZZBBZZZZAAAJJJJJJJJJJJJLLEEEEEDDDDDDDDBBBBTTCBCPPPEEEEEAASSSSQQAAAAAEEEEQEBBBBBBEEEEEEEUUUUUUUUUUUUUUUBBBBBBBBBBBBBZVWUUUUUUZZZZZZZ
TTTTZZZBBBLBBZZZAAAAAADJJJJJHHJJLEEEEEEDDDDDDDDDBBBBBCBCPPEEEEEEESSSSSSSGAAAAEEEEBBBBBBBBBBEEEEEUUUUUUUUUUUUSBBBBBBBBBBBBBBBUVUUUUUZZZZZRRZZ
TTBZZDBBBBBBBBBZDAAAADAJRRJJHHHHLHOHEDDDDDDDDDDBBBBBBCCCPPPEEEEEESSQSSSAAAAAWEEOBBBBBBBBBBBEEEEEUUUUUUUUUUUUSBBBBBBBBBBBBTTTUUUUUUUUZZZZZRZZ
TTBBBBBBBBBBBBWAAAAAAAAARRRHHHHHHHHHFDDDDDDHHDHHBBBBBCCYEEEEEEEEESSSHHHHAAAAWAOOBBBBBBBBBBEEEEEEUUUUUUUUUUUUSBBBBBBBBBBBTTTTUUUUUUUCUZUUURUZ
TTBBBBBBBBBBBBWAAAAAAAAARHHHHHHHHHHHFHDDDDHHHHHHHHHCCCCYEEEEEEEEEHSSHHHAAAHAAABBBBBBBBBBBEEEOOEEEEEQUUUUUUULSBBBBBBBBBBBTTTTTUUUUUUUUUBURRUU
TTTTBBBBBBBBBBBBOAAAAAAAAHHHHHHHHQQHHHHHHHHHHHHHHHHCCCCCCCCEEEEEHHHHHHHHAAHHHYBBBBBBBBBBXXXEXOEEEEEQUUUUUUUBBBBBBBBBBBBBTTTTTUUUUUUUUUUUUUUU
TTTBBBBBBBBBBBBBBAAAAAAAAHHHHHHHHHQHHHHHHHHHHHHHHHHICCCCCHHEHHEEHHHHHHHHHAVVVVVVVVVBBBBBBXXXXXXEEVVHHHHLLLLBBBBBTTTTTTTTTTTUUUUUUUUUUUUUUUUU
TQHHBBBBBBBBBBBBBAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHBBVCCCCCCHHHHHHHHHHHIHHHHHVVVVVVVVVBBBBBXXXXXXXXVVHHHHHLLLLBBBBBTTTTTTTTTTTTUUUUUUUUUUUUUUUU
TQQHBBBBBBBBBBBBBAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHBCCCCCCCCCHHHHHHHHHHHHHHHHVVVVVVVVVBBBBBXXXXXXXXVVHHHHLLLLLBBBBBTTTTTTTTTTTTTTUUUUUUUUUUUUUU
QQQHHBBBBBBBBBBBVAAAAAHAAAHHHHHHHHHHHHHHHHHHHHHHBCCCCCCCCEEHHHHHHHHHHHHVVVVVVVVVVVVBBBBXXXXXXXXXVVVHELLLLLLBBBBBTTTTTTTTTTTTTTUUUUUUUUUUUUUU
QQQHHBBHBBBBBBBBVAAAYAHHHHHHHHHHHHHHHHHHHHHHHHHBBBCCCCCCCEEEEEEHHHHHHHHVVVVVVVVVVVVBBBBXXXXXXXXHVHHHHLLLLLLBBBBBBBTTCCCCTTTTTTTVVUUUUVUUUUEE
QQHHHHHHBHBBBBBBBKAOYAHHHHHHHHHHHHHTHHHHHHHHHSBBBBCCCBCCEEEEEEEHHHHHHHHVVVVVVVVVVVVBBVYXXXXXXXHHHCHHHLLLLLLLLBBBBBTTCCCCTTTTTTTTVVVVVVEUUEEE
QQHHHHHHHHBBBBBKKKOOYAHHHHHHHHIIIIHHHHHHHHHHHSBBBBVCAECCEEEEEDDDDHHHHHHVVVVVVVVVVVVBBYYXXYXXXXXHHHHHHHHLLLLLLBBBBBCCCCCCTTTTTTTTVVVVVVEEEEEE
QQHKKHHHHHHIBBKKKKOOYYHHHHHHHHIIIIHHHHHHHHHHHLBBBBBXEEEEEEEDDDDDHHHHHHHVVVVVVVVVVVVHYYYYYYXXXXHHHHHHHHHHHLLCCBBBBBCCCCCCCCCCCCCCCCVVTVVVVVEE
QQQHKHHHHHHHKKKKKOOOYYHHHHHHIIIIIICCCCCHHHHHLLBBBBTEEEEEEEEDDDDDHHHHHHHVVVVVVVVVVVVHYYYYYYYHHHHHHHHHHHYYLLLNCBBBBBCCCCCCCCCCCCCCCCVVVVVVVVEV
QQQHHHHHHHHHKKKKOOOOOHHIIIIIIIIIIIICCCCCCCLLLLLLLBTTELEEEEEDDDDDHDDHHHHVVVVVVVVVVVVRYYYYYYYHHHHHHHHHHHYYLLCCCBBBBBCCCCCCCCNNNNCCCCVVVVVVVVEV
QQQHHHHHHHHKKKKKKKKOOOOEIIIIIIIIIIITTCCCCLLLLLLLLLLTTEEEEDDDDDDDDDDHHHHHHHHHRVVVRRRRYYYYYYHHHHHHHHHHYYYYYYCCCBBBBBCCCCCCCCNNNNCCCCVVVVVVVVVV
QQHHHHHHHHHHHKKKKKOOOOEEIIIIIIIIIIITTTTTCCLLLLLLLLTTTTTTEDDDDDDDDDDHHHHBBBBRRVVVRRRRRYYYYYHYHHHHHHHHHHYYYYCCCCCCCCCCCCCCCCNNNNCCCCRVVVVVVVVV
QQQHHHHHHHHKKKKKKKOOOOIIIIIIIIIIIITTTTTCCCLLLLLLPLTTTTTTDDDDDDDDDDDDDBBBBBBBRVVVRRRRYYYYYYYYHHHHHHHHHHHYYYYCCCCCCCCCCCCCCCNNNNCCCCRRVRVVVVVV
QQQHHHHHHHKKKKKKKKOOOOVIIIIIIIIIIITTTCTCTLLLTTLLLLTTTTTTDDDDDDDDDDDDDBBBBBBBRVVVRXXYYYYYYYYYYYHHHHHHHHYYYYYCCCCCCCCCCCCCCCNNNNCCCCRRRRVVVVVV
QQQQQHHHHHKKFFKKKFOOFFFFIIIIIIIIIITTTCCCTLTTTTLLTTTTTTTTTTTDDDDDDNNDBBBBBBBBRVVVVVVYYYYYUUUUYYYYHHYYYYYYYYYYCZCCCCCCCCCCCCNNNNCCCCYYRRVVVVVV
QQQQQQHKHKKKFFFFFFXFFFFNDDIIIIIIIITTTCCCTTTTTTTTTTTTTQQTTTTDDDDDDNMMBBBBBBBBBVVVVVVVVVYYYUUUUYYYHYYYYYYYYYCYCCCCCCCYYCCCCCCCCCCCCCRRRRVVVVVV
QQQQQQQKKKKFFFFFFFFFFFFFFDDIIIIIITTTTTCCTTTTTTTTTTTTTQQTTTTDDMDMDDMMBTBTTTBTBVVVVVVVVVYYUUUUUYYYYYYYYYYYYCCCCJCCCCCYYYYHDDDDCCCCCCRRRRRVVVVV
QQQQQQQKKKFFFFFFFFFFFFFUFDDIIIIQQQTTTTCTTTTTTTTTTTTQQQTTTTQQMMMMMMMMMTBBTTBTTBVVVVVVVVYWUUUUUYYYYPYYYYYYCCCCCCCCCCCCYHHHHDDRRRRRRRRRRVVVVVVV
QQQQQQQQKQQQFFFFFFFFFFFFFDDIIIIQTTTDTDDTTTTTTTTTTTTQQQQQQQQMMMMMMMMTTTTTTTTTTBXVVVVVVVWWUUUUTPPPPPPPPPYCCCKCCCCCCCCCCCHHCRRRRRRRRRRRDVVVVVVV
QQQQQQQQQQQFFFFFFFFFFFFFFDDDIIIQQQTDDDDWTTTTTTTTTTTTQQQQQQQQMMMMMMMTTTTTTTTTVTXVVVVVVVWWUUUUUPPPPPZPPYYCCKKCCCCCCCCCCCCHCRRRRRRRRRRRRVVVVVZV
QQQQQQQQQRFFFFFFFFFFFFFFDDDIIIQQQQTDDWWWTUTTTTTVVVTTQQQQQQQQMMMMMMMTTTTTTTTTTTXXVVVVVVWWWWWUWWWPPPPPPPPKKKKKCCCCCCCCCCCCCURRRRRRRRRRRRVVVZZZ
QQQQQPQQOFFFFFFFFFFFFFDDDDDDNQNQQQDDDWWWWUTTTTVVVVVQQQQQQQMMMMMMMTTTTTTTTTTTTRXXXXWWWWWWWWWWWWPPPPPPPPKKKKKKCCCCCCCCCCCCCCRRRRRRRRRRRIZZZZII
QQQPPPQQOPFFFFFFFFFFEEDDDDDDNNNNQQQQQWWWWUUTTTZVVVVVQQQQQQMMMMMMMMTKTTTTTTTTXXXXXXLWWWWWWWWWWWPPPPPPPPKKKKKCCCCCCCCCCCCCCXXRRRRRRRRRRIIIZIII
QQQQPPPPPPFFFFFFFFFEEEEEEDDDDNNQQQQQQWWWUUUTTVVVVVVRRGQQQMMMMMMMMMMKTTWTTTTTCXXXXXWWWWWWWWWWWPPPPPPPPKKKKKCCCNNCCCCCCCCCCCRRVRRRRRRHHIIIIIII
QQQPPPPPPPFFFFFFFFEEEEEEEDDNNNNQQQQQWWWWWWUTUUVVVVVRRRRMMMMMMMMMMMMTTTWTTTTTTTXXXXWWWWWWWWWWPPPPPPPPKKKKKKCCCCCCCCCCCCCCCKKMMMRRRRRIIIIIIIII
QQQPPPPPPPWFFFFFFFFFEEEEEDDDNNNQQQWWWWWWWUUUUUUVVVVRRRRMXMMMMMMMMMMMWWWWWTTTTTXXXWWWWWWWWWWWWWPPPPPPKKKKKCCCCCCDCCCCCCKCCKMMMMRRRMRRIIIIIIII
MMMPPPPPPPPHHHFFFFFFEEEGEDDDNNNNQQWYWWWWUUUUUUUVVVVRRRRRMMMMMMMMMMMMMWWWTTTTTTXDTTWWWWWWWWWWWWWWWKKKKKKKKCCCCCCCCCCCCCCCKKKMMMMMMMMMIMMMIIII
MMPPPPPPPPPHHHHFFFFEEEEEEDDDNNNQQQQWWWWWUDDDUUVVFFVRRRRRMMMMMMMMMMMMMWWWWTTTTTTTTTTWWWWWWWWWWWWAWAAKAAKKCCCCCCCCCCCCCCCKKKKMKKMMMMMMMMMMMIII
MMMMPPPPPPPPHHHEEELLEEEEDDDDNNNQJJQQQWWWDDDDUUVVEEERRRRRRMMMMMMMMMMMMWWWWWITVVTTTRRRRWWWWWWWWWWAAAAKAKKKKCCCCCCCCCCCCKKKKKKKKKMMMMMMMMMMEFII
MMMMMPPPPPEEHHEEEEEEMDEDDDDDDJJJJJQQWWWWDDDDDUVGEEERRRRRMMMMMMMMMMMMMWWWWWWTWWRRRRRRWWWWWWWWWWWAAAAAAKAKCCCCCCCCCCCCCKKKKKKKKMMMMWMMMMMMMFIF
MMMMMMMPPPPEEHEEEEEEDDDDDDOJJJJJJJQWWWWTDTTDDDTEEEERRRWWMMMMMMMMMWWMWWWWWWWWWWRRRRRWWWWWWWNWWWWWAAAAAAAACCCCCCCCCCCCKKKKKKKKKMMMMWWWMMPPFFFF
KMMMMMMPPPEEEEEEEEEEEEEEDDDJJJJJJJJTTWTTTTTTTTTEEEEERRWWWWWWWWMWWWWWWWWWWWWWYYYRRRRWWWNNNNNNWWWWAAAAAAACCCCCCCCCCCCDDDDDKKKKKKMWMWWWMFFFFFFF
KKMMMMPPPPEEEEEEEEEEEEEESDSJJJJJJJJJTTTTTTTTTTTEEEEEBBWWWWWNNWWWWWWWWWWUUWWYYYYYRRRXXXNNNNNNAAAAAAAAARURCCCCCCCCDQDDDDDDDKKKKKWWWWWWTFFFFFFF
KKWWMWWPPPPLLEEEEEEEEEEESSSJJJJJJJJJTTTTTTTTTTTEEEEEEEANNSNNNWWWWWWWWWWWUIIYYYWYYRYEXXNNNNAAAAAAAARRRRRRCCCCCCCDDDDDDDDDDKKKKWWWWWWWTFFFFFFF
KKWWWWWPPPPLLLEEEEEEEEEESSSJJJJJJJJJJTTTXXXTTXXEEEEEECNNNNNNNNNWWWWWWWWUUIIYYYYYYYYXXXXXNNAAAAAAAAAARRRRCCCCCCDDKDMDDDDDDKKKKWDWWWWQFFFFFFFF
KKKWWWWPPPPLLLEEEEEEEEEESSSJJJJJJJJJJTJJXWWXTXXEEEEEECCNNNNNNNNNWWWWWWUUUUUYYYYYYYXXXXNNNNNAAAAAAAAARRRRRRCCCCKKKDDDDDDDDDKKWWWWWWWWFFFFFFFF
KKKKWKWLLLLLLLEEEEEEEEEESJJJJJJJJJJJJJJWXXWXXXXCEXWWNNNNNNNNNNNNNUUUWUUUUUUUYYYYYYYXXXNNNNAAAAAAAAAAARRRRRRCCKKKKDDDDDDDDKKKWWWWWWWWWWFFFFFF
KKKKKKKCLLLLLLEEEEAEEEEEEJJJJJJJJJJJJJJXXXXXXXXXDXXNNNNNNNNNNNNUUUUUUUUUUYYYYYYYYYYXXNNNNAAAAAAAAAIARRRRRNCCCKKKDDDDDDDDDFFFWWWWWWWWWFFFFFFF
KKKKKCCCLLLLLLEEEEEFEEEENJJJJJJJJJJJJJJXXXXXXXXXDXGGTTNNNNNNNNUUUUUUUUUUUUYYYYYYYYYYYNNNNNIIAAAAAAIAIRRRRNKCKKKKDDDDDDDDDDDFWWWWWWWWWFFFFFFF
KKKKKKKCLLLLLLEEEFFFEEEEJJJJJJJJJJJJJJXXXXXXXXXXXXGTTTTNNNNNNUUUUUUUUUUUUYYYYYYYYYYYKYNNNNNIIIAIIIIIIIRRRNKKKKKDDDDDDDDDDDDWWWWWWWWWLWFFFFFF
KKKKKPLLLLLFFFEFFFFFFFKKJJJJJJJJJJJJXXXXXXXXXXXXXXXTTTTTNNNNNNUUUUUUUUUUUUYYYYYYYYYYYYNNNIIIIIAIIIIIIIIIKKKKKKKDDDDDDDDDDDDWWWWWWBWWWWWWFFFF
KKKKKPPLLLLLFFFFFFFFFFJJJJJJAJJJJJJXXXXXXXXXXXXXXRXTTTTTTNNNNNNUUUUUUUUUUUUYYYYYYYYYYNNNNNIIIIIIIIIIIIIIKKKKKDDDDDDDDDDDDDWWWWWWWWWWFWFWFFFF
KKKKKPPLLLPLFFFFFFFFFFFJJJJJJJJJJJXXXXXXXXXXXXXXXRTTTTTNNNNNNUUUUUUUUUUUUUUYYYYYYYYYYNNNNNNIMMIIIIIIIIIIKKAAKDDDDDDDDDDDDDWWWWWWWWFFFFFFFFFF
PKPPPPPPPPPPPFFFFFFFJJFJJJJJJJJJXJXXXXXXXXXXXXXXRRTTTTTTNNNNNUUUUUUUUUUUUUUYYYYYYYYYNNNNNNNNMIIIIIIIIIAAAAAAADDBBDDDDDDDDDDDWWWWFFFFFFFFFFFF
PPPPPPPPPPPPPFFFFFFJJJJJJJJJJJJJXXXXXXXXXXXXXXXXRRRTNNNNNNNNNUUUUUUUUUUUUUUYYYYYYYYYNNNNNNMMMMIIIIIIIIIAAAAAAADBDDDDDDDDDDDDDWWFFFFFFFFFFFFF

4
input/day12_example1.txt Normal file
View File

@@ -0,0 +1,4 @@
AAAA
BBCD
BBCC
EEEC

5
input/day12_example2.txt Normal file
View File

@@ -0,0 +1,5 @@
OOOOO
OXOXO
OOOOO
OXOXO
OOOOO

10
input/day12_example3.txt Normal file
View File

@@ -0,0 +1,10 @@
RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE

1279
input/day13.txt Normal file

File diff suppressed because it is too large Load Diff

15
input/day13_example.txt Normal file
View File

@@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279

500
input/day14.txt Normal file
View File

@@ -0,0 +1,500 @@
p=58,57 v=-51,-38
p=26,92 v=-82,30
p=51,30 v=21,-47
p=29,38 v=37,60
p=29,23 v=59,-19
p=7,38 v=-61,12
p=83,51 v=58,-56
p=84,94 v=62,61
p=79,93 v=-95,-32
p=59,34 v=88,93
p=29,86 v=25,79
p=24,6 v=6,23
p=25,25 v=69,-47
p=76,102 v=-45,69
p=39,24 v=-79,19
p=16,46 v=45,-62
p=65,41 v=-47,-68
p=63,19 v=28,-88
p=53,61 v=51,12
p=72,37 v=-23,56
p=4,65 v=-35,80
p=96,89 v=65,41
p=76,71 v=83,-41
p=31,41 v=-8,-42
p=53,4 v=-38,-71
p=70,36 v=80,-68
p=14,37 v=-6,-78
p=29,88 v=53,2
p=39,15 v=-78,-96
p=100,63 v=63,84
p=37,23 v=71,93
p=19,99 v=-30,67
p=5,76 v=60,69
p=83,96 v=7,-26
p=84,78 v=32,49
p=59,29 v=70,73
p=56,27 v=27,97
p=17,6 v=16,-30
p=33,77 v=-67,73
p=36,60 v=-29,-95
p=66,7 v=3,-16
p=22,74 v=91,12
p=71,33 v=-98,6
p=44,93 v=30,-1
p=59,23 v=68,-75
p=98,33 v=11,-72
p=97,22 v=87,-74
p=78,81 v=53,24
p=80,54 v=-57,-36
p=63,25 v=54,16
p=5,85 v=-38,-71
p=83,37 v=84,82
p=93,15 v=-40,54
p=34,89 v=-76,98
p=54,19 v=4,-18
p=33,52 v=-34,72
p=90,74 v=9,51
p=21,12 v=44,83
p=42,43 v=72,41
p=16,85 v=-36,88
p=47,4 v=-52,-30
p=0,69 v=88,81
p=57,33 v=51,64
p=56,26 v=-71,94
p=63,34 v=-71,-78
p=74,100 v=-21,-61
p=69,88 v=58,77
p=46,60 v=-69,-30
p=62,44 v=26,-70
p=38,84 v=98,-75
p=93,26 v=-62,-4
p=71,82 v=42,-21
p=16,45 v=93,74
p=40,31 v=21,-76
p=12,42 v=-60,-68
p=73,35 v=-7,-14
p=19,42 v=-9,-72
p=48,79 v=-27,63
p=73,57 v=30,14
p=96,2 v=83,54
p=40,10 v=46,81
p=88,8 v=-92,-20
p=31,63 v=31,-51
p=29,9 v=-66,-2
p=8,53 v=12,39
p=33,21 v=19,-84
p=46,33 v=-30,6
p=20,35 v=-63,84
p=72,18 v=-20,23
p=82,89 v=7,-75
p=23,3 v=-87,34
p=77,91 v=-53,-80
p=36,4 v=-5,44
p=22,1 v=-55,-84
p=7,6 v=-49,-85
p=38,74 v=-5,53
p=19,87 v=-88,67
p=84,47 v=73,-15
p=36,67 v=22,-54
p=78,10 v=55,-24
p=55,51 v=-26,2
p=0,27 v=63,-76
p=85,11 v=-17,50
p=52,16 v=-47,42
p=0,14 v=47,69
p=82,8 v=7,87
p=13,92 v=86,-56
p=11,11 v=-70,87
p=89,74 v=80,-22
p=23,60 v=-11,37
p=0,67 v=-13,24
p=14,33 v=37,29
p=68,94 v=85,4
p=64,23 v=53,81
p=96,35 v=84,76
p=19,29 v=-45,56
p=72,19 v=-71,-90
p=9,36 v=90,-33
p=59,52 v=-20,80
p=50,100 v=76,85
p=78,57 v=54,-81
p=27,84 v=73,-48
p=81,65 v=-42,-7
p=55,76 v=15,-91
p=86,87 v=-92,-7
p=57,76 v=30,-3
p=28,15 v=81,79
p=58,96 v=3,36
p=52,69 v=76,-60
p=61,88 v=79,30
p=15,70 v=91,22
p=80,5 v=3,52
p=85,22 v=83,60
p=49,8 v=-28,-59
p=100,59 v=66,39
p=100,100 v=62,36
p=74,75 v=-72,59
p=20,34 v=93,-74
p=30,63 v=44,55
p=71,101 v=29,-92
p=57,59 v=77,-56
p=84,29 v=25,53
p=41,81 v=-33,-79
p=45,31 v=-2,39
p=11,89 v=83,-19
p=7,67 v=-52,-59
p=29,44 v=-6,78
p=48,7 v=-3,23
p=36,17 v=92,25
p=1,29 v=-88,-41
p=47,55 v=75,-56
p=10,64 v=-35,-91
p=5,82 v=-87,26
p=19,22 v=13,-82
p=43,55 v=-77,6
p=71,59 v=-95,78
p=49,45 v=-25,65
p=31,72 v=-82,-83
p=71,59 v=4,-25
p=88,2 v=54,-59
p=64,67 v=-28,92
p=68,75 v=-43,-11
p=34,66 v=-1,-87
p=28,63 v=50,-62
p=9,93 v=57,-67
p=58,57 v=-22,41
p=21,59 v=67,8
p=28,24 v=-53,-14
p=76,88 v=-19,65
p=96,97 v=35,-20
p=28,93 v=42,-73
p=39,70 v=-56,84
p=77,19 v=-66,52
p=68,31 v=1,52
p=99,23 v=-41,81
p=84,23 v=-27,60
p=26,59 v=59,67
p=96,83 v=-63,-98
p=67,65 v=-65,80
p=92,78 v=10,59
p=75,14 v=13,38
p=15,64 v=65,80
p=46,99 v=-53,63
p=12,15 v=-10,-80
p=55,11 v=-23,-43
p=33,99 v=-86,41
p=98,55 v=-77,-18
p=49,48 v=-45,21
p=100,9 v=-93,-12
p=60,87 v=-99,-9
p=55,101 v=-99,71
p=13,18 v=39,-88
p=33,88 v=-56,20
p=31,15 v=-27,-6
p=49,13 v=-82,-80
p=14,79 v=85,-26
p=22,74 v=-4,-44
p=97,8 v=83,38
p=51,4 v=-85,-10
p=34,46 v=56,24
p=14,64 v=-9,55
p=50,102 v=-55,36
p=34,77 v=72,-83
p=87,57 v=8,35
p=52,65 v=-49,-21
p=15,47 v=-36,-6
p=22,26 v=-83,91
p=27,38 v=65,2
p=78,29 v=-44,72
p=14,58 v=-77,-92
p=9,75 v=39,90
p=17,95 v=-86,36
p=88,53 v=-96,73
p=38,92 v=-8,20
p=48,96 v=26,61
p=80,82 v=84,-17
p=35,99 v=23,-53
p=93,58 v=90,-54
p=49,25 v=48,-32
p=65,30 v=73,-45
p=39,59 v=23,47
p=6,67 v=52,-48
p=59,26 v=-25,-78
p=23,3 v=-33,83
p=12,49 v=-12,-68
p=42,66 v=-79,55
p=52,94 v=76,1
p=28,33 v=21,-10
p=10,96 v=36,9
p=36,66 v=-51,47
p=40,32 v=71,62
p=94,71 v=36,-3
p=50,9 v=46,44
p=68,48 v=58,-54
p=12,87 v=53,40
p=52,92 v=-23,-92
p=13,68 v=90,82
p=18,58 v=66,12
p=72,89 v=5,1
p=37,77 v=-4,90
p=17,89 v=-55,10
p=47,30 v=-60,49
p=6,79 v=54,-15
p=89,46 v=-41,-25
p=95,65 v=-64,82
p=57,29 v=3,-80
p=79,51 v=76,-8
p=59,97 v=-48,-67
p=68,12 v=53,-20
p=1,27 v=-88,31
p=61,84 v=2,34
p=52,76 v=-51,-79
p=28,90 v=22,57
p=38,78 v=-52,55
p=81,52 v=78,-74
p=8,79 v=88,-13
p=52,94 v=-51,-38
p=39,12 v=-83,7
p=46,97 v=-20,7
p=28,23 v=94,-84
p=30,49 v=-31,4
p=50,92 v=99,54
p=1,32 v=76,55
p=44,12 v=-57,-95
p=67,60 v=78,-54
p=46,78 v=-99,84
p=48,74 v=34,56
p=19,39 v=26,-19
p=21,8 v=-84,17
p=80,74 v=95,-3
p=21,6 v=69,-28
p=35,98 v=-84,-61
p=87,62 v=-91,78
p=66,71 v=73,-34
p=42,24 v=44,95
p=89,22 v=-72,26
p=54,67 v=-97,-87
p=78,17 v=-77,87
p=92,63 v=91,-1
p=59,56 v=-36,92
p=11,50 v=-84,99
p=28,83 v=71,-42
p=80,48 v=-44,2
p=41,3 v=-5,89
p=84,71 v=-68,14
p=87,79 v=-41,65
p=7,101 v=68,-96
p=18,7 v=-84,77
p=51,70 v=74,-52
p=41,20 v=-68,-17
p=32,19 v=49,15
p=1,68 v=87,84
p=86,60 v=1,45
p=98,46 v=88,39
p=92,42 v=-95,78
p=93,86 v=-93,47
p=37,92 v=73,-19
p=100,42 v=-85,-14
p=33,84 v=-30,-69
p=32,49 v=1,38
p=51,12 v=-51,-88
p=96,49 v=44,77
p=49,54 v=-4,33
p=71,90 v=-48,-3
p=65,49 v=-43,-3
p=20,70 v=-85,86
p=18,95 v=40,-25
p=84,16 v=4,97
p=94,43 v=-94,60
p=54,22 v=24,-14
p=63,4 v=70,-77
p=88,68 v=42,48
p=60,1 v=-24,-94
p=33,83 v=97,-40
p=71,47 v=-17,-60
p=42,65 v=23,66
p=13,93 v=13,-57
p=14,91 v=67,-3
p=47,34 v=52,41
p=66,63 v=-10,57
p=64,19 v=27,-80
p=23,87 v=-58,67
p=50,49 v=24,-29
p=48,38 v=-76,-41
p=30,87 v=98,55
p=79,60 v=32,78
p=66,16 v=-98,-37
p=80,8 v=7,85
p=64,101 v=89,7
p=86,93 v=9,-44
p=14,81 v=92,57
p=32,39 v=-81,2
p=65,76 v=56,-21
p=5,102 v=-86,3
p=7,87 v=39,73
p=91,12 v=-42,-92
p=54,41 v=24,66
p=81,43 v=-45,70
p=29,72 v=20,-50
p=8,23 v=-58,93
p=89,62 v=30,74
p=17,18 v=-82,-4
p=27,92 v=69,7
p=68,10 v=5,48
p=72,19 v=-73,15
p=44,20 v=-51,-53
p=97,27 v=91,-53
p=60,72 v=37,-32
p=24,83 v=60,-84
p=82,64 v=-43,43
p=87,5 v=-42,17
p=62,17 v=52,-53
p=64,41 v=-82,98
p=35,44 v=17,-95
p=46,50 v=-76,-95
p=90,58 v=58,-33
p=76,22 v=-44,-86
p=3,90 v=-11,67
p=75,36 v=-69,-4
p=0,73 v=-38,28
p=80,58 v=-5,-47
p=49,41 v=73,-14
p=39,42 v=-54,70
p=67,45 v=-18,-23
p=43,29 v=-35,-91
p=74,70 v=-7,-21
p=81,20 v=-70,4
p=41,3 v=-4,-24
p=78,38 v=-43,-6
p=55,91 v=77,79
p=89,25 v=-67,56
p=36,11 v=-31,81
p=81,68 v=6,-54
p=19,64 v=13,-83
p=43,28 v=-47,53
p=27,38 v=94,37
p=4,23 v=88,-82
p=59,98 v=54,71
p=23,37 v=43,64
p=21,20 v=-80,-43
p=74,15 v=-49,50
p=26,99 v=78,-78
p=55,96 v=2,69
p=92,21 v=-95,-88
p=50,62 v=7,-61
p=82,38 v=89,-76
p=63,12 v=2,56
p=95,55 v=87,41
p=59,48 v=75,-68
p=82,92 v=58,-36
p=40,76 v=-55,-34
p=36,48 v=50,-19
p=5,71 v=32,76
p=55,39 v=50,-70
p=0,85 v=41,-79
p=52,48 v=-26,16
p=65,86 v=-47,-3
p=68,89 v=30,-88
p=7,4 v=10,15
p=57,71 v=80,10
p=75,0 v=32,9
p=18,95 v=-59,26
p=26,42 v=44,-29
p=52,17 v=-28,48
p=63,3 v=79,46
p=61,68 v=-75,-48
p=88,96 v=5,79
p=26,89 v=22,22
p=64,38 v=-24,62
p=44,24 v=24,-78
p=26,39 v=-66,-71
p=15,40 v=40,-33
p=85,35 v=-93,-70
p=8,19 v=-65,-72
p=40,44 v=-82,-47
p=63,80 v=28,20
p=45,75 v=-28,-79
p=24,72 v=-58,-71
p=96,99 v=-44,-65
p=91,84 v=54,-27
p=55,47 v=80,-13
p=50,35 v=87,-57
p=76,98 v=-99,-98
p=72,67 v=80,57
p=69,38 v=68,-55
p=50,30 v=46,64
p=2,67 v=92,-44
p=22,7 v=-78,45
p=74,12 v=52,13
p=11,74 v=1,76
p=55,55 v=-67,-55
p=38,63 v=42,62
p=90,85 v=-65,94
p=20,36 v=-8,68
p=50,57 v=-98,-83
p=32,69 v=-6,30
p=30,35 v=97,-74
p=4,81 v=95,-88
p=70,86 v=-47,94
p=99,72 v=33,-89
p=48,59 v=74,-93
p=95,98 v=-66,36
p=6,64 v=96,-14
p=88,19 v=85,-80
p=16,41 v=-35,-39
p=70,71 v=81,20
p=85,58 v=58,8
p=59,40 v=-78,-25
p=51,39 v=-25,35
p=99,52 v=42,38
p=91,18 v=74,-14
p=65,86 v=28,67
p=92,50 v=64,6
p=86,97 v=57,-32
p=87,17 v=59,-51
p=36,59 v=74,68
p=19,11 v=-88,7
p=38,88 v=72,90
p=38,45 v=-4,-62
p=59,78 v=-59,28
p=92,13 v=44,80
p=35,53 v=-28,-2
p=87,22 v=-68,-24
p=20,64 v=-20,-33
p=83,76 v=-68,55
p=89,61 v=60,-37
p=2,35 v=37,31
p=12,62 v=-14,-54
p=7,97 v=-10,-48
p=83,99 v=84,-26
p=74,0 v=-20,-26
p=34,10 v=-80,-84
p=14,1 v=60,-30
p=12,94 v=15,-38
p=36,46 v=22,-41
p=35,69 v=42,-43
p=16,96 v=41,1
p=8,24 v=-10,21
p=60,89 v=3,89
p=70,13 v=49,-28
p=9,49 v=-10,39
p=100,31 v=-64,93
p=57,44 v=-72,-30
p=29,25 v=96,-8
p=19,75 v=-34,-79
p=26,18 v=94,19
p=6,9 v=-61,-10
p=24,23 v=-33,-47
p=23,56 v=-71,25
p=3,23 v=12,60
p=73,14 v=32,81
p=15,41 v=-9,-37
p=36,63 v=-6,82
p=71,56 v=-21,-25
p=60,90 v=78,3
p=52,37 v=-4,-47
p=52,61 v=54,20
p=66,84 v=31,-35
p=35,8 v=46,-26
p=90,28 v=-17,-10

12
input/day14_example.txt Normal file
View File

@@ -0,0 +1,12 @@
p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3

108
src/day10.rs Normal file
View File

@@ -0,0 +1,108 @@
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
use crate::util::{Coord, Grid};
use itertools::Itertools;
use std::collections::HashSet;
pub struct Day10 {
map: Grid<u8>
}
impl Day10 {
pub fn create(input: String) -> Self {
Day10 {
map: Grid {
data: input.lines().join("").chars().map(|c| (c as u8) - b'0').collect(),
width: input.lines().next().map(|l| l.len()).unwrap_or(0),
default: Some(255)
}
}
}
fn calculate_score(&self, trailhead: Coord<usize>) -> usize {
// Since paths have an even, gradual, uphill slope, we can just go up in height and see what we can reach
let mut last_layer: HashSet<Coord<usize>> = HashSet::new();
last_layer.insert(trailhead);
for h in 1..10 {
let mut cur_layer = HashSet::new();
for pos in last_layer.clone() {
// Check which neighbors are height h
if self.map.get(pos.x + 1, pos.y) == &h { cur_layer.insert(Coord::new(pos.x + 1, pos.y)); };
if pos.x > 0 && self.map.get(pos.x - 1, pos.y) == &h { cur_layer.insert(Coord::new(pos.x - 1, pos.y)); };
if self.map.get(pos.x, pos.y + 1) == &h { cur_layer.insert(Coord::new(pos.x, pos.y + 1)); };
if pos.y > 0 && self.map.get(pos.x, pos.y - 1) == &h { cur_layer.insert(Coord::new(pos.x, pos.y - 1)); };
}
last_layer = cur_layer;
}
last_layer.len()
}
fn update_pos(&self, new_x: usize, new_y: usize, target_height: &u8, cur_paths_to_pos: usize, cur_layer: &mut HashSet<Coord<usize>>, paths_to_pos: &mut Grid<usize>) {
if self.map.get(new_x, new_y) == target_height {
cur_layer.insert(Coord::new(new_x, new_y));
paths_to_pos.set(new_x, new_y, paths_to_pos.get(new_x, new_y) + cur_paths_to_pos);
}
}
fn calculate_score_pt2(&self, trailhead: Coord<usize>) -> usize {
let mut last_layer: HashSet<Coord<usize>> = HashSet::new();
last_layer.insert(trailhead);
let mut paths_to_pos: Grid<usize> = Grid {
data: vec![0; self.map.data.len()],
width: self.map.width,
default: Some(0),
};
paths_to_pos.set(trailhead.x, trailhead.y, 1);
for h in 1..10 {
let mut cur_layer = HashSet::new();
for pos in last_layer.clone() {
let cur_paths_to_pos = paths_to_pos.get(pos.x, pos.y).to_owned();
self.update_pos(pos.x + 1, pos.y, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos);
if pos.x > 0 { self.update_pos(pos.x - 1, pos.y, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos); };
self.update_pos(pos.x, pos.y + 1, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos);
if pos.y > 0 { self.update_pos(pos.x, pos.y - 1, &h, cur_paths_to_pos, &mut cur_layer, &mut paths_to_pos); };
}
last_layer = cur_layer;
}
last_layer.iter().map(|l| paths_to_pos.get(l.x, l.y)).sum()
}
}
impl DaySolver for Day10 {
fn solve_part1(&mut self) -> String {
self.map.find_positions(&|d| d == &0)
.map(|c| self.calculate_score(c))
.sum::<usize>().to_string()
}
fn solve_part2(&mut self) -> String {
self.map.find_positions(&|d| d == &0)
.map(|c| self.calculate_score_pt2(c))
.sum::<usize>().to_string()
}
}
#[test]
fn test_part1() {
let mut day = Day10::create(read_file("input/day10_example.txt"));
assert_eq!("36", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day10::create(read_file("input/day10_example.txt"));
assert_eq!("81", day.solve_part2());
}

78
src/day11.rs Normal file
View File

@@ -0,0 +1,78 @@
use std::collections::HashMap;
use num::Integer;
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
pub struct Day11 {
pebbles: Vec<u64>
}
impl Day11 {
pub fn create(input: String) -> Self {
Day11 {
pebbles: input.split_whitespace().filter_map(|n| n.parse::<u64>().ok()).collect()
}
}
fn split_digits(n: u64) -> (u64, u64) {
let digits = n.ilog10() + 1;
assert!(digits.is_even());
let factor = 10u64.pow(digits / 2);
(n / factor, n % factor)
}
fn count_pebbles_after_blinks(pebble: u64, blinks: usize, cache: &mut HashMap<(u64, usize), u64>) -> u64 {
if blinks == 0 { return 1 };
let cache_key = (pebble, blinks);
if let Some(cached) = cache.get(&cache_key) {
return cached.to_owned();
}
let res = if pebble == 0 {
Self::count_pebbles_after_blinks(1, blinks - 1, cache)
} else if pebble.ilog10().is_odd() {
let (left, right) = Self::split_digits(pebble.to_owned());
Self::count_pebbles_after_blinks(left, blinks - 1, cache) + Self::count_pebbles_after_blinks(right, blinks - 1, cache)
} else {
Self::count_pebbles_after_blinks(pebble * 2024, blinks - 1, cache)
};
cache.insert(cache_key, res);
res
}
fn count_total_pebbles_after_blinks(pebbles: &[u64], blinks: usize) -> u64 {
pebbles.iter().map(|p| Self::count_pebbles_after_blinks(p.to_owned(), blinks, &mut HashMap::new())).sum::<u64>()
}
}
impl DaySolver for Day11 {
fn solve_part1(&mut self) -> String {
Self::count_total_pebbles_after_blinks(&self.pebbles.clone(), 25).to_string()
}
fn solve_part2(&mut self) -> String {
Self::count_total_pebbles_after_blinks(&self.pebbles.clone(), 75).to_string()
}
}
#[test]
fn test_part1_basic() {
assert_eq!(7, Day11::count_total_pebbles_after_blinks(&vec![0, 1, 10, 99, 999], 1));
}
#[test]
fn test_part1() {
let mut day = Day11::create("125 17".into());
assert_eq!("55312", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day11::create(read_file("input/day11_example.txt"));
assert_eq!("EXAMPLE_ANSWER", day.solve_part2());
}

189
src/day12.rs Normal file
View File

@@ -0,0 +1,189 @@
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
use crate::util::{Coord, Grid};
use itertools::Itertools;
use std::collections::HashSet;
pub struct Day12 {
garden: Grid<char>,
}
#[derive(Debug, PartialEq, Copy, Clone)]
enum Side {
N,
E,
S,
W,
}
const SIDES: [Side;4] = [Side::N, Side::E, Side::S, Side::W];
struct Fence {
side: Side,
pos: Coord<usize>,
}
struct Area {
patches: Vec<Coord<usize>>,
fences: Vec<Fence>
}
impl Day12 {
pub fn create(input: String) -> Self {
Day12 {
garden: Grid::parse(input, None),
}
}
fn calc_area(&self, start_x: usize, start_y: usize, visited: &mut Grid<bool>) -> Area {
let plant = self.garden.get(start_x, start_y);
let mut to_check = vec![Coord::new(start_x, start_y)];
visited.set(start_x, start_y, true);
let mut in_patch: HashSet<Coord<usize>> = HashSet::new();
in_patch.insert(Coord::new(start_x, start_y));
let mut fences = Vec::with_capacity(32);
while let Some(cur) = to_check.pop() {
for side in SIDES {
if let Some(f) = self.check_neighbor(visited, plant, &mut to_check, &mut in_patch, cur, side) { fences.push(f) }
}
}
Area {
patches: in_patch.into_iter().collect(),
fences
}
}
fn check_neighbor(
&self,
visited: &mut Grid<bool>,
plant: &char,
to_check: &mut Vec<Coord<usize>>,
in_patch: &mut HashSet<Coord<usize>>,
cur: Coord<usize>,
side: Side,
) -> Option<Fence> {
let neighbor = match side {
Side::N => cur.north(),
Side::E => cur.east(),
Side::S => cur.south(),
Side::W => cur.west()
};
if let Some(n) = neighbor {
if self.garden.in_bounds(n.x, n.y) && self.garden.get(n.x, n.y) == plant {
if !visited.get(n.x, n.y) {
to_check.push(n);
in_patch.insert(n);
visited.set(n.x, n.y, true);
}
return None;
}
}
Some(Fence { side, pos: cur })
}
fn calc_total_price(&self) -> usize {
let mut visited = Grid {
data: self.garden.data.iter().map(|_| false).collect(),
width: self.garden.width,
default: Some(true),
};
let mut sum = 0;
for y in 0..self.garden.height() {
for x in 0..self.garden.width {
if *visited.get(x, y) {
continue;
}
let area = self.calc_area(x, y, &mut visited);
sum += area.patches.len() * area.fences.len();
}
}
sum
}
fn count_side(fences: &Vec<Fence>, side: Side) -> usize {
let cur_side_fences = fences.iter()
.filter(|f| f.side == side)
.sorted_by(|a, b| {
match side {
Side::W | Side::E => a.pos.x.cmp(&b.pos.x).then(a.pos.y.cmp(&b.pos.y)),
Side::N | Side::S => a.pos.y.cmp(&b.pos.y).then(a.pos.x.cmp(&b.pos.x)),
}
});
let mut sides = 0;
let start_fence = Fence { side: side.to_owned(), pos: Coord::new(usize::MAX, usize::MAX) };
let mut last_fence = &start_fence;
for fence in cur_side_fences {
if !match side {
Side::W | Side::E => last_fence.pos.x == fence.pos.x && fence.pos.y == last_fence.pos.y + 1,
Side::N | Side::S => last_fence.pos.y == fence.pos.y && fence.pos.x == last_fence.pos.x + 1,
} {
sides += 1
}
last_fence = fence;
}
sides
}
fn calc_modern_total_price(&self) -> usize {
let mut visited = Grid {
data: self.garden.data.iter().map(|_| false).collect(),
width: self.garden.width,
default: Some(true),
};
let mut sum = 0;
for y in 0..self.garden.height() {
for x in 0..self.garden.width {
if *visited.get(x, y) {
continue;
}
let area = self.calc_area(x, y, &mut visited);
// Now we need to find full "sides"
let sides = SIDES.iter().map(|s| Self::count_side(&area.fences, s.to_owned())).sum::<usize>();
sum += area.patches.len() * sides
}
}
sum
}
}
impl DaySolver for Day12 {
fn solve_part1(&mut self) -> String {
self.calc_total_price().to_string()
}
fn solve_part2(&mut self) -> String {
self.calc_modern_total_price().to_string()
}
}
#[test]
fn test_part1_example1() {
let mut day = Day12::create(read_file("input/day12_example1.txt"));
assert_eq!("140", day.solve_part1());
}
#[test]
fn test_part1_example2() {
let mut day = Day12::create(read_file("input/day12_example2.txt"));
assert_eq!("772", day.solve_part1());
}
#[test]
fn test_part1_example3() {
let mut day = Day12::create(read_file("input/day12_example3.txt"));
assert_eq!("1930", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day12::create(read_file("input/day12_example1.txt"));
assert_eq!("80", day.solve_part2());
}

86
src/day13.rs Normal file
View File

@@ -0,0 +1,86 @@
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
use crate::util::Coord;
pub struct Day13 {
machines: Vec<ClawMachine>
}
#[derive(Copy, Clone, Debug)]
struct ClawMachine {
button_a: Coord<i64>,
button_b: Coord<i64>,
prize: Coord<i64>
}
impl ClawMachine {
fn find_cheapest_win(&self) -> Option<i64> {
// Turns out, this is a system of linear equations, and if there is an integer solution, it works out.
// For a system with 2 equations and two parameters like this, we can just use a standard solution:
//Determinant = (a₁b₂ - a₂b₁)
let determinant = self.button_a.x * self.button_b.y - self.button_a.y * self.button_b.x;
if (self.prize.x * self.button_b.y - self.prize.y * self.button_b.x) % determinant != 0 || (self.button_a.x * self.prize.y - self.button_a.y * self.prize.x) % determinant != 0 {
return None
}
let button_a_presses = (self.prize.x * self.button_b.y - self.prize.y * self.button_b.x) / determinant;
let button_b_presses = (self.button_a.x * self.prize.y - self.button_a.y * self.prize.x) / determinant;
// println!("button A={}, button B={}, det={}", button_a_presses, button_b_presses, determinant);
Some(button_a_presses * 3 + button_b_presses)
}
}
impl Day13 {
pub fn create(input: String) -> Self {
Day13 {
machines: input.split("\n\n")
.filter(|c| !c.is_empty())
.map(|c| {
let mut c_lines = c.split("\n");
let button_a = c_lines.next().unwrap()["Button A: X+".len()..].split_once(", ").map(|(x, y)| Coord::new(x.parse::<i64>().unwrap(), y[2..].parse::<i64>().unwrap())).unwrap();
let button_b = c_lines.next().unwrap()["Button B: X+".len()..].split_once(", ").map(|(x, y)| Coord::new(x.parse::<i64>().unwrap(), y[2..].parse::<i64>().unwrap())).unwrap();
let prize = c_lines.next().unwrap()["Prize: X=".len()..].split_once(", ").map(|(x, y)| Coord::new(x.parse::<i64>().unwrap(), y[2..].parse::<i64>().unwrap())).unwrap();
ClawMachine {
button_a, button_b, prize
}
})
.collect()
}
}
}
impl DaySolver for Day13 {
fn solve_part1(&mut self) -> String {
self.machines.iter()
.filter_map(|m| m.find_cheapest_win())
.sum::<i64>().to_string()
}
fn solve_part2(&mut self) -> String {
self.machines.iter()
.map(|m| ClawMachine {
button_a: m.button_a,
button_b: m.button_b,
prize: m.prize.add(&Coord::new(10000000000000, 10000000000000))
})
.filter_map(|m| m.find_cheapest_win())
.sum::<i64>().to_string()
}
}
#[test]
fn test_part1() {
let mut day = Day13::create(read_file("input/day13_example.txt"));
assert_eq!("480", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day13::create(read_file("input/day13_example.txt"));
assert_eq!("875318608908", day.solve_part2());
}

154
src/day14.rs Normal file
View File

@@ -0,0 +1,154 @@
use crate::day_solver::DaySolver;
#[cfg(test)]
use crate::util::read_file;
use crate::util::{Coord, Grid};
pub struct Day14 {
robots: Vec<Robot>
}
#[derive(Debug, Copy, Clone)]
struct Robot {
p: Coord<i32>,
v: Coord<i32>
}
impl Robot {
fn step(&mut self, w: i32, h: i32) {
self.p = self.p.add(&self.v);
if self.p.x >= w { self.p.x -= w; }
if self.p.x < 0 { self.p.x += w; }
if self.p.y >= h { self.p.y -= h; }
if self.p.y < 0 { self.p.y += h; }
}
}
impl Day14 {
pub fn create(input: String) -> Self {
return Day14 {
robots: input.lines()
.filter_map(|l| l[2..].split_once(" v="))
.map(|(p, v)| Robot {
p: p.split_once(",").map(|(x, y)| Coord::new(x.parse().unwrap(), y.parse().unwrap())).unwrap(),
v: v.split_once(",").map(|(x, y)| Coord::new(x.parse().unwrap(), y.parse().unwrap())).unwrap()
})
.collect()
}
}
#[allow(dead_code)]
fn print(&self, robots: &Vec<Robot>) {
let (w, h) = self.map_size();
let mut grid = Grid {
data: vec![0; (w*h).try_into().unwrap()],
width: w.try_into().unwrap(),
default: None
};
for r in robots {
let x = r.p.x.try_into().unwrap();
let y = r.p.y.try_into().unwrap();
grid.set(x, y, grid.get(x, y) + 1);
}
let print_grid = Grid {
data: grid.data.iter().map(|g| if g > &0 { '#' } else { ' ' } ).collect(),
width: grid.width,
default: None
};
print_grid.print();
}
fn map_size(&self) -> (i32, i32) {
// First we have to know if we're in the example case or the real case, which we guess by checking if any robots are outside a 11 by 7 area.
if self.robots.iter().any(|r| r.p.x > 11 || r.p.y > 7) {
(101, 103)
} else {
(11, 7)
}
}
fn variance(data: &[i32]) -> f64 {
let sum = data.iter().sum::<i32>();
let n = f64::from(data.len() as u32);
let mean = f64::from(sum) / n;
(data.iter().map(|x| (f64::from(*x) - mean).powi(2)).sum::<f64>() / (n - 1f64)).sqrt()
}
fn variance_f(data: &[f64]) -> f64 {
let sum = data.iter().sum::<f64>();
let n = f64::from(data.len() as u32);
let mean = sum / n;
(data.iter().map(|n| (f64::from(*n) - mean).powi(2)).sum::<f64>() / (n - 1f64)).sqrt()
}
}
impl DaySolver for Day14 {
fn solve_part1(&mut self) -> String {
let (w, h) = self.map_size();
let mut robots = self.robots.clone();
for _ in 0..100 {
for robot in &mut robots {
robot.step(w, h);
}
}
(robots.iter().filter(|r| r.p.x < w / 2 && r.p.y < h / 2).count() *
robots.iter().filter(|r| r.p.x > w / 2 && r.p.y < h / 2).count() *
robots.iter().filter(|r| r.p.x < w / 2 && r.p.y > h / 2).count() *
robots.iter().filter(|r| r.p.x > w / 2 && r.p.y > h / 2).count()).to_string()
}
fn solve_part2(&mut self) -> String {
let (w, h) = self.map_size();
let mut robots = self.robots.clone();
let mut x_variances = Vec::new();
let mut y_variances = Vec::new();
// We're gonna simulate the robots, and try to find anomalies in the variance in x and y positions.
for i in 1..10000 {
for robot in &mut robots {
robot.step(w, h);
}
let var_x = Self::variance(&robots.iter().map(|r| r.p.x).collect::<Vec<i32>>());
let var_y = Self::variance(&robots.iter().map(|r| r.p.y).collect::<Vec<i32>>());
// To find anomalies, we find the variance in the variance of X, and if the variance in this sample is more than 3 times the variance of the variance
// away from usual, we found the outlier!
let var_var_x = Self::variance_f(&x_variances);
let var_var_y = Self::variance_f(&y_variances);
x_variances.push(var_x);
y_variances.push(var_y);
// We assume
// println!("var: {}, {}", var_x, var_y);
if i > 1 && (var_x < x_variances[0] - 3f64 * var_var_x && var_y < y_variances[0] - 3f64 * var_var_y) {
// self.print(&robots);
return i.to_string();
}
}
panic!("Couldn't find easter egg");
}
}
#[test]
fn test_part1() {
let mut day = Day14::create(read_file("input/day14_example.txt"));
assert_eq!("12", day.solve_part1());
}

View File

@@ -2,9 +2,9 @@ use std::collections::HashMap;
use itertools::Itertools;
use crate::{day_solver::DaySolver, util::{Coord, Grid}};
#[cfg(test)]
use crate::util::read_file;
use crate::{day_solver::DaySolver, util::{Coord, Grid}};
pub struct Day8 {
map: Grid<char>
@@ -14,7 +14,7 @@ impl Day8 {
pub fn create(input: String) -> Self {
return Day8 {
Day8 {
map: Grid::parse(input, None)
}
}

171
src/day9.rs Normal file
View File

@@ -0,0 +1,171 @@
use crate::day_solver::DaySolver;
use num::Integer;
pub struct Day9 {
disk_map: Vec<u8>
}
impl Day9 {
pub fn create(input: String) -> Self {
Day9 {
disk_map: input.chars().map(|c| (c as u8) - b'0').collect()
}
}
// fn print_layout(disk_blocks: &Vec<Block>) {
// for block in disk_blocks {
// match block {
// Block::File(size, idx) => {
// for _ in 0..*size {
// print!("{}", idx);
// }
// }
// Block::Empty(size) => {
// print!("{}", ".".repeat(*size));
// }
// }
// }
// println!();
// }
}
impl DaySolver for Day9 {
fn solve_part1(&mut self) -> String {
let mut cur_disk_idx = 0usize;
let mut disk_map_idx = 0usize;
let mut disk_map_idx_rev = self.disk_map.len() + (self.disk_map.len() % 2);
let mut left_to_move = 0u8;
let mut res = 0usize;
while disk_map_idx <= disk_map_idx_rev {
if disk_map_idx.is_even() {
// We're reading a file from the front of the disk map
let left_in_file = if disk_map_idx == disk_map_idx_rev { left_to_move } else { self.disk_map[disk_map_idx] };
for _ in 0..left_in_file {
// print!("{}({})", disk_map_idx / 2, cur_disk_idx);
res += cur_disk_idx * (disk_map_idx / 2);
cur_disk_idx += 1;
}
} else {
// We're reading empty space
for _ in 0..self.disk_map[disk_map_idx] {
// So let's grab some blocks from files at the end of the disk map
while left_to_move == 0 && disk_map_idx_rev > disk_map_idx {
disk_map_idx_rev -= 2;
left_to_move = self.disk_map[disk_map_idx_rev];
}
if disk_map_idx_rev < disk_map_idx {
break
}
// print!("{}({})", disk_map_idx_rev / 2, cur_disk_idx);
res += cur_disk_idx * (disk_map_idx_rev / 2);
cur_disk_idx += 1;
left_to_move -= 1;
}
}
disk_map_idx += 1;
}
res.to_string()
}
fn solve_part2(&mut self) -> String {
// Somewhat nicer data structure
let mut disk_blocks: Vec<Block> = Vec::new();
for (i, b) in self.disk_map.iter().enumerate() {
if i.is_even() {
disk_blocks.push(Block::File(b.to_owned().into(), i / 2))
} else if b > &0 {
disk_blocks.push(Block::Empty(b.to_owned().into()))
}
}
// Self::print_layout(&disk_blocks);
let original_disk = disk_blocks.clone();
for block in original_disk.iter().rev() {
if let Block::File(size, idx) = block {
// Self::print_layout(&disk_blocks);
// println!("{:?}", disk_blocks);
// Try to move the file
let move_target = disk_blocks.iter().enumerate()
.find(|(_, b) | if let Block::Empty(s) = b { s >= size } else { false })
// To prevent double borrowing, we need to clone the block here
.map(|(i, b)| (i, b.to_owned()));
if let Some((can_move_to_idx, b)) = move_target.to_owned() {
match b {
Block::Empty(empty_size) => {
let original_index = disk_blocks.iter().position(|b| b == block).unwrap();
// Never move blocks to the right
if can_move_to_idx >= original_index { continue; }
// We replace the original block by an empty one
// Note that, because we never move blocks to the right, it doesn't matter that the empty space around the block we're moving is inaccurate.
disk_blocks[original_index] = Block::Empty(size.to_owned());
disk_blocks[can_move_to_idx] = Block::File(size.to_owned(), idx.to_owned());
if &empty_size > size {
// Add additional empty space
disk_blocks.insert(can_move_to_idx + 1, Block::Empty(empty_size.to_owned() - size.to_owned()))
}
}
_ => panic!("uhm?")
}
}
}
}
// Self::print_layout(&disk_blocks);
let mut checksum = 0usize;
let mut cur_disk_idx = 0usize;
for block in disk_blocks {
match block {
Block::File(size, idx) => {
for _ in 0..size {
checksum += cur_disk_idx * idx;
cur_disk_idx += 1;
}
}
Block::Empty(size) => {
cur_disk_idx += size;
}
}
}
checksum.to_string()
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
enum Block {
Empty(usize),
File(usize, usize)
}
#[test]
fn test_part1_basic() {
let mut day = Day9::create("12345".to_string());
assert_eq!("60", day.solve_part1());
}
#[test]
fn test_part1() {
let mut day = Day9::create("2333133121414131402".to_string());
assert_eq!("1928", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day9::create("2333133121414131402".to_string());
assert_eq!("2858", day.solve_part2());
}
#[test]
fn test_part2_bonus() {
let mut day = Day9::create("2931514".to_string());
assert_eq!("158", day.solve_part2());
}

View File

@@ -1,7 +1,11 @@
extern crate core;
use std::time::Instant;
use crate::day1::Day1;
use crate::day10::Day10;
use crate::day11::Day11;
use crate::day12::Day12;
use crate::day13::Day13;
use crate::day14::Day14;
use crate::day2::Day2;
use crate::day3::Day3;
use crate::day4::Day4;
@@ -9,8 +13,10 @@ use crate::day5::Day5;
use crate::day6::Day6;
use crate::day7::Day7;
use crate::day8::Day8;
use crate::day9::Day9;
use crate::day_solver::DaySolver;
use crate::util::read_file;
use std::time::Instant;
mod util;
mod day_solver;
@@ -22,6 +28,12 @@ mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
@@ -101,10 +113,12 @@ fn build_day_solver(day: u8, input: String) -> Option<Box<dyn DaySolver>> {
6 => Some(Box::new(Day6::create(input))),
7 => Some(Box::new(Day7::create(input))),
8 => Some(Box::new(Day8::create(input))),
// 9 => Some(Box::new(Day9::create(input))),
// 10 => Some(Box::new(Day10::create(input))),
// 11 => Some(Box::new(Day11::create(input))),
// 12 => Some(Box::new(Day12::create(input))),
9 => Some(Box::new(Day9::create(input))),
10 => Some(Box::new(Day10::create(input))),
11 => Some(Box::new(Day11::create(input))),
12 => Some(Box::new(Day12::create(input))),
13 => Some(Box::new(Day13::create(input))),
14 => Some(Box::new(Day14::create(input))),
_ => None
}
}
@@ -188,7 +202,7 @@ fn solve_all(silent: bool) -> AocBenchResult {
for day in 1..(max_day + 1) {
bench_results.push(solve(day, silent));
}
return AocBenchResult {
AocBenchResult {
read_file: bench_results.iter().map(|t| t.read_file).sum(),
init: bench_results.iter().map(|t| t.init).sum(),
part1: bench_results.iter().map(|t| t.part1).sum(),