metya il y a 1 an
Parent
commit
9d10379074

+ 1 - 1
aoc2023/aocutils.py

@@ -86,7 +86,7 @@ def bench(part):
 
 
 if __name__ == "__main__":
-    day = 7
+    day = 17
     root = os.path.dirname(__file__)
     task_dir = os.path.join(root, f"day{day}")
     generate_readme(task_dir, day)

+ 75 - 0
aoc2023/day17/README.md

@@ -0,0 +1,75 @@
+--- Day 17: Clumsy Crucible ---
+-------------------------------
+
+The lava starts flowing rapidly once the Lava Production Facility is operational. As you leave, the reindeer offers you a parachute, allowing you to quickly reach Gear Island.
+
+
+As you descend, your bird's-eye view of Gear Island reveals why you had trouble finding anyone on your way up: half of Gear Island is empty, but the half below you is a giant factory city!
+
+
+You land near the gradually-filling pool of lava at the base of your new *lavafall*. Lavaducts will eventually carry the lava throughout the city, but to make use of it immediately, Elves are loading it into large [crucibles](https://en.wikipedia.org/wiki/Crucible) on wheels.
+
+
+The crucibles are top-heavy and pushed by hand. Unfortunately, the crucibles become very difficult to steer at high speeds, and so it can be hard to go in a straight line for very long.
+
+
+To get Desert Island the machine parts it needs as soon as possible, you'll need to find the best way to get the crucible *from the lava pool to the machine parts factory*. To do this, you need to minimize *heat loss* while choosing a route that doesn't require the crucible to go in a *straight line* for too long.
+
+
+Fortunately, the Elves here have a map (your puzzle input) that uses traffic patterns, ambient temperature, and hundreds of other parameters to calculate exactly how much heat loss can be expected for a crucible entering any particular city block.
+
+
+For example:
+
+
+
+```
+2413432311323
+3215453535623
+3255245654254
+3446585845452
+4546657867536
+1438598798454
+4457876987766
+3637877979653
+4654967986887
+4564679986453
+1224686865563
+2546548887735
+4322674655533
+
+```
+
+Each city block is marked by a single digit that represents the *amount of heat loss if the crucible enters that block*. The starting point, the lava pool, is the top-left city block; the destination, the machine parts factory, is the bottom-right city block. (Because you already start in the top-left block, you don't incur that block's heat loss unless you leave that block and then return to it.)
+
+
+Because it is difficult to keep the top-heavy crucible going in a straight line for very long, it can move *at most three blocks* in a single direction before it must turn 90 degrees left or right. The crucible also can't reverse direction; after entering each city block, it may only turn left, continue straight, or turn right.
+
+
+One way to *minimize heat loss* is this path:
+
+
+
+```
+2*>**>*34*^**>**>**>*1323
+32*v**>**>**>*35*v*5623
+32552456*v**>**>*54
+3446585845*v*52
+4546657867*v**>*6
+14385987984*v*4
+44578769877*v*6
+36378779796*v**>*
+465496798688*v*
+456467998645*v*
+12246868655*<**v*
+25465488877*v*5
+43226746555*v**>*
+
+```
+
+This path never moves more than three consecutive blocks in the same direction and incurs a heat loss of only `*102*`.
+
+
+Directing the crucible from the lava pool to the machine parts factory, but not moving more than three consecutive blocks in the same direction, *what is the least heat loss it can incur?*
+
+

+ 0 - 0
aoc2023/day17/day17.ol


+ 0 - 0
aoc2023/day17/day17.py


+ 13 - 0
aoc2023/day17/example.txt

@@ -0,0 +1,13 @@
+2413432311323
+3215453535623
+3255245654254
+3446585845452
+4546657867536
+1438598798454
+4457876987766
+3637877979653
+4654967986887
+4564679986453
+1224686865563
+2546548887735
+4322674655533

+ 141 - 0
aoc2023/day17/input.txt

@@ -0,0 +1,141 @@
+154651534533264223246736313357734657147374325514765434772544275388338442868844847827285753355677536765673622573135621137234461521333452441541
+434613344236623124357254431623141437257446714666363524476254466252424656766464543767833234754157661744135677735466542544652224313641123332623
+111656244231261643672337356332261667312415742412843278763423442625288648554467623422864383587622427376656341227463517657723745142466436612332
+165136343443341162231423452344525473231472466432243883553358332844847863852642574732237457642328251735767616161153526651513633151325531232154
+425162642164653166237577573266152444736721465776278554374686666765264272874554378373258465367847432213643665354176363146415334666644611262365
+613514122133246516652772625532462433317163648836726654272423253264346888555473666322576243675582732847512756757567731352746543772145452516552
+626155453666464414642266742147367271742354522737427852567873742477886873632746327236632385366884343653653426445236345115522726141334361523223
+233445262556673526733536651746413563147575357654266553684346345454337877847846826485857685863744744726428867233473156546517773141566416246235
+641435561561714375667267366234645272573576875263433732445848523845477733556458883625652227565862866275433576343554562446215213247637244333232
+244343112625757756556752527222156354666643654263565663323766825737643238637458432585334687355572258385858683564337413464717236627634614245335
+622511244277412256373463253114532558782675534254527477337255738643346838875732373844456288642767446775823833443617342734414445546742464134364
+232661653527512136737133242651268568258836768758565476863528846677644827427636564545542254438262634875278785324345217215221573255456364323646
+342163125674631636272756741733876753363376365254484536663567875535237563747325556248282475755388234386826265535728451311154711775262253262523
+161646332434246516366422434585474757563343222537675475443564782783774933673564723636447725257333384734373455463675443572122357121534335523624
+123555731631462631122134547866353487727242558468687856276647673369944498469843695384872374576783338885232325246434234155564347275466216462454
+545561174551676651765474785526373744832377726384383267847849549584868485684587555989349824354843733527562653635835267727214114156531564126542
+635133373565363436576632865886353776475474363453345866849757894434449454793463649966645799534765882647427848235282432567451572443122673722452
+642226414343346747155675285465842267788573563282724966869795865573458488585776599477384366959625458588566727456434728565762651154674131274374
+326545253656156161562578528675337448234255352454655474849548843788896745335668448487499693883645886242625428582743772748633323634776454552436
+634357257236273434641676333463427456442825557746967373888475656673574387689693878488556877786948848763456868322574633337741346256546411567612
+343572626551346472233274435334853326382783274884978386957557837498668659665838883386493565787476374936347252483473833823477525115332425453726
+167471726674523523363837576458522768588725379334335435874847993666673495753435963487337677646867787555748763657667654858323765571516453574567
+613661427654472164837676527224826677322263548756976866844637934744777345579894573567995439744436565663475865484778637388387376126376311363434
+332146564341247714557765355543847575882764745574488845498797677497459393455599796934573958953463478545932625574324664777785864446151571324625
+123367743334745273483222463366372346633869953873535576634859598469468947347453697855679865337584868945588464854554233623674788227254426756176
+313716535772243853248728528265246652654566478975983939568647946973687746337335358848577685355783475447699742858647578267563735574516276771417
+351326535414113548684553432344334573349596795676375444564636797763549997353888378836644956475689446797459458435532447626346738633357463252246
+432714122562746337536763783537687679887587456575979586859463433388497439459639787495746737835673686598357785945252876652442226547367411136326
+452477371331233435773863458475879846444799475968479835598869696344698586776996537858484577397679965377679774844427852333278645225824472333675
+631667433722873827452456736446343968644467697549586388339636948876594954774564686898578875939493356733475795785436286828852682637445635631761
+157571413664325828647463283258483939793475673666389978378789857487666974965778997896459656755537744584566437576943327533848572474468414223223
+741636266264223763473445236788766685695998546737884839455789746446989657969675647697689754659358868954849359644336588782335457645747644212215
+321435623424464345722357766779593883377487399896635576964695845958644484985494588455576796874395364987489785576967732277848732875475336221211
+614727555532353583428252782446554758844576767583845944996864866748699877555767875657885878855844357553494394868846987576444453884656642616246
+233737327388223853487665523453464346358398956758965449498964674588948549594669946888577967459668467799983438683967655442378326735824386365751
+673246768687733758348574857554544393749565738679958946787459754596994459466656464656768897445596779448697593747375756572865436772535557754211
+643457614367338742587762445569579447794658688474988797855967585494797688679469695647949677664948989438964885938654847566655273344546288527454
+356575457324273366465647997438575963694538459645656465875875558498467756996794875675577589488668578696596764773344453982235353577268774834463
+633321623433836843273528383336387495483596994466468678694577448567758874756598679589888787598979974549335494978894935543458468547346753432673
+115313556652823374565836834655457357764375575949847558498448584896998857699778897468958484945685859667743587393986455533555622566747274273212
+361721666566675563585867769969736437457977596568845687888869944785945999966597767579696498566647648459497896448859646549823383887456845657771
+566775333727343683842886855898484535396649789458788775667657895959489857847847649756675645455448487747566544878794363345357465546682547733763
+254414735335683264443778939565679883759844669979687799894569984775445958994947697948574467695488965998864836795896346753646446375847874672433
+456426575666374752778436466636354345479658879866448567954689488666969789559787778477899466555988658756779836757773759843789762332648335567642
+351567742488247372235344934965784578949884446765976579457465797666777576597797888965785566869857948894695988796985877765736522725583254543235
+171434334834237673275557953568738485776855786997559987678796998855555979896896895866944648887795876484994597774768735943895342452537684668412
+215446886462582568364664365843773343598865897848598887649567985767997987775558897986969587786557664974846754934457657399977443276666265473835
+465524642772282674444999688483968744669969697884768968675856667755869588978987777778756688479874858875856485956778383678364848467348336457636
+638554888368352558545564466374543474458579449967844985989665687669796778598565665685978996767694896664464488694387435497486857272656744254468
+554342247773486773577637634865683778864797597899885495699886665555786598989988566585789756999956469868846587856998747637986452882328285764578
+356255862786352224595948895664463858466766678664577998788787578597575759786996576687679888559667577457984696655549836456779437344226426265754
+344327728558542223875736798864557946696484758456658865878667986887779858975967769959895855669778574955574444997447784479997697275727678226776
+185688448363434853657769586555685584765657675547976766755966769978878585565978896857777886975975457757754555844375839946996747357875666774363
+188646847823335339873347753383354898476646746795758759575756858876698756659779998588587595786588878789886996798394645775775377327888343856565
+376585835485545576499678444683996657888878888664669568695977899766667798886587765978855577569986868598498597755548375584734396348252446866285
+252482488445458564668857694457378544474555679986786959669865687778559756667986678988886997988567476768966857775747448583486837952836458334243
+568273875576773636336636468583957477855454476777689899675986667889855957989669588955569859689556778698468859787765973637553557876483557728433
+777258855472864748746789568983844987477495868466799568877567566898956786999578985578679856597778556996788864976955787478579536498682877426754
+486746238838266398635658476877799564856499847866799676659998588699778869697778668585588858658985987859557944546654553844885868976357783335234
+432546538343684464978799898959754899655774466665797976957989656778766969968779986677588865676977795795798984594464376446445456793582467354323
+445675445468757649737955496899947848875978944558888595885885986689667889689679786896956687668996875976695968445845466543673733955854882452822
+845547862442224993565544479756947896849967456686986898857578566686996698889778666866759667568999765596557497584775656997878746549768672283543
+684633267222384334797446939455895977467496667568887675687589777978876877899688978778668696857898788784877884499464569854374757965234458283724
+343474688774535748367956535996879848797696747958987698658887777887796976897889897966795988997776568978485587988699379999439469658343436567323
+874827456725563636845864834847774697595855795895769566788668898996769887779766978678885778989666865756669564754549795975347599648425422767542
+474487685656557779345799756746568987975977788867866578759879666977886698998766896766757785688587998995864889546774859959537979786353486787288
+448476622346327344394849633848477676895589999989766965867797986767976867987967887887977787657558855546989574989774864779454675636682853752257
+585753566737595834856685897466684454485659499996557697577678968786667879688886698977697667988868697649777848457947944345974539784937645478847
+526737422567653736445595557949964875776686677598867565699869787879997676868998688686896569865888567868449548657679536666538839974386426322388
+376438532548394485644747385746769987468468898888959968879897998879779699977799797897969655865788768759898775688745787438977689674662622788785
+566667755624349557449753755974885754479888679897578959575898887787866996797677898688697775959885896664779888984544757379463567897437482348466
+825528865477734846633574535787859669654464755696677659588668766678779988667778889677766969978559877689564579889986966954957579783973722732573
+837225443233283579866885735685754565665674887986559766667669768869769878996876777869877576898689699875996898759888667767958398534552644667664
+382546845852453743384576376469487666575658657787697887955889678698966776888896679668986958597796878855888476879488546533899866889623484542276
+425854787382438755437489897787654748565774869995858858789777778686988988876669976876799669589796888765674849576847946995979368355366743258765
+483442763688843758979649983365948689564556655885788658767677676798678966779886988767898866685987877649444567589894973438397644933885537466775
+528367522475357954936633653669858868697947975699976879669698668768678896977996879766675875967868668585578799886684784345786679547863735567473
+468866437346689694649889646649655864949678459996566656897896997899999877769698877868779797665759988986547876449876578938779833738388227333758
+472553765763223394543566558465789556569868968969679786675887768976879798887988777896777978589795987868575789448969886537846993856552322236586
+438725732725665543367698347894695644984698687757785876998958878886796788977889776979976565978857795695785658654664639447469336563453345327374
+752684527475356858356769538947864887994964777578596868878595786688697996897976966895667778996756655669666786488657449343635753583365623368382
+662238474247557543977335574444474789758984575559576896658985668797686899779877676885579756886966569688948849458875663439893748795276728624868
+627284635774839657663447478495844795488546775957968689875859669798969976797696768656686786777669657877585775945899734638897465943354826842882
+477373683637773963486939884584669688765484745986998599856699886776988977768687897878775965677968598785546859477447979568539788482256884468684
+534288352852362776377346644983965648844875899898696767765666979997677798967889668976596579585685579496497879769774656777766443893264888876643
+348878668255247558769745438874568966476944676686976778966779695785686666869596757955857669798755886746866867455975943874648364692556332542587
+876433645368648657567688587485676946676594869587879768689767567889678899686999579955655688675787564474685498659747566399858547688856852752467
+165838473255777377896487667369755674495745586666789878877698797986957777895595985576778676695975447697599685769997443984944733487273735824577
+255343267466263654439533888647779686578778848548998567685798767998859796655966789559759756589589565444747869785464433846775549586527386622582
+688347884354244359566733875978765767599684767679766786776899765997858797886569669695579876786998844585868864594578478333399944444638276357778
+474822284677472748995796373366536495648454558779767985967596678757678775859695989875856769978555456646744484579789563589863775962555354664543
+366453867748523683964853389857694764556755958687878689899666869997997689679987796875668755668486745745658664798637377474475787437234834674743
+363562443732545545734364378477876584947468648486949668899969899966867768975655955777997859959585998987576648667543378387967948464546462576674
+167874878723738768695359348787889369679687558659658987576755889567556689776758986668795696689944585447868455639645644897355596775268377276735
+247773478853653687796549535959989449959546696499668794789899987665757658776689876865757679879588877449459645567753465366936963648837272336673
+222375652557565346953989358966346785774974899846557784888885988986665659976796788769889785675554474564585855495434667483995476642786278647522
+434553576855457275763579584778437435786995668545487658896698895667967697989957979667986476844784464594956585475895336959896782462386883685267
+744464444335544467586596755495857785658567959686569979946889595966757978888558655998776575955494577885877899758463587957685933668755858267617
+644275628882728232848796456653896337895695744494848785485779867998759685698955589558985868587766859989865684795897478448968365344543535823515
+726554686753373724433557537597788655459857468954694749756557957577855756788866959445947689978659899444448757937998673848764884762244885447711
+425235653434283265243695843537893943459667974788498948995694446998669697956658867686756569548465998848869369777647664878444453673737576283477
+172525262773245785738594463645547368476847645785679966888845665874887674669557565646849594646596968749855675596779956953652455566688444885514
+125345375647672378628733466636484343465858784644669555446679787944955965989777595965885958547575976744634884867847766735422537444387487284341
+451563673752232342385645834694545383869395797989788799888747845995657848899894698978845959649684959756789856667644834763353725826734536724123
+445231632763376268366333999374547793584334775448785549575484889966545779764785868574559544794569754873699793664983958362483248364447634646242
+716322647664237245474534587464874573968659769669945685795796989844558996985744994959688886989679999446567976556499947367253663588856888324475
+466217513556732443583835736934395945798939399855997765448969987988977494744799597774868776957677763434798998654893377866555842788672354252563
+763135318466752356574346279836755543974997968435566559566886997596847997474476797897584954898487345653855575983647743647352622845262265441574
+147521211823767363586423837798897397945743434337549865475855647445984746796555559489578468754976956897353479459877538276252245575255335541242
+417233764742428782243686786966339493967953973985795894988475767866974465445676859755976567685699473435467494666754468475437273848723743525617
+547625222245535364542567568594648354445394446848834969976894876764464749458486798449655994879664856433867583695357525378868728668286856426734
+273657757123543764474777486478548473866744349346835475674697449784447954698897997454748746884759678778874739587679237757453868428635424265273
+456746564566437628663828342366654383977948778797636598467978879457689784747789889949957354534533955554668885949535875375746632454335316521553
+211363223652275752437672233475483898783399588467657653476978947788659649898698788945383535677637669686796559934642752384368225744364116521715
+265224427432352425758375427368244858645366579477763477385875649896789548867977464773457834947687979789959699568837855372575838756534135757342
+124314564152662653354623284452775537849639978476366763885363339994935443657366978987737333536575865643354964956226857685383362628761664423114
+565771232573734555766578226454828526386378333576636354768343534667569774395543985495375389597977697379998746834562748338264728844411337264621
+627335323645345235387834463625352332558359775734455333369797673447475847688764359498844684788946345857898652853545873823232847466736535216456
+455775554647516626787383523257246878666858668794769883956933696574895888366395894587563576996787973636884676633663736838577725431675114512263
+133721554314256176658574327263626746727945537764994546396999334559948963888866347879359987379539997853793554373647454544586286523161622256227
+564256725767766664538252754683322232674686696996486363587686584544539745857443887665953554854974988354865277575867762743758572544677365671174
+342432131636221665265622536544773525578473465665544949534487559855933653787997577365458355493369777376348425353725478553825664426625171332471
+237257216656246677746266656338352742342777643774666393343975467644559536338776396964378977976739496374458262887655527622836765124312475161536
+427266616626153776676844276685545238247576745848345568853894764458954393436435475885374588443836966727373376234468755826362721444663771736656
+147557137462114333172152683685724484374388878468845559745785559847595584847956963758975763759583262836344766525328423776561343751713555313135
+435513555345226574627155725785658623623654368366485663993468394389367686665939737986853747367664243644824584658886754656736776255427771335234
+243337713474454142437322262563673668225425656764864438569759947386569988545437398855394537774624724273347477386757358281176113674572131474143
+446517731347735351452747574645462778657625382753875786755878793753695787859638943855757868245252276274648626482525487347577175235545312611223
+646214451633672457761737726624383832888827252274856742588632746547443538544659389695326634545728874426373466622252624734646767421266547266356
+615315257433435511264243747347283584524855646533688522764423462854566967663955265725484756727452548278578588734222835657712271114575426772345
+312625411122527753661626644533433776784526283474543685566226555487268787536766288726243547848475264388447642648464531465616414126632121735323
+331642216651537545423424157531886246753822224872522257535524633736775252357567687273487847884255777245652785623886341326327554177734653123612
+514522335365715616642364654513212884235563878372453676345322272885724648352626225488834732247568353765656578486315734534253677227275174154551
+312342353411212641724217467171355638745458746235538653875374228578346242525673575252576582265274547284845384653672644114516666267574626426446
+641656535461165653134137137722477635874264666754876537273748764746874224483372752532865454884388684445242625354215454736174156554454113515152
+251151226161462453633472466415347646547633244767443532463535583635635877275735264463758778722233266528342272775417356141135631314376665444451
+425632161465541424373523554243462375236228647728436237224244444783665877572637583426525378746876552776446464147565673615224667543761522432135
+532454562315245552355534656643543315415435287527884778223325668522753852474448867676375387628636286225571754523771223257562736755636513111414
+562565135566335125441463772322476616346666766454646466557286832778843766453328868242552727864437867631175455255327417542446331156214261133214
+545556525563512364764355571215152443741754226655642557247686658685864827574832252555434336427852877136574545437145171514662256641124656632134
+134114445634224644124445174544414343456644375627553722884563486256653482544748584575362474826271174547117176154323461247334336214255363631564

+ 51 - 0
aoc2023/day8/README.md

@@ -0,0 +1,51 @@
+--- Day 8: Haunted Wasteland ---
+--------------------------------
+
+You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching. When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about *ghosts* a few minutes ago.
+
+
+One of the camel's pouches is labeled "maps" - sure enough, it's full of documents (your puzzle input) about how to navigate the desert. At least, you're pretty sure that's what they are; one of the documents contains a list of left/right instructions, and the rest of the documents seem to describe some kind of *network* of labeled nodes.
+
+
+It seems like you're meant to use the *left/right* instructions to *navigate the network*. Perhaps if you have the camel follow the same instructions, you can escape the haunted wasteland!
+
+
+After examining the maps for a bit, two nodes stick out: `AAA` and `ZZZ`. You feel like `AAA` is where you are now, and you have to follow the left/right instructions until you reach `ZZZ`.
+
+
+This format defines each *node* of the network individually. For example:
+
+
+
+```
+RL
+
+AAA = (BBB, CCC)
+BBB = (DDD, EEE)
+CCC = (ZZZ, GGG)
+DDD = (DDD, DDD)
+EEE = (EEE, EEE)
+GGG = (GGG, GGG)
+ZZZ = (ZZZ, ZZZ)
+
+```
+
+Starting with `AAA`, you need to *look up the next element* based on the next left/right instruction in your input. In this example, start with `AAA` and go *right* (`R`) by choosing the right element of `AAA`, `*CCC*`. Then, `L` means to choose the *left* element of `CCC`, `*ZZZ*`. By following the left/right instructions, you reach `ZZZ` in `*2*` steps.
+
+
+Of course, you might not find `ZZZ` right away. If you run out of left/right instructions, repeat the whole sequence of instructions as necessary: `RL` really means `RLRLRLRLRLRLRLRL...` and so on. For example, here is a situation that takes `*6*` steps to reach `ZZZ`:
+
+
+
+```
+LLR
+
+AAA = (BBB, BBB)
+BBB = (AAA, ZZZ)
+ZZZ = (ZZZ, ZZZ)
+
+```
+
+Starting at `AAA`, follow the left/right instructions. *How many steps are required to reach `ZZZ`?*
+
+

+ 0 - 0
aoc2023/day8/day8.ol


+ 8 - 0
aoc2023/day8/day8.py

@@ -0,0 +1,8 @@
+import os
+from collections import Counter, defaultdict
+
+with open(os.path.join(os.path.dirname(__file__), "example.txt")) as example:
+    example_data = example.read().splitlines()
+
+with open(os.path.join(os.path.dirname(__file__), "input.txt")) as example:
+    input_data = example.read().splitlines()

+ 9 - 0
aoc2023/day8/example.txt

@@ -0,0 +1,9 @@
+RL
+
+AAA = (BBB, CCC)
+BBB = (DDD, EEE)
+CCC = (ZZZ, GGG)
+DDD = (DDD, DDD)
+EEE = (EEE, EEE)
+GGG = (GGG, GGG)
+ZZZ = (ZZZ, ZZZ)

+ 716 - 0
aoc2023/day8/input.txt

@@ -0,0 +1,716 @@
+LRRLRRLLRRRLRRLRLRRRLRRLRRRLRLLRRRLRRRLRLRRRLRRLRRLRLRLLLRRRLRRRLRRLRRLRLRRRLRRLLRRLRRLRLLRLRLRRLRLLRLRLRRRLRRLRLLRLRLLRRLRLRRLLLRLRRLRRRLLLRRLRLRRRLLRRLLLRRRLRRRLLLRRLLRLRRLRLRRLLLRLRRLLLLRRLLRRRLRRLRRLRLRLLRLRRRLLRRLLRRLRRLRRLRRLRLLRRLRRRLRLRLLLRRRLLRRRLRRLRRLLLLRRRR
+
+VRN = (CSM, GPD)
+XDT = (QBK, PJR)
+HVC = (MKM, TJS)
+KRH = (BHN, PXB)
+GTX = (VFD, TXR)
+BQB = (MQV, PFQ)
+TDV = (VSG, MJX)
+VJM = (QHP, XMB)
+KLG = (QLJ, HCV)
+TSM = (JPG, DNP)
+KHS = (QNR, DXJ)
+FXM = (PHF, PHF)
+RMV = (BMM, KHS)
+QXL = (BKG, TLP)
+MHS = (QXL, CFQ)
+TBT = (TVT, BRD)
+QXS = (GPP, RND)
+XLL = (JHQ, LDV)
+PBQ = (VXK, RJR)
+FXB = (HMN, THX)
+DPF = (GLX, GNC)
+HVG = (HJF, SCH)
+QMN = (DQJ, GMN)
+MBS = (PFX, JHG)
+VGL = (FHX, CCK)
+QLV = (BLT, FDR)
+MNS = (BDB, BMJ)
+MMT = (TSM, SFR)
+NRP = (FKB, QPH)
+XFQ = (GTS, CCQ)
+XFF = (HKG, NVL)
+TXR = (VHQ, CKP)
+VPL = (GHC, VMT)
+SGC = (BGM, MJV)
+SMS = (GJV, LSC)
+BVC = (PRH, FJJ)
+JHQ = (VJQ, XTX)
+RJF = (GKK, NKX)
+RJR = (JJQ, JTK)
+VHQ = (JPS, JPS)
+SFR = (JPG, DNP)
+RDP = (GPD, CSM)
+GGQ = (MVX, XBP)
+XGK = (GBB, VPH)
+XBH = (PTH, GSL)
+MKG = (RBP, MGG)
+FSG = (KFC, RMB)
+NHC = (RQG, CVF)
+SSV = (MVF, QFP)
+RLP = (FXC, HCP)
+FBZ = (FJF, CRJ)
+HFL = (FKB, QPH)
+NBM = (QBD, XGK)
+NSP = (QKG, NDN)
+TQF = (RMH, TDB)
+RBB = (QTC, HPT)
+CVF = (BSV, VTR)
+XQG = (LFJ, JXD)
+KXF = (CRJ, FJF)
+MQC = (MQL, BSL)
+RCC = (NHC, QLC)
+TNT = (VKQ, NSX)
+TVN = (NDN, QKG)
+SCH = (FXB, NTM)
+CVD = (XLJ, XDT)
+QVF = (MQR, RDB)
+GXS = (HCK, SHD)
+KBD = (JHG, PFX)
+KXV = (HVQ, QCJ)
+MQR = (RNQ, SVC)
+CBC = (SXB, BVC)
+GKK = (HDR, LTF)
+FRT = (CFQ, QXL)
+VMT = (SQQ, DBB)
+QPV = (NVQ, VVV)
+XGD = (MPL, PMQ)
+MNT = (JDD, NQC)
+RGT = (QHD, SQP)
+HXV = (RQD, RRX)
+LGR = (FHX, CCK)
+PHF = (CBV, TMC)
+BTP = (JSC, QMN)
+CXS = (SCH, HJF)
+MQV = (FGJ, QPD)
+HRZ = (CCX, BCF)
+DDB = (DJK, CVD)
+XNL = (QLJ, HCV)
+GLX = (MGN, CFV)
+QCJ = (NDK, XBR)
+XBX = (CQM, VKD)
+QPH = (XBH, CFG)
+NSL = (LFJ, JXD)
+DJQ = (VMN, STS)
+RNV = (XFF, KSR)
+JTR = (QLG, XRD)
+VVV = (MDH, KHK)
+TLR = (DMH, NXC)
+GBH = (GLS, XLK)
+LRN = (QRM, FMC)
+BRM = (DCK, DSK)
+GQS = (FXV, QPV)
+XMT = (NHF, RXG)
+KLR = (HFN, KDR)
+SVH = (RMR, JLC)
+QSG = (KQC, CMH)
+VVX = (XGM, FNX)
+BCF = (LNR, MTS)
+RPJ = (RCC, CKG)
+JJD = (NRP, HFL)
+FGP = (MFS, RBB)
+BJX = (BTD, KSC)
+PQC = (VMN, STS)
+JPG = (RQL, CSQ)
+SLK = (JJC, BPJ)
+JTK = (XHN, BFH)
+HCV = (BRF, VPT)
+VPH = (BVS, RRT)
+MSH = (JQF, XFJ)
+JHL = (QPF, QPF)
+FGD = (MPC, TVB)
+DCB = (JBC, XFB)
+RKN = (TSL, VQG)
+QBQ = (QLV, NRT)
+MQX = (JSX, MCV)
+XHX = (FNX, XGM)
+DTL = (JDM, BDX)
+LST = (JHL, CQN)
+VGR = (HQV, HRZ)
+CTQ = (XCF, TJK)
+SQP = (HHB, NBM)
+RRL = (TSL, VQG)
+NNM = (DDS, XSF)
+KHK = (HSG, NDF)
+MGN = (VXT, VGV)
+TLB = (DPK, MLV)
+NMM = (TRR, XJH)
+SJG = (XRJ, XBX)
+GSC = (RRL, RKN)
+KDR = (PSJ, TBM)
+LRP = (SQP, QHD)
+DKF = (MVR, QQB)
+FHC = (BPT, BKC)
+PLT = (JGG, GGQ)
+XRD = (HMH, PBQ)
+RHP = (JPD, XVL)
+MXF = (MQR, RDB)
+DML = (BRD, TVT)
+CKP = (JPS, RBS)
+BFK = (BCL, TLK)
+KSR = (NVL, HKG)
+XQF = (BMM, KHS)
+BVJ = (CBL, PLC)
+BCS = (RQF, GTB)
+JCC = (VTT, VPQ)
+BCL = (BNV, PDB)
+HCK = (DDB, CBX)
+SVG = (FGD, VQL)
+BLT = (XNK, LHM)
+MVQ = (LRG, NPB)
+RND = (QCK, QRN)
+HFR = (FBT, CLS)
+KNK = (XDS, BCK)
+XBB = (BRM, FDC)
+XGM = (FFC, GJX)
+PTN = (TQF, QKP)
+RNQ = (GSC, XKH)
+TPT = (CMK, KXT)
+HPL = (CKB, QLR)
+MVX = (QSG, TKJ)
+QFP = (RLP, RSF)
+GXF = (LNB, VNJ)
+QHD = (NBM, HHB)
+KSS = (LLH, PFK)
+MFD = (XGJ, GGS)
+JJQ = (XHN, BFH)
+JDD = (HXV, FVH)
+CFR = (FXM, FXM)
+FDR = (XNK, LHM)
+DHG = (BRS, TLR)
+TDB = (SBS, XBB)
+BVS = (GQH, BFS)
+DGZ = (TMC, CBV)
+HQD = (JSC, QMN)
+TMZ = (XFB, JBC)
+BRF = (MBF, KGJ)
+RQG = (VTR, BSV)
+CSQ = (FTS, RHR)
+FFJ = (QCL, CTQ)
+XKH = (RRL, RKN)
+VJQ = (BTL, GQS)
+NGK = (JGG, GGQ)
+RQN = (GVG, SJN)
+GRR = (RNV, FHF)
+LSR = (VBL, SLK)
+VQG = (QBV, NJV)
+BHK = (BVJ, LJR)
+BRS = (DMH, NXC)
+NKX = (LTF, HDR)
+QBD = (GBB, VPH)
+RGQ = (CLM, FHK)
+VXX = (KRH, VGN)
+KRF = (VFQ, SMN)
+XFR = (XGD, RMM)
+JGC = (JGM, PFR)
+SHD = (DDB, CBX)
+QKG = (QTS, GXP)
+CDL = (GLX, GNC)
+RBP = (HKK, CMN)
+CLN = (HDG, BHM)
+XFX = (RNV, FHF)
+AAA = (DXX, SVG)
+FXC = (MMT, KLS)
+PTF = (SKF, SDF)
+QPF = (RQF, RQF)
+DTB = (HQV, HQV)
+RRF = (FNV, MKG)
+MGG = (HKK, CMN)
+NDF = (KMD, FFH)
+DVL = (RKL, CLC)
+JRQ = (BXV, BRB)
+HVM = (DRT, SSV)
+BHM = (KNK, BPP)
+TDT = (DPS, VCP)
+JPC = (DCH, FHD)
+RSF = (FXC, HCP)
+KSX = (BVJ, LJR)
+NLT = (LTB, QBQ)
+SBD = (NKX, GKK)
+VQL = (MPC, TVB)
+JXD = (MLK, LHN)
+XNN = (TNT, LPQ)
+HMH = (RJR, VXK)
+JGG = (MVX, XBP)
+PTP = (MVQ, NPS)
+FQC = (XQF, RMV)
+FXT = (TDH, JGD)
+RGP = (CPN, KGF)
+BTD = (NKN, NTQ)
+BGM = (NRJ, CJN)
+RMM = (PMQ, MPL)
+DQJ = (DPF, CDL)
+TVT = (TFJ, VJM)
+TGL = (CGS, SJG)
+NHF = (HVC, LVM)
+NMK = (GRR, XFX)
+QRN = (MMP, XSL)
+FFH = (DJQ, PQC)
+PDJ = (NQC, JDD)
+CGS = (XBX, XRJ)
+NTQ = (RXX, FLX)
+CFB = (TVC, PTP)
+GXK = (FLC, GXS)
+RBS = (DCB, TMZ)
+CFQ = (TLP, BKG)
+QHP = (KVX, GSG)
+HDJ = (RPH, QPK)
+VXT = (GXF, JKM)
+NCM = (NJL, TGL)
+HFN = (TBM, PSJ)
+JGF = (CFB, NMC)
+JDM = (CLN, PHJ)
+DJS = (RMR, JLC)
+RDB = (RNQ, SVC)
+RRX = (HQD, BTP)
+HHS = (MXF, QVF)
+MMP = (GTX, HKC)
+JRK = (KKP, PTN)
+TRR = (VGD, HGC)
+JKM = (LNB, VNJ)
+BRD = (TFJ, VJM)
+TLK = (BNV, PDB)
+QTS = (CHL, LSR)
+BPP = (XDS, BCK)
+RXX = (BKP, TLS)
+VFD = (VHQ, VHQ)
+BQF = (DHG, DQC)
+XDL = (QVF, MXF)
+ZZZ = (SVG, DXX)
+GGB = (LTB, QBQ)
+QTN = (JHL, CQN)
+BVK = (BHQ, SSG)
+VGB = (BXV, BRB)
+QLR = (XFR, KNM)
+QBK = (KNC, VJX)
+BMJ = (JLK, TDV)
+FDC = (DSK, DCK)
+XDS = (SMS, TVR)
+GBC = (NGK, PLT)
+HPT = (XHQ, SXT)
+FHK = (JCC, FJS)
+KNM = (RMM, XGD)
+GTB = (KLR, JVZ)
+VCT = (PTN, KKP)
+LDV = (XTX, VJQ)
+KTK = (MQV, PFQ)
+TVC = (MVQ, NPS)
+BXV = (XLL, KDL)
+BFA = (BCF, CCX)
+CCF = (CLM, FHK)
+JGS = (VCP, DPS)
+RVK = (MKJ, QLH)
+FNX = (FFC, GJX)
+XBP = (QSG, TKJ)
+LMJ = (FPH, JVL)
+HKG = (VXX, RNX)
+KMD = (DJQ, PQC)
+BRB = (XLL, KDL)
+NDK = (DJS, SVH)
+BSV = (XVC, QXS)
+TLS = (FSJ, MNS)
+CRJ = (SGC, RNH)
+BNV = (QSF, FSG)
+SMN = (MNK, QGN)
+JVV = (TRN, DVL)
+JJC = (HBT, RPJ)
+KSB = (XVL, JPD)
+JJT = (TLB, DTJ)
+TSL = (QBV, NJV)
+GNV = (GCS, JLR)
+HJF = (FXB, NTM)
+VMN = (CFR, CFR)
+GVG = (XDL, HHS)
+LNB = (HMP, XMP)
+RTL = (FXT, RCT)
+XVC = (RND, GPP)
+GNS = (MFS, RBB)
+XTG = (LRM, DKQ)
+JVZ = (KDR, HFN)
+QQB = (XTG, GFG)
+HMN = (FHC, FMN)
+XLC = (FXT, RCT)
+CKG = (QLC, NHC)
+NJB = (DVL, TRN)
+VCP = (LRF, HPL)
+KQJ = (MXH, MXH)
+GJV = (TPT, QNJ)
+CCX = (LNR, MTS)
+DTJ = (MLV, DPK)
+HDX = (JSX, MCV)
+XRJ = (VKD, CQM)
+DMH = (RGP, KPR)
+QGN = (VRF, QDL)
+JSC = (DQJ, GMN)
+BPT = (LLB, XNN)
+CJN = (JJT, PGM)
+XDV = (XVD, HJH)
+JHG = (LLF, MLJ)
+NKN = (FLX, RXX)
+TGP = (XJH, TRR)
+TLP = (XLC, RTL)
+HQT = (SSN, BPS)
+BKP = (MNS, FSJ)
+VPT = (KGJ, MBF)
+JSJ = (PFK, LLH)
+CBX = (DJK, CVD)
+TJK = (VGL, LGR)
+THP = (TGL, NJL)
+NSX = (SQL, GNV)
+JQF = (VDM, JJD)
+SDF = (JPC, KRV)
+XNK = (HDJ, MQJ)
+DSD = (SJN, GVG)
+SBS = (FDC, BRM)
+FPH = (NCM, THP)
+LMR = (KQJ, BGV)
+VKQ = (SQL, GNV)
+FMC = (CPV, GBC)
+HHB = (QBD, XGK)
+HVQ = (NDK, XBR)
+KXT = (JKG, NLS)
+GJX = (TVP, JTR)
+JLT = (MHM, MSH)
+VNJ = (HMP, XMP)
+TDH = (JGF, GGD)
+VPQ = (HDX, MQX)
+SKF = (JPC, KRV)
+NXT = (RXG, NHF)
+TRN = (CLC, RKL)
+RRT = (BFS, GQH)
+JFJ = (SXB, BVC)
+KBR = (CGD, JGC)
+PGG = (HFR, TJJ)
+CMK = (JKG, NLS)
+CBV = (FCX, KBR)
+GMN = (DPF, CDL)
+BTL = (QPV, FXV)
+PFX = (MLJ, LLF)
+DCT = (XLK, GLS)
+PGM = (DTJ, TLB)
+NVL = (VXX, RNX)
+RPD = (TLK, BCL)
+QDL = (FFJ, SFH)
+JVL = (THP, NCM)
+NVQ = (MDH, KHK)
+TMC = (FCX, KBR)
+LPQ = (NSX, VKQ)
+RHR = (PPL, LCD)
+JSX = (DHM, PMS)
+DPK = (KBD, MBS)
+LTF = (PGG, QPN)
+BPS = (GXK, HCM)
+HKC = (VFD, TXR)
+PXB = (RPN, BQF)
+FLX = (TLS, BKP)
+PJR = (VJX, KNC)
+PDB = (QSF, FSG)
+NMC = (TVC, PTP)
+MLP = (MSH, MHM)
+PMQ = (KXV, QFJ)
+FKB = (XBH, CFG)
+JRV = (SMN, VFQ)
+SQL = (GCS, JLR)
+DXX = (FGD, VQL)
+XMM = (GMG, LRN)
+PFK = (HDL, XFQ)
+XSL = (GTX, HKC)
+CLC = (JRQ, VGB)
+LMH = (KXF, FBZ)
+NMX = (KSC, BTD)
+GTJ = (KLG, XNL)
+THX = (FMN, FHC)
+RMH = (XBB, SBS)
+SSG = (MFD, KFP)
+QNR = (RBG, HNG)
+DSK = (LMJ, FRP)
+GQP = (FXM, XVT)
+MFS = (QTC, HPT)
+VHX = (VBD, RDD)
+SQS = (GTJ, MSR)
+LJR = (CBL, PLC)
+QSF = (KFC, KFC)
+DHM = (VFJ, DTL)
+MDH = (NDF, HSG)
+SSN = (HCM, GXK)
+HCM = (FLC, GXS)
+PQX = (FGG, BXR)
+DQC = (BRS, TLR)
+KRV = (DCH, FHD)
+FNH = (SKF, SDF)
+LFJ = (LHN, MLK)
+MVR = (GFG, XTG)
+HBT = (RCC, CKG)
+VKD = (NMK, PFV)
+TKJ = (KQC, CMH)
+MRH = (RHV, ZZZ)
+CKB = (XFR, KNM)
+BMM = (DXJ, QNR)
+KDL = (JHQ, LDV)
+VFJ = (BDX, JDM)
+PLC = (PND, GNP)
+MNK = (QDL, VRF)
+MXT = (RMV, XQF)
+TJS = (PTF, FNH)
+PHJ = (BHM, HDG)
+FSJ = (BDB, BMJ)
+CFV = (VGV, VXT)
+XVD = (CBF, SQS)
+TFJ = (QHP, XMB)
+CPV = (PLT, NGK)
+VTR = (XVC, QXS)
+BKC = (XNN, LLB)
+NPS = (NPB, LRG)
+FXV = (NVQ, VVV)
+FTS = (PPL, LCD)
+HMP = (QMD, SNX)
+VBD = (DTB, DTB)
+VFQ = (QGN, MNK)
+KFP = (GGS, XGJ)
+BHN = (RPN, BQF)
+PFV = (GRR, XFX)
+QMD = (MGK, XDV)
+MLK = (RPD, BFK)
+GFG = (DKQ, LRM)
+NLS = (BQB, KTK)
+XLK = (HVG, CXS)
+LSC = (QNJ, TPT)
+FNV = (RBP, MGG)
+HKK = (RCX, MQC)
+GPD = (NSL, XQG)
+RQL = (RHR, FTS)
+HDB = (GHC, VMT)
+HJH = (SQS, CBF)
+QTC = (SXT, XHQ)
+TRS = (BXR, FGG)
+MTS = (DML, TBT)
+RHV = (DXX, SVG)
+XVL = (FGP, GNS)
+GSG = (RRF, CSP)
+VBL = (JJC, BPJ)
+CCK = (RJF, SBD)
+QPN = (TJJ, HFR)
+PRH = (TGP, NMM)
+PQT = (TRS, PQX)
+QKP = (RMH, TDB)
+XMP = (SNX, QMD)
+QPD = (KRF, JRV)
+RQD = (HQD, BTP)
+XVT = (PHF, DGZ)
+GXP = (CHL, LSR)
+LHM = (MQJ, HDJ)
+STS = (CFR, GQP)
+FJJ = (NMM, TGP)
+MPC = (CCF, RGQ)
+MKM = (PTF, FNH)
+QVH = (VBD, VBD)
+XMB = (KVX, GSG)
+CHL = (VBL, SLK)
+XBR = (DJS, SVH)
+KPR = (CPN, KGF)
+MQL = (KSB, RHP)
+CQM = (PFV, NMK)
+XHQ = (HCR, HVM)
+FFC = (JTR, TVP)
+FMN = (BPT, BKC)
+SNX = (MGK, XDV)
+KNC = (QVJ, NNM)
+DPS = (LRF, HPL)
+GBB = (BVS, RRT)
+BFH = (XMM, XQL)
+GLS = (HVG, CXS)
+RXG = (LVM, HVC)
+MPL = (QFJ, KXV)
+NXC = (KPR, RGP)
+NJV = (TVN, NSP)
+LLB = (LPQ, TNT)
+SXT = (HVM, HCR)
+LLH = (HDL, XFQ)
+MLV = (KBD, MBS)
+CBF = (GTJ, MSR)
+JBC = (KTX, QQG)
+FLC = (SHD, HCK)
+FRP = (FPH, JVL)
+BHQ = (MFD, KFP)
+LNR = (DML, TBT)
+CSP = (MKG, FNV)
+GHC = (SQQ, DBB)
+NRT = (BLT, FDR)
+VTT = (HDX, MQX)
+HSG = (FFH, KMD)
+VGA = (CBV, TMC)
+KLS = (TSM, SFR)
+PFQ = (FGJ, QPD)
+MKJ = (JLT, MLP)
+MFX = (RVK, NSF)
+QNJ = (KXT, CMK)
+QBV = (NSP, TVN)
+MSR = (KLG, XNL)
+NSF = (QLH, MKJ)
+DKQ = (JDR, DQQ)
+PLH = (RVK, NSF)
+JKG = (BQB, KTK)
+LVM = (MKM, TJS)
+QLJ = (VPT, BRF)
+FVH = (RRX, RQD)
+MJX = (DCT, GBH)
+QLH = (MLP, JLT)
+NPB = (XMT, NXT)
+HDL = (CCQ, GTS)
+JPS = (DCB, DCB)
+CQN = (QPF, BCS)
+GNP = (DSD, RQN)
+JLK = (MJX, VSG)
+PMS = (DTL, VFJ)
+BFS = (JGS, TDT)
+XJH = (VGD, HGC)
+VRF = (SFH, FFJ)
+BCK = (SMS, TVR)
+DRT = (QFP, MVF)
+PND = (DSD, RQN)
+VSG = (GBH, DCT)
+VGV = (JKM, GXF)
+FHD = (MXT, FQC)
+GPP = (QRN, QCK)
+BDX = (CLN, PHJ)
+LLF = (HQT, DCL)
+DXA = (HFN, KDR)
+MCV = (DHM, PMS)
+NTM = (HMN, THX)
+JLC = (RDP, VRN)
+HQV = (BCF, CCX)
+NDN = (QTS, GXP)
+QVJ = (DDS, XSF)
+MQJ = (RPH, QPK)
+FGJ = (KRF, JRV)
+LHN = (BFK, RPD)
+MXH = (RHV, RHV)
+HGC = (DNN, PQT)
+MHM = (XFJ, JQF)
+JGD = (JGF, GGD)
+FCX = (JGC, CGD)
+GCS = (LST, QTN)
+RCX = (BSL, MQL)
+XGJ = (VCT, JRK)
+SXB = (FJJ, PRH)
+LRG = (XMT, NXT)
+XSF = (LRP, RGT)
+DNP = (CSQ, RQL)
+RKL = (VGB, JRQ)
+KVX = (CSP, RRF)
+JPD = (FGP, GNS)
+GNC = (MGN, CFV)
+PFR = (MHS, FRT)
+DCK = (LMJ, FRP)
+KKP = (TQF, QKP)
+XQL = (GMG, LRN)
+QCL = (TJK, XCF)
+TVP = (XRD, QLG)
+HDR = (QPN, PGG)
+HLN = (BHQ, SSG)
+GGS = (VCT, JRK)
+SJN = (HHS, XDL)
+DBB = (BHK, KSX)
+QPK = (MFX, PLH)
+MBF = (NLT, GGB)
+BDB = (TDV, JLK)
+KSC = (NKN, NTQ)
+CPN = (HDB, VPL)
+TVB = (RGQ, CCF)
+VJX = (NNM, QVJ)
+FBT = (JLL, LMR)
+TVR = (GJV, LSC)
+RNX = (KRH, VGN)
+RPH = (MFX, PLH)
+VJA = (JBC, XFB)
+CLS = (JLL, LMR)
+PSJ = (DKF, MSL)
+QLG = (PBQ, HMH)
+DXJ = (HNG, RBG)
+XFB = (KTX, QQG)
+TJJ = (FBT, CLS)
+KFC = (JRF, JRF)
+XFJ = (JJD, VDM)
+RCT = (TDH, JGD)
+RNH = (BGM, MJV)
+VGD = (PQT, DNN)
+KQC = (JFJ, CBC)
+PPL = (JSJ, KSS)
+HCR = (DRT, SSV)
+XLJ = (PJR, QBK)
+PTH = (QVH, VHX)
+RQF = (KLR, KLR)
+MSL = (MVR, QQB)
+NRJ = (PGM, JJT)
+JLL = (KQJ, KQJ)
+DCL = (BPS, SSN)
+GTS = (MNT, PDJ)
+BXR = (NMX, BJX)
+CBL = (PND, GNP)
+VXK = (JJQ, JTK)
+BSL = (RHP, KSB)
+NJL = (SJG, CGS)
+DQQ = (XHX, VVX)
+SQQ = (BHK, KSX)
+KTX = (BVK, HLN)
+QCK = (XSL, MMP)
+SVC = (GSC, XKH)
+BGV = (MXH, MRH)
+GMG = (QRM, FMC)
+KGJ = (NLT, GGB)
+LRF = (QLR, CKB)
+CMN = (RCX, MQC)
+CGD = (JGM, PFR)
+LCD = (JSJ, KSS)
+HDG = (BPP, KNK)
+DDS = (LRP, RGT)
+LRM = (DQQ, JDR)
+CMH = (CBC, JFJ)
+GQH = (TDT, JGS)
+BKG = (RTL, XLC)
+RMR = (VRN, RDP)
+MGK = (XVD, HJH)
+FJS = (VTT, VPQ)
+SFH = (CTQ, QCL)
+XHN = (XQL, XMM)
+BPA = (CRJ, FJF)
+XCF = (VGL, LGR)
+TBM = (MSL, DKF)
+JLR = (LST, QTN)
+QFJ = (HVQ, QCJ)
+CCQ = (MNT, PDJ)
+VGN = (PXB, BHN)
+LTB = (QLV, NRT)
+DCH = (MXT, FQC)
+CFG = (PTH, GSL)
+JRF = (KXF, KXF)
+QRM = (CPV, GBC)
+XTX = (BTL, GQS)
+FHX = (SBD, RJF)
+FHF = (KSR, XFF)
+CSM = (NSL, XQG)
+HCP = (MMT, KLS)
+DJK = (XDT, XLJ)
+QLC = (CVF, RQG)
+MLJ = (HQT, DCL)
+CLM = (JCC, FJS)
+NQC = (HXV, FVH)
+RDD = (DTB, VGR)
+RPN = (DQC, DHG)
+GSL = (QVH, VHX)
+FGG = (NMX, BJX)
+BPJ = (RPJ, HBT)
+RBG = (NJB, JVV)
+FJF = (SGC, RNH)
+GGD = (CFB, NMC)
+QQG = (HLN, BVK)
+MVF = (RLP, RSF)
+JGM = (MHS, FRT)
+RMB = (JRF, LMH)
+VDM = (HFL, NRP)
+HNG = (NJB, JVV)
+MJV = (CJN, NRJ)
+DNN = (PQX, TRS)
+JDR = (XHX, VVX)
+KGF = (HDB, VPL)

+ 193 - 0
aoc2024/.gitignore

@@ -0,0 +1,193 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+
+*.ipynb
+
+

+ 94 - 0
aoc2024/aocutils.py

@@ -0,0 +1,94 @@
+import os
+import requests
+import time
+import bs4
+import markdownify as md
+
+YEAR = "2024"
+session_id = "53616c7465645f5fac063ee400b29580afda85dde7a28a255d300226c59d9dc7f19e200f03ce27cd6a26f59a64ee6b6d39b155c46f7a6b90b63dcb265c37cbca"
+
+
+def create_files(task_dir: str, day: int):
+    go_path = os.path.join(task_dir, f"day{day}.go")
+    python_path = os.path.join(task_dir, f"day{day}.py")
+    if os.path.exists(go_path):
+        os.utime(go_path, None)
+    else:
+        open(go_path, "a").close()
+    if os.path.exists(python_path):
+        os.utime(python_path, None)
+    else:
+        open(python_path, "a").close()
+
+
+def generate_readme(task_dir: str, day: int):
+    os.makedirs(task_dir, exist_ok=True)
+    readme_path = os.path.join(task_dir, "README.md")
+    cookies_dict = {"session": session_id}
+
+    soup = bs4.BeautifulSoup(
+        requests.get(
+            f"https://adventofcode.com/{YEAR}/day/{day}", cookies=cookies_dict
+        ).content,
+        features="html.parser",
+    )
+    with open(readme_path, "w") as readme:
+        readme.write(md.markdownify(str(soup.find_all("article")[0])))
+    if len(soup.find_all("article")) > 1:
+        with open(readme_path, "a") as readme:
+            readme.write(md.markdownify(str(soup.find_all("article")[1])))
+
+
+def get_input(task_dir: str, day: int) -> tuple[list[str], list[str]] | None:
+    input_path = os.path.join(task_dir, "input.txt")
+    example_path = os.path.join(task_dir, "example.txt")
+    readme_path = os.path.join(task_dir, "README.md")
+
+    cookies_dict = {"session": session_id}
+
+    os.makedirs(task_dir, exist_ok=True)
+
+    if os.path.exists(input_path):
+        with open(input_path, "r") as f:
+            input = f.read().splitlines()
+    else:
+        input = requests.get(
+            f"https://adventofcode.com/{YEAR}/day/{day}/input", cookies=cookies_dict
+        ).text
+        with open(input_path, "w") as f:
+            f.write(input.strip())
+        input = input.splitlines()
+
+    if os.path.exists(example_path):
+        with open(example_path, "r") as e:
+            example = e.read().splitlines()
+    elif os.path.exists(readme_path):
+        with open(example_path, "w") as e:
+            with open(readme_path, "r") as r:
+                example = r.read().split("\n\n```\n")[1]
+            e.write(example)
+            example = example.splitlines()
+    else:
+        print("call `generate_readme()` first!")
+        return
+
+    return input, example
+
+
+def bench(part):
+    def wrapper(*args, **kwargs):
+        start = time.perf_counter()
+        value = part(*args, **kwargs)
+        print(f"\tevaluation time: {time.perf_counter() - start} s")
+        return value
+
+    return wrapper
+
+
+if __name__ == "__main__":
+    day = 1
+    root = os.path.dirname(__file__)
+    task_dir = os.path.join(root, f"day{day}")
+    generate_readme(task_dir, day)
+    get_input(task_dir, day)
+    create_files(task_dir, day)

+ 107 - 0
aoc2024/day1/README.md

@@ -0,0 +1,107 @@
+--- Day 1: Historian Hysteria ---
+---------------------------------
+
+The *Chief Historian* is always present for the big Christmas sleigh launch, but nobody has seen him in months! Last anyone heard, he was visiting locations that are historically significant to the North Pole; a group of Senior Historians has asked you to accompany them as they check the places they think he was most likely to visit.
+
+
+As each location is checked, they will mark it on their list with a *star*. They figure the Chief Historian *must* be in one of the first fifty places they'll look, so in order to save Christmas, you need to help them get *fifty stars* on their list before Santa takes off on December 25th.
+
+
+Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants *one star*. Good luck!
+
+
+You haven't even left yet and the group of Elvish Senior Historians has already hit a problem: their list of locations to check is currently *empty*. Eventually, someone decides that the best place to check first would be the Chief Historian's office.
+
+
+Upon pouring into the office, everyone confirms that the Chief Historian is indeed nowhere to be found. Instead, the Elves discover an assortment of notes and lists of historically significant locations! This seems to be the planning the Chief Historian was doing before he left. Perhaps these notes can be used to determine which locations to search?
+
+
+Throughout the Chief's office, the historically significant locations are listed not by name but by a unique number called the *location ID*. To make sure they don't miss anything, The Historians split into two groups, each searching the office and trying to create their own complete list of location IDs.
+
+
+There's just one problem: by holding the two lists up *side by side* (your puzzle input), it quickly becomes clear that the lists aren't very similar. Maybe you can help The Historians reconcile their lists?
+
+
+For example:
+
+
+
+```
+3   4
+4   3
+2   5
+1   3
+3   9
+3   3
+
+```
+
+Maybe the lists are only off by a small amount! To find out, pair up the numbers and measure how far apart they are. Pair up the *smallest number in the left list* with the *smallest number in the right list*, then the *second-smallest left number* with the *second-smallest right number*, and so on.
+
+
+Within each pair, figure out *how far apart* the two numbers are; you'll need to *add up all of those distances*. For example, if you pair up a `3` from the left list with a `7` from the right list, the distance apart is `4`; if you pair up a `9` with a `3`, the distance apart is `6`.
+
+
+In the example list above, the pairs and distances would be as follows:
+
+
+* The smallest number in the left list is `1`, and the smallest number in the right list is `3`. The distance between them is `*2*`.
+* The second-smallest number in the left list is `2`, and the second-smallest number in the right list is another `3`. The distance between them is `*1*`.
+* The third-smallest number in both lists is `3`, so the distance between them is `*0*`.
+* The next numbers to pair up are `3` and `4`, a distance of `*1*`.
+* The fifth-smallest numbers in each list are `3` and `5`, a distance of `*2*`.
+* Finally, the largest number in the left list is `4`, while the largest number in the right list is `9`; these are a distance `*5*` apart.
+
+
+To find the *total distance* between the left list and the right list, add up the distances between all of the pairs you found. In the example above, this is `2 + 1 + 0 + 1 + 2 + 5`, a total distance of `*11*`!
+
+
+Your actual left and right lists contain many location IDs. *What is the total distance between your lists?*
+
+
+--- Part Two ---
+----------------
+
+Your analysis only confirmed what everyone feared: the two lists of location IDs are indeed very different.
+
+
+Or are they?
+
+
+The Historians can't agree on which group made the mistakes *or* how to read most of the Chief's handwriting, but in the commotion you notice an interesting detail: a lot of location IDs appear in both lists! Maybe the other numbers aren't location IDs at all but rather misinterpreted handwriting.
+
+
+This time, you'll need to figure out exactly how often each number from the left list appears in the right list. Calculate a total *similarity score* by adding up each number in the left list after multiplying it by the number of times that number appears in the right list.
+
+
+Here are the same example lists again:
+
+
+
+```
+3   4
+4   3
+2   5
+1   3
+3   9
+3   3
+
+```
+
+For these example lists, here is the process of finding the similarity score:
+
+
+* The first number in the left list is `3`. It appears in the right list three times, so the similarity score increases by `3 * 3 = *9*`.
+* The second number in the left list is `4`. It appears in the right list once, so the similarity score increases by `4 * 1 = *4*`.
+* The third number in the left list is `2`. It does not appear in the right list, so the similarity score does not increase (`2 * 0 = 0`).
+* The fourth number, `1`, also does not appear in the right list.
+* The fifth number, `3`, appears in the right list three times; the similarity score increases by `*9*`.
+* The last number, `3`, appears in the right list three times; the similarity score again increases by `*9*`.
+
+
+So, for these example lists, the similarity score at the end of this process is `*31*` (`9 + 4 + 0 + 0 + 9 + 9`).
+
+
+Once again consider your left and right lists. *What is their similarity score?*
+
+

+ 97 - 0
aoc2024/day1/day1.go

@@ -0,0 +1,97 @@
+package main
+
+import (
+	"bufio"
+	"flag"
+	"fmt"
+	"math"
+	"os"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+func readInput(filename string, v bool) ([]int, []int, error) {
+	file, err := os.Open(filename)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer file.Close()
+
+	var leftList, rightList []int
+	reader := bufio.NewReader(file)
+
+	for {
+		line, _, err := reader.ReadLine()
+		if len(line) == 0 {
+			break
+		}
+		numbers := strings.Fields(string(line))
+		if v {
+			fmt.Println(numbers)
+		}
+		if len(numbers) != 2 {
+			return nil, nil, fmt.Errorf("invalid line format: %s", line)
+		}
+
+		// Convert the numbers to integers
+		leftNum, err := strconv.Atoi(numbers[0])
+		if err != nil {
+			return nil, nil, err
+		}
+		rightNum, err := strconv.Atoi(numbers[1])
+		if err != nil {
+			return nil, nil, err
+		}
+
+		leftList = append(leftList, leftNum)
+		rightList = append(rightList, rightNum)
+	}
+
+	return leftList, rightList, nil
+}
+
+func totalDistance(leftList, rightList []int) int {
+	sort.Ints(leftList)
+	sort.Ints(rightList)
+
+	total := 0
+	for i := 0; i < len(leftList); i++ {
+		total += int(math.Abs(float64(leftList[i] - rightList[i])))
+	}
+
+	return total
+}
+
+func similarityScore(leftList, rightList []int) int {
+	rightFrequency := make(map[int]int)
+	for _, num := range rightList {
+		rightFrequency[num]++
+	}
+
+	total := 0
+	for _, num := range leftList {
+		total += num * rightFrequency[num]
+	}
+
+	return total
+}
+
+func main() {
+	args := flag.String("filename", "input", "example or input, just type the filename")
+	// Read input from file
+	flag.Parse()
+
+	filename := fmt.Sprint(*args + ".txt")
+	leftList, rightList, err := readInput(filename, true)
+	if err != nil {
+		fmt.Println("Error reading input:", err)
+		return
+	}
+
+	// Calculate and print the result
+	result1 := totalDistance(leftList, rightList)
+	result2 := similarityScore(leftList, rightList)
+	fmt.Println("Part 1 Total Distance:", result1)
+	fmt.Println("Part 2 Total Similarity:", result2)
+}

+ 0 - 0
aoc2024/day1/day1.py


+ 17 - 0
aoc2024/day1/day1_test.go

@@ -0,0 +1,17 @@
+package main
+
+import (
+	"testing"
+)
+
+func BenchmarkExample(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		readInput("example.txt", false)
+	}
+}
+
+func BenchmarkInput(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		readInput("input.txt", false)
+	}
+}

