bp-aoc-2022/2023/17.py

215 lines
21 KiB
Python

garbage = """222121221125545442551354433121526425256135462244521145435534754273766414422352566611173565254633655234633532614263351511443421253152344411142
344142321144343113114443312252464244613133242216212561236744564126151267757561763515131375662365415443364352425141212343145112215215511141224
441422133512325311441433351556523126645443151336244236622317413476361435642512671235371314132135121213141141656134432452434133111145144131412
414111443322112341211443226663351133662251644146532727245365327154452744667325663152763177747141424455263212362141122662422552434353241423324
411311212242124523143125243632315541642642262264136337334672477667475611146413273551112743164151522465563322461152132531334335133534542132132
321122151351122225153114363213366265626621115315745247663575425716426725447526531567372741246522574122626252513255556342334454551215425553314
222344543451153434554656335346216661355742647532375733512113644715574656743663267621426535471555255377346441115161611531236513133215334542222
424413423352513131223245121556146213611374676625544254362266777363612725532275672737136557255565747446535165226525616365612611535521515433134
431451451125542325342416445235353211655554633275544463321132655774261556172535541166222151166276112356274615452424263215242162523355221532433
415431453153514333335651214334135231232571764666675252741545514221727562562773756234133422172621526122763477244311421664632251444535122455532
453354515221515151544145661512335236226155242623135776566271848525823834474742441284453157567765772573655251136651624151254422525554513423442
111251243245532541234645342523325455512724636276247174118161825685547483762684441515848364676621422673556343715533324666565332152243113222511
111334534133235522166163642623256237672415565114775575374383328153235266845466485833187225631764631246571144523511625666632462332331333353354
133554531512152455344145545211212256511553542467174471454364731718353838418633184182651667374774344521735243627124141354151351335563422211233
351313145245643433522454423356674434251561731723323871242663244821682621542465213661172154522583466446476362633631543625424531653162231443541
523213452215134311233415452744217472277446126762374527832155848154815377584423245742686675835552512114617665565266277164626455645653215423221
421143453365251251362566736717516327574475222722228574536523462275766527152738267844812633434621753622131346173524466551235633253343532154453
454431124534624655515546346667536513715713387528627274286467556378683261325548386332133441231368728765222762675664454731462221263615332332535
345211553515533654334677757111263671753535383176573738475482422167238416533755712458624477183778534288626353765351133276465223242315114545254
524225553333453612235554431325336274552657716236758247872428475577736841335713334163571255148237851333623627175551466316735541221425166152431
313441254324113655642131612647751467735557556431135168313367733697695326195866635432532542781152342574855613172215434547377324351145612613312
513254365665214351425216331672416414186423585784526323538576921178526962198855643637754334213656253576277622667334577774551226656215641622234
425454234646226555262471412354554143581423468714438625749267326441584124444336971688572981561137814356654424635376167466127255666356653325241
223534224614216632371553266316151156444874446212657491442878539931921211878421973257995927977112625877222556267211563134637774623526262445352
535651645643163445274751757555163641823156164172521178341768742214453793355497735179123229321174146536533246632712425571155767324445124122133
331515523432411451251654635325437433361375471866818786226959967795518464371693551281564876431557813458242436331154324561422147245323346115241
424662265614341346267537765417561854452155616544125534968712941327879273731337187813791345843478974443817572143334513251261712674261566563134
563241661226163746513133637118862617166688619979855524888424565541351139533373483416977717869257847783566611451476374266474756154114144161546
351143323323242361243144174341168737716772244923696933877656678812883771565187141555374487432878435515765136884718335441126135731651336152666
452434251323436214332544751511581161188446976215677984365192714649427421349715344618752957937781121666753345156633613371256376615556634651533
626151661264654712341126112727188133128475544463391252688139368168322538986238435842636557711511884942343171487577428663165373151141356466325
233124223653613525141353666387224345542367184137456186263621557926489652299292562222224615652488272899684283736384452466432371243374644534424
633442413227264452253117384235752663727323354763226337815846742384289643225778623386639519716999442245666438575546123866312312226732124533566
542245644243363244424544674185578756889143929986122569589584843749264724473356576638252279588724366251364592443512546312533165443123656232523
553166262126764642747412786445837127684733425725441427446584463655465327287838897649428252265389952569338317424123585815771776765557556253651
631316366355213136334764342221377266232161778815792996637762843744938823222656753734936724989977475972197312871735771242766326524274732361463
533126226771445113352111883621213394746398258533956632965545222339837838472567952865337877329439274921999421294748518778883376645712541261623
161235671121227167354576827568773582122887396473896449424437574542476549265599582368994293822549137841425889135356286763774723431476547524312
135613151547135641371565561556372189343562437734734752989277789734736797836587446347242992844358292876465772465768637324885242711525355411655
351522766647342722424751774543171774314573318563357463222963624985862569988948669252354749488736272394116155194543221367487854547112226246361
451161571435225612858144376145321227386686479798259227448564865794362558432583995232836732597637445511726264178751266552572651164225463352556
125123761163451724588522873282279473575477625484469878324484593735478445384537357625445789667593729319841424696251712577262721652126167425526
455143516376274615135416445648291754889711575868726458979923536338543386435437445364936625392878797571962859592231462527277332451755215734324
112116162262355262313454835861887713364448774752228963872446643483733998448774888975695637974759532562232676892623188775875855363133213764151
416325736251277144485257567385557968124376979892494348876354695595498536779336496635767492759555383968913422468979921328867838134556175477642
343327225742767555326137427177467411398895547532592426858748385987966897857473447935574762255484459258639717855697312467811238725714562324145
613641657622444365336614848975234359353776624376882995935795743343957687748343443895999349939787542876339145422152347655564886385271723437132
133113162462432167885852112598932161712853958875725873753895875484363938797987383856758847524726296456836255736949522487554587875752257363346
121242215256544381265784156658297689288599535827374777855778487777869779995839397569639938354948938755663862438648356643461317236771216275143
644314272374432371855212181923272546524994959277768363943959564973348843474685853695537847369344487687977272687417939132441561141153675532732
527741152741153422816223743123623488985427495547669757758745588454463639988664748448968583856489752975784764875653457798627374515243356112561
161661456531367418871482873267145173486383258785344594983684563856975947787453775757746768845842369993457544385384641378582823245532111125526
667427267156244342285142475133111337768242654236443538398797577559689964584474869694495578986869775273745925544444212579266431326517543157256
655316612362786245245814217772915227546377546258644663498354457986578449949896977938764535933963472864975239268955558872183512753261531772144
144673172344338786868116226684563862764363897443489689399595895597676954486548657554584977768653796595689824691385352273355588557451567776775
211714635726264561367423918287264748546426576564868783568546476789874866684459886655699893336698564769492244578714241438565227165858425435725
117262732448166452136525347556938732737866249754587665476946575756764987956489687699875585439383764786649532799973631795187587457421654237153
667572423753254457644563196798659476378482893754675997667674567645489885995854855445544547948976498384876634959612629639673116153767734721344
554377157763111615451663724292964779286735883465895945367754854475868795449956956795547485997448648639985232882978314212213112453788113576231
472721737525448123485739964261737477985658346747735393686764997476864899688685745685455538683848656859888932269359111243527578286444712422636
716136274534887761176928426121964234636626887577394457648657998457969757665747678944774553947433934365763368349517742553356421766334254627332
325525561332461542872389643691124587585558477846789866564978668769555866765467444744468988847489533839289879543456386181824174117324517332412
417442355541237223236155781712828685977243797448379845497848484678657879685868664979888574698337578444423572888327428694147243336551541454665
741466471466778128552231734696832628695937534998537666744679988947896595969655844798499847876469778478437637749368124651465845562111552737166
131716524445418325624292529874499836273474594358948365769766955468769655956969966644544647665448387989698342622355257658952822853351532223546
722653611276335452176557276178322247257283983345868646847955574767656576956679688776749697753994798879768694592942675931983661786317815333744
557245554186156472871489427315555823794326998596444775964474858688589955798566598855555876996967643933836298733455423183242563162588533667645
764555551452325835211646856691824443557737483648756865587498586958567667898677557657865585545346896658975364992535463368341468353411387536424
631273117847475346356999711637933569826855449653859487879846586557887978668766657887846858575347699648268526738844726835419232635833874252257
577612754581428423316977663137253537358248476374889649948465769966568868586588588568466569457953374859868464285599363577412172847318572314464
632246124352335726547263578612464342829574356864937779746954959867768755588659955785989886485638573949368669253247285138229768716354737445742
664567433662157611854926285984834934245389935938369847759857765989887679978886569797549465645583875798967923683464659283834161543121835414113
276466614468374122684193564734649347979765683465937899445557569758768886585597568855796588749388977897633936869856263884632215387471833524642
177576343762811518267653656191986958599674968497687464897487557678786655669579897778948584969975534398737282983486825738687164338685122431667
112162513784621281655757339327478323642978874367765954586658855679788975585658857966585889585483668543256624239268127256427147236114335441534
147353362622573867855275372213943289523646466633973668958764579978886775786797997468796677753875884787467522735972815512614831715862524266744
126446557128515554556478211474385866926389685436955776585554746979897978679668596987854997775934454654558985256324578248691778135612141555675
671126254418762253521316521184238276472754593734833387565865679665688787685598874555775467847657746957768883989797641543597438166741225414332
457313557758258274384896397537958856582937538335384794484954675596999999587988546467958545557498956498937998928583547615156817511687762167142
656232325748645485769479114392948863367484535695885987985645776885665898995575457447946666968644799973764628985329185793277487512627423747733
761254673324625124352857194925365287889752746886974847568884995588889557986775779689574758843494595694435798672216734838533835357856336724255
144372111363255661146867245582389289644345846855496445846548558955468875677785745889864754733699998637525943854924443855654116551445712176453
376425664771525153744381352787668993574224648454683575976774577748676696476965585644846846479673659895525382842839684131674233311732172174466
222342366531343851233789683727147898683625395366865865384554986785864444755755557877868574837966989635572593764117925434683432151381656425424
413166741614635325683515483498252755367476533358363683847578785959798459499579444575756966659565495475838884932945642119613442217481673433144
142224122655344248548716234815836227765859534776676779944667567468479594976755445455896599777677739378552349968998119425287436875112466235424
215225474745135247155124751949758657236522323995374597563799755765586655757997779944944669436683777946896383394597248179762467617633133261152
216247165476457851625645229833753544263976383877648388944646778599875765688699954486534444983364558533872748781869668395783533176868637142577
545533211453346825245522968546865583342667652544599894986596987849584559685544655763677995857835495538383538369845577888518775384464574113143
675214351164564558513422843865951229243747722593835459744453374595455589858896496787437739734953584685667447611994624731343315673275361634315
152124155651827618726637237533446355254975997263448994357887938887596654755457498739335357899639443894547635267531628869147575865827215641624
526755236461573542654255145473135712236928784484397893488633354358477948884547475665366947647449586494456324276476124392263678645145746254114
154324521264531552752673258685735882864756452229454678643645775839883398836937458337743469443992953535532891178133714757667327735765732231221
533572473241688226266614415933631588934343593672946339575699446878954349485554933953695434865797386593657547312353383765254585146536245255621
122272764271746887867632586157548869597952893592749844566477796389438445936988798994653576537569536779573215215167959944618177675344162252555
225417712776748542588544846299988264548747975634243293937459645683779386474773699977894786553669622245938453844166355326341876252145172312422
164132375165773175662428773691636383317559289935542434845354549855393747785379474794447769435393933755492749863197616126526841667647774212534
652174557216537531446217155297712138583877979349926225637494683747668596378953666668643354252522243287254612395662462564775342171162631311452
422646121144516841663882427817697351216833884358924764786833666453469655688479653798447869387244923856357227677662573388315822634712662153411
242246365532243251655138637611828976964574955967664924535294699989534458976863935373394577749234553468654942751359227232253572345473645337525
634255277221321587381641275279228275584178745298274842264254494395885586767599873779947449686926422736384535672319873255834216216616177127451
346147274276773576345267667242282855959937783683363369822335563437985546874694644789596826259924962926851483697475423435382232553724266141423
463422252214751244152628361144236579151194119386366632634983498533852576585748693882493242492872224885264771753786244358872863131314642314521
145541562617431523125115635564119183323936355358546773448464434965787775494855724637878346977737364959191122388948678537678235117436362221544
553635653577143761358364185563536963785882361747743556844653974372683656372335356556724598353469272462779732392225761243445772425624536464115
154115351657614327151848182822556587234829371761343348276456935939375399687267282283278278882245946724947415837582137413111163641512516734535
322441646316565661134377728267873614928149424315853495552554283964634585969674528572252936889535364878625724741753567545358253233762554124214
155215364611375253777426431146141499178828692652552869444795874485668885973764839428394756635755927828316661921212115118824545276411262113525
542422365713554142251615243348188376381495552556977952977838969465485646269829958768928747345696229272625827634134122888341544433276474222526
525264226355376432237372422181755221178861282762935925426987657758368224886269229394398657215468897621477671811775465845774744642762631111644
251464216571532573453616548421258771327976433699853527749289664449856367765922435269647932459696384176149171438216477412221764116544215652411
253336624357113227775246131582551131731237217659484521362597883982388784326825465678696142329292798836961847567651148262772453235176365124341
233541242144465637164532722787277554387561733988982979529113963192335842498357599826411331921635265149227866683357431157666245647176154234353
531633251242674324165344211523364686476487435225618168685425558913544358671256995442726735799471193634875762225855483226612231545561526552133
145264321651416336771753163356146416142666218338515859355544368316437819826794372277545916816195211123147111387464536356377475264631634365155
332336634423122573775157412168738243232868221935148763494299933657176595972276458797696673517182487615187873641713821677331117125436215134322
312232313115661645452216451727443571334577262781925231298241544745867972121422887346935212971857222512775435665483647721347525135632623646555
443655466364323717765666712476452844766617127847254134458447268116666394355444318294519669652938717537187442346456277441274437744511621644262
155652431331424436354432762315758768363847133758724341778582246828873482279181834189737517246284323754762854182871777141435541235566365443422
314223436343155561361547367152423133748536371865611569314176513425172933222745358593785959436238877128587738156722766475116155533652153545313
323543162562234354342143615714767751863571473224168813264961788822253955862276384349242583552381833643748813442514541756533125514661321446424
323213543345242346145466223765255625438188532455188533277833563833793468851766234643918687777863764333572314627516712451636413161456353132432
122413155262166125536531562444127176134186863137571344613376426649159139592972199742587453574228455331135887314162745555155253462664461125111
153424444231415451613636652377157532286782817522873285846114748567885868812476326616212857261257525125361552724761365513351225365346262434233
524315122655322124241275124423274145435632114786568311323671121582511537134837652583477777641741765113265724534735253351653552113532511353121
412311441243216514654316537663616245455146422434517158111482664622523858471421337815562851666786226576414436535275526421211415434446315145235
432135553232624525221446636456745644626556317152728145876344326421671235564622621323573125316411586225125115446712147766222263512143213433112
341525414252424435565152176473317415313346648582317315267188761284125268878515363888836256526836713122772336735161263223533142651423523531231
432224422341515356663331662566144176416447261225427831175328825865128581811218267134425673418365371663677447542724666523131543145665435433131
553255135254664356645466445627417123552572423312387152473572744237741742637481781833758568335122653777731515717733732446151233526624533512331
453521315452232643126463645531665636246153711114751222575376645726732614487131784251185667536757561743751363754165224534511651415515133231122
322442512532234155345342132364526361646772264235563321753356172726447618438251564318263713147243764512532113637521151121353132221125324452255
244241233413455625654224164652136733174224743563641634143426734578287613758374427638533542174677535666311416251643414131632422163435511134331
333213542122322445152462412154424162514213324533334542557572125642188764817363273711533777723532517535411671615533141461622134551512243223551
444541112534344225466666242511463246234362655327614567312551656447232765625566545626445722754733516655673632223251641563453621325253124553511
314311534455514223413264343142343565545574451733233673161656672447612673453255425247242433631526445264447643523253164134151314522312124125434
212234235454113513353545113126623616166527465317544272142755613252543713756631641747412773312546661556454443452332465161112541331244552512341
342422212345235554145122362522546215235626733517351171264445241275512625674552142371176332511714141317565611431524121222211142411123234342214
112324252444352435533342624135532554461123165474452442713113441633656247123272775664353226614573535143112451621563436646133414454432354442123
233341335314133142241454121462455423141113234226462651122255762156317662635734437361131455723125121134223142621154353543341335111233315421112
332221421123152115115324541163451134364461344354353456121757577555134633137721533432424265625113364536134655252636625241322332523342121222333"""
garbage = [[int(ch) for ch in g.strip()] for g in garbage.splitlines()]
dirs = {(-1,0),(1,0),(0,1),(0,-1)}
size = (len(garbage), len(garbage[0]))
def isValid(y: int, x: int) -> bool:
Y, X = size
return 0 <= y < Y and 0 <= x < X
from collections import defaultdict
from typing import *
Offset = tuple[int, int]
Point = tuple[tuple[int, int], int, Offset]
start: Point = ((0,0), 0, (0, 0))
goal = (size[0]-1, size[1]-1)
def h(p: Point) -> int:
Y, X = goal
(y, x), _, _ = p
return abs(Y - y) + abs(X - x)
toDo = {start}
cameFrom: dict[Point, Point] = {}
def delta(a: Point, b: Point) -> Offset:
(y, x), _, _ = a
(Y, X), _, _ = b
return (Y - y), (X- x)
def getNext(here: Point) -> list[Offset]:
(y, x), straights, delta = here
steps = set(dirs)
if prev := cameFrom.get(here):
Dy, Dx = delta
steps.remove((-Dy,-Dx))
if straights == 2:
steps.remove((Dy, Dx))
else:
Dy, Dx = 0, 0
nexts: List[Point] = []
for dy, dx in steps:
Y, X = y + dy, x + dx
D = straights + 1 if (Dy, Dx) == (dy, dx) else 0
if isValid(Y, X):
nexts.append(((Y,X), D, (dy, dx)))
return nexts
gScore: dict[Point, int] = defaultdict(lambda: 9999)
gScore[start] = 0
fScore: dict[Point, int] = defaultdict(lambda: 9999)
fScore[start] = h(start)
while toDo:
# print(toDo)
here = min(toDo, key=lambda x: fScore[x])
toDo.remove(here)
if here[0] == goal:
break
for next in getNext(here):
(Y, X), _, _ = next
wouldBe_gScore: int = gScore[here] + garbage[Y][X]
if wouldBe_gScore < gScore[next]:
cameFrom[next] = here
gScore[next] = wouldBe_gScore
fScore[next] = wouldBe_gScore + h(next)
toDo.add(next)
print(gScore[here])