+ 6 - 0
aoc2024/day1/example.txt

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

+ 1000 - 0
aoc2024/day1/input.txt

@@ -0,0 +1,1000 @@
+88450   63363
+58674   73195
+30431   97265
+79176   36224
+51071   64526
+78115   34829
+26281   65342
+99747   75563
+81068   41201
+81760   39590
+91539   66113
+51799   96883
+69353   19440
+64094   96883
+27283   88579
+52983   37831
+36638   37255
+68035   36007
+26604   96883
+43449   69865
+90472   75289
+20731   35412
+31769   42457
+37135   22483
+64018   44347
+49545   45637
+87888   11937
+89770   85917
+39164   26074
+34963   57264
+69433   87585
+89828   75289
+51940   30644
+76011   76423
+86044   69863
+42178   81634
+58537   84529
+68039   39015
+91534   80235
+95383   26816
+72575   20171
+63014   53853
+32766   84529
+21621   89301
+65716   94131
+74270   26729
+73720   99746
+22637   82429
+96044   16327
+93882   19601
+49123   36007
+59778   64129
+62853   55358
+72347   80203
+48833   47045
+64129   62494
+21955   96883
+92027   12818
+38750   29622
+16496   92138
+68900   26494
+13007   75255
+15450   75255
+82750   57264
+35089   36007
+60190   26729
+92533   72231
+95863   46766
+28192   34386
+36229   31291
+84353   84529
+85760   94567
+68643   63363
+47794   81334
+26171   63475
+14558   25238
+73997   72059
+56966   79382
+26572   86541
+15302   89301
+25557   89301
+52311   84529
+83219   10771
+47897   38681
+51489   33757
+10737   70282
+14395   57593
+75289   33474
+50622   53826
+33690   96463
+88570   36007
+88810   37995
+76440   71407
+96318   30287
+17056   63363
+90971   75246
+26526   85772
+64411   41201
+41386   10166
+16374   92034
+69742   91071
+71716   23782
+52237   32193
+63724   35412
+29598   55182
+58958   55182
+70562   56476
+99313   47299
+99705   70328
+38730   36007
+93620   29617
+64261   33757
+37597   26576
+86139   77794
+81816   20568
+25422   63744
+41188   26729
+91310   94596
+42798   61799
+12672   96315
+51173   45929
+23901   79382
+86756   95419
+72786   33757
+21624   90149
+81152   20260
+76279   75816
+86686   60299
+96883   79162
+52777   54244
+44760   69775
+48872   50008
+13502   66090
+39968   94596
+49634   17015
+90616   79382
+98097   94596
+94918   36224
+71745   76703
+63978   94596
+96485   96984
+34269   66751
+86448   64129
+40845   35412
+24852   28792
+49514   37277
+60306   41587
+19242   81203
+42110   55182
+88579   19310
+14788   36076
+22896   77018
+53083   89301
+21419   62087
+16682   40987
+45509   63363
+19280   80435
+35886   81329
+25186   22123
+72836   88497
+97528   96823
+72387   18771
+83455   86201
+33568   86544
+30442   94455
+83110   29374
+49301   88579
+34315   69117
+41298   86008
+55295   97010
+35412   88552
+52239   68865
+31395   26729
+26416   51263
+62441   69129
+43014   92675
+73780   55669
+59350   99109
+61061   22458
+41617   18191
+49483   35412
+58955   33400
+36007   37276
+10241   35159
+46681   33757
+89126   36224
+33265   38854
+95319   13101
+73018   20969
+60322   26729
+50982   88579
+12810   57845
+16293   33757
+74375   28399
+63806   18191
+66212   85298
+65902   32364
+88549   12193
+41289   15659
+68097   14208
+88017   30570
+73445   22551
+38360   15738
+39931   47827
+30391   46615
+46148   17015
+50563   33757
+55685   74778
+88469   69721
+22810   57264
+32215   74778
+59903   15150
+17397   57264
+10767   17015
+99371   18191
+90831   51790
+65156   94131
+97534   74778
+91168   84518
+26858   70445
+29539   87613
+30333   71407
+99445   73344
+16567   94131
+32900   69357
+27489   63148
+46422   63363
+91270   37691
+19540   53813
+65489   45632
+76210   98226
+29062   27996
+41201   74778
+45915   88579
+94945   81121
+54375   41217
+21536   17358
+75870   30864
+79743   89214
+20691   94596
+10352   83523
+83970   30864
+98914   18386
+58938   55182
+51275   11339
+86583   95003
+69981   47537
+27674   84373
+43824   47258
+87336   25451
+56054   20831
+33272   54103
+36755   63991
+73434   10847
+36649   82725
+80713   71407
+13544   74784
+27841   88579
+84003   22246
+48985   68185
+10176   71407
+58353   22559
+15647   74778
+68910   41553
+46401   31790
+80269   22871
+86290   47068
+95993   10051
+44568   41201
+44398   66153
+41393   84557
+30042   18191
+31917   38515
+13513   59458
+71906   89301
+75883   73018
+95352   64129
+14275   63363
+69876   35412
+16298   31473
+30864   79382
+19877   81988
+22165   16975
+62660   18191
+72656   13418
+81487   69274
+72705   79382
+22301   88579
+81495   94131
+88386   77944
+71675   21687
+34867   50027
+41331   74778
+53633   96823
+54664   42918
+29793   43797
+68537   94131
+46224   88579
+36246   75957
+68342   16975
+94273   33645
+97185   26729
+23728   63363
+68264   29231
+79652   26729
+89531   20323
+98937   94073
+91690   94596
+48648   67496
+32882   40888
+57264   71920
+13447   95151
+35448   64129
+75778   98592
+23234   27536
+49904   64383
+26513   17296
+91793   13262
+27874   74776
+66884   71407
+45213   64129
+40497   84529
+76273   23793
+39230   36224
+89266   29166
+35518   85657
+16168   94208
+20476   58668
+87694   93276
+45088   29626
+60101   92034
+33643   46999
+84013   36057
+45702   52055
+82641   36007
+20831   96883
+77611   96823
+82075   84749
+56470   18508
+19621   11287
+59631   21505
+64405   73018
+19772   36007
+86905   95374
+17583   26729
+53767   33757
+37207   40318
+94596   73018
+51890   38283
+52083   30246
+10991   37453
+33366   61295
+70856   40290
+84010   75289
+95694   77859
+57389   49009
+38239   36007
+92555   55182
+83182   98585
+66779   73018
+89448   30783
+82430   55798
+96968   63363
+93774   96883
+85440   59291
+94915   76935
+81147   25407
+71130   91090
+74977   84529
+74557   55182
+22159   75441
+31266   66927
+98350   20323
+13272   26729
+95602   91096
+88655   10128
+74822   68720
+11346   89301
+52663   28749
+20323   61116
+94621   75255
+27159   42996
+61249   44166
+22861   88579
+64142   83623
+29355   22533
+23153   94131
+28248   36007
+70448   60535
+53405   20323
+38065   92034
+37806   32005
+88000   43943
+72790   84856
+33687   34647
+11417   69129
+53871   63990
+45748   51721
+95328   16975
+59125   16975
+12587   96823
+94131   34262
+42511   38283
+52071   60452
+73868   33171
+38312   38283
+98418   56577
+85457   88579
+16464   89301
+76815   24744
+28900   88027
+49734   96738
+92985   57264
+86926   74778
+93208   57264
+41938   88579
+67527   93270
+49205   26792
+41165   20323
+40200   81976
+59357   20831
+75079   97383
+60169   63363
+92074   10369
+18585   96883
+43719   65952
+71503   61691
+20439   41201
+50067   42595
+89766   94596
+20035   79104
+29197   34472
+82716   92034
+15062   84529
+91337   41587
+23698   74778
+86500   64129
+52046   28042
+40868   67872
+96384   34853
+60434   73018
+56290   14749
+57746   40512
+18898   68267
+51209   38283
+67029   49628
+40530   26729
+63443   70371
+69441   72474
+73700   35412
+41594   24791
+51804   75289
+45731   16482
+36815   74778
+47389   36007
+34424   48448
+31341   35412
+69202   64129
+47466   45163
+13481   35412
+82208   62440
+52875   24907
+38932   57264
+10312   89301
+99845   66120
+26735   67913
+90820   80814
+64199   30409
+99821   35412
+80212   79866
+54094   23997
+94967   55182
+18831   76412
+69611   88579
+20794   42343
+18926   33757
+17242   60919
+78473   69441
+13515   33757
+84378   73018
+18489   67992
+12314   67269
+29089   69129
+68433   57264
+87740   17015
+78290   55182
+83596   83443
+16316   58265
+45777   36224
+50505   26729
+73351   49921
+23112   72074
+29172   74778
+11572   73018
+63218   98846
+10094   81881
+46797   75255
+27552   29062
+31740   42212
+52505   37612
+84303   79266
+18826   17378
+80340   36224
+69924   35412
+37554   25059
+57758   88579
+12994   75289
+28474   89301
+98133   96823
+59181   89301
+19715   20323
+57509   14174
+48026   73018
+10803   76950
+34768   17015
+73776   75743
+23928   29064
+20765   52954
+44968   17011
+47992   55182
+22902   87954
+42359   79382
+38908   65592
+94050   89301
+25874   89204
+10650   71407
+39759   24477
+17442   70977
+73455   63363
+43244   51733
+36224   63523
+24323   24865
+40462   80381
+77474   80809
+57622   13765
+47172   32125
+51053   71446
+38866   75255
+14536   81935
+18191   34338
+50783   94131
+32218   73018
+65928   98893
+33554   43527
+48966   94596
+68980   96823
+92199   17370
+47624   98708
+81484   96883
+36264   10166
+86887   41536
+56559   20799
+69481   15846
+95563   48609
+48042   94131
+89886   41856
+32235   91508
+75609   74778
+93104   49394
+78119   56999
+73185   31883
+66947   35412
+10279   82579
+74932   79382
+46673   94131
+16885   64129
+50651   42094
+79768   51705
+55122   69129
+75702   26729
+42522   92034
+81922   17576
+67535   92034
+56847   84529
+95298   36007
+79649   30220
+80679   88023
+39366   94131
+72233   72394
+45780   71407
+27048   34309
+72918   27570
+11115   79811
+18720   16379
+78049   89301
+25027   30864
+39170   73018
+72551   36224
+38283   63363
+71042   39139
+93626   65171
+97077   69322
+44993   88579
+99937   36007
+92127   79382
+89301   64129
+34485   96823
+70901   63363
+93765   64129
+22641   47498
+96940   94131
+69328   77254
+48593   33757
+62393   76585
+50116   55182
+31287   88361
+46213   35412
+86316   45354
+52095   63363
+73009   39645
+76994   36224
+52768   96883
+58014   91861
+38328   79382
+86656   28792
+24198   35412
+20644   96823
+80856   48773
+85514   69129
+78541   79504
+89198   69441
+66843   19369
+42847   80534
+10506   71407
+53734   50401
+56950   33757
+10097   42731
+11735   35718
+47055   15050
+62723   96459
+46747   45849
+85689   45896
+26070   33757
+24973   79382
+98067   40236
+10839   60254
+83064   71407
+11426   41587
+53675   88894
+42916   17015
+26729   56376
+85296   18191
+70877   88315
+59363   94131
+90177   91923
+65577   26729
+22974   84529
+82930   88579
+48640   69441
+77227   69768
+21808   71796
+12093   36292
+57834   26729
+85449   79076
+31321   58970
+29147   21478
+54452   96883
+36762   94179
+77729   30525
+38806   95982
+16975   12420
+59754   38283
+92634   96918
+75255   72045
+20579   94596
+10838   30864
+72028   33757
+34045   31285
+10166   54162
+39450   17015
+79156   64765
+99772   88914
+66119   58424
+84505   57996
+79335   23710
+22607   18562
+70069   69129
+56842   82046
+51924   26981
+53971   60458
+63946   36630
+58512   69441
+83844   84320
+73324   33757
+49874   14478
+96638   88579
+25651   92034
+35046   63158
+45863   50172
+33827   11916
+74271   71407
+92141   80677
+26165   94596
+29156   91383
+14258   65553
+99336   57264
+56949   19178
+29951   94131
+80133   26729
+69937   64129
+27282   35509
+37999   64333
+35714   32970
+74778   82464
+65706   63363
+28826   35412
+43880   57264
+65365   11878
+60998   53456
+23464   96883
+63996   71407
+47988   62639
+72134   68309
+43808   17923
+71794   64129
+55139   44545
+68486   70532
+88866   19086
+31014   73174
+25100   32701
+23168   77965
+86321   46763
+56564   97150
+66443   94876
+34574   26729
+18319   55182
+52080   63363
+34903   57264
+10503   73018
+73547   18191
+71407   36363
+14066   10066
+55291   38283
+49333   73182
+85590   31911
+31583   92034
+56885   94596
+10853   84529
+54330   26729
+60526   60376
+73313   37560
+64827   21896
+54707   41377
+78727   89301
+81267   42594
+97418   54093
+48561   90307
+27700   98842
+88852   25642
+27571   26729
+30253   18191
+96823   11966
+15510   28792
+34473   10074
+19128   92715
+66281   16359
+87566   55338
+73327   15839
+90546   73018
+10731   88579
+33757   35881
+53264   77702
+27559   14286
+76671   43247
+14652   56992
+66269   16975
+68360   35412
+47909   37394
+34184   27993
+56983   96823
+46159   47334
+17929   19802
+19939   33757
+54638   51325
+81041   71407
+82318   16975
+36922   87710
+37124   35412
+97802   99288
+44780   41201
+41587   29901
+79382   94596
+58560   24533
+49390   75255
+64184   64129
+63363   13174
+31139   94913
+41545   45809
+31298   79382
+27867   20831
+31915   89301
+57731   54824
+16568   39610
+37837   71407
+67097   36007
+66230   62450
+72316   10166
+93233   90637
+53568   38068
+30604   35412
+52867   72154
+94676   13310
+64541   64129
+75970   94040
+84132   63836
+23468   69030
+41002   63111
+25437   73018
+73367   89016
+61905   28740
+58157   57264
+40049   75255
+88306   88579
+41571   13741
+63613   86935
+81673   72916
+55528   60139
+27726   79382
+76018   20831
+93265   23625
+67182   26729
+21149   13330
+25611   84529
+84359   94134
+98940   88075
+91702   53729
+49126   92878
+67287   87543
+13917   96823
+38327   71407
+94612   12864
+55182   45518
+43277   74778
+31570   15210
+75076   69063
+80682   89301
+22072   69129
+12519   75255
+76313   64129
+67075   96823
+65234   57699
+43693   72346
+89876   29062
+17665   92034
+33737   36661
+91753   36730
+59183   43449
+14540   67538
+74552   79382
+12545   26729
+51062   30818
+96261   36224
+17961   86727
+41550   88380
+44693   18191
+56353   97146
+26427   68693
+10521   55270
+50199   78554
+55779   71477
+13694   71407
+84529   35412
+28117   94596
+28792   79382
+86182   23320
+72131   80477
+49826   74426
+34390   74778
+74094   16341
+69129   34543
+50073   92706
+37199   88579
+37972   32503
+88066   55182
+84391   31812
+33375   89622
+84125   64129
+68050   62191
+80017   35566
+89775   80938
+43499   69441
+93020   48741
+28839   69441
+65343   71722
+82862   46646
+35994   75255
+94975   88579
+66142   36828
+65082   26265
+85699   45338
+49094   65410
+89012   69332
+12731   32597
+12574   50774
+23300   79382
+59711   20831
+48379   19665
+26444   73931
+94298   55575
+64549   25462
+85255   33757
+18260   15074
+89345   39774
+47964   96883
+30500   75255
+40701   13580
+85115   63598
+56810   57264
+49698   74778
+60564   57264
+16225   71407
+89966   85122
+61233   14073
+31511   41588
+33945   73524
+98473   31768
+41456   64129
+85038   87448
+73588   96883
+25283   86498
+33280   13657
+49275   20323
+87664   77882
+47908   57264
+33245   58814
+42158   28925
+22933   72601
+60641   63363
+79702   44349
+78739   17205
+22561   96035
+43533   21008
+71914   12918
+14862   15368
+17015   89301
+73903   93498
+43166   85414
+90888   78097
+43451   33757
+99167   55182
+71516   86059
+51747   78573
+37581   94131
+12993   79382
+32228   96328
+69475   33757
+54981   23543
+81379   33567
+80367   35412
+58566   94131
+26053   35412
+77442   80466
+70340   17984
+83405   14607
+59197   85280
+98773   49233
+32734   94596
+53611   52671
+45926   94927
+53823   53295
+31731   20323
+97782   95936
+92678   43308
+98973   47522
+63484   89301
+29604   60237
+74422   93965
+80370   58449
+89621   75255
+27363   31734
+11198   90186
+88033   42157
+93444   24578
+35116   55182
+16393   73018
+33628   38645
+67211   57264
+24757   20323
+73181   35191
+24567   76180
+84081   15390
+34345   10519
+21185   17015
+33414   96823
+30310   72888
+24352   57264
+56004   14161
+14492   39140
+47871   75255
+42912   92034
+91823   36007
+46731   73158
+24112   74778
+92034   95808
+77157   89301
+29215   99938
+37580   89301
+73593   36007
+11075   96823
+49084   34885

+ 3 - 0
aoc2024/go.mod

@@ -0,0 +1,3 @@
+module aoc2024
+
+go 1.23.3