aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AoC2023/day17/eg-in13
-rw-r--r--AoC2023/day17/input141
-rw-r--r--AoC2023/day17/solver.lisp132
3 files changed, 286 insertions, 0 deletions
diff --git a/AoC2023/day17/eg-in b/AoC2023/day17/eg-in
new file mode 100644
index 0000000..f400d6e
--- /dev/null
+++ b/AoC2023/day17/eg-in
@@ -0,0 +1,13 @@
+2413432311323
+3215453535623
+3255245654254
+3446585845452
+4546657867536
+1438598798454
+4457876987766
+3637877979653
+4654967986887
+4564679986453
+1224686865563
+2546548887735
+4322674655533
diff --git a/AoC2023/day17/input b/AoC2023/day17/input
new file mode 100644
index 0000000..c0689bc
--- /dev/null
+++ b/AoC2023/day17/input
@@ -0,0 +1,141 @@
+534415514135453124461333615152111172677134533636656271274236365616565137415273525511165575327363331241741557653113666233613115623152664423332
+143153553532652144244555514665734545167762313231334475322557762622752145154167727645126513352223423415651656133121126453225343466255353344324
+431231423644152164112135132615556326276246113351777544176256511561764724256562566422367116247525362264766445567115621232144511654116644221442
+425112541336332234654342545214351652572172316456737222125677244536164452131262721226545725765227744454452372645522325411234233321414435114313
+333322512434455165453611427363633244553411531716322136116465566556725287838862767327666631213226747356156745324362547346612431145111316162222
+111514411336235512434444722163142532326377265214477474772227434242342487248563656855381764455575443361236276175665733434666412316634222625432
+141463114244415543252465174452177273546126747241275378348335524748634687254422624326485536775674735465743152735472613365122645655326361561134
+134653525652435431235625115231515114422634276355327264488345322457327577336525263756684486556413673514652631745334477413724124144242416562364
+434616262562242243346234454655134362454141337665258437457763523262865265676844582783487233862482357347212322641527462516415365134321145512424
+353433635165154445216737761473212433367151711344884646786288727388682537235754633528622423642343267676557653373252736324131431534241261612624
+535615234511545246516346262344152117454443774583448446657364527357552232352434576756858266262525523551653164511467127723215346233625622165551
+231653426453544512572173275441612612663732727322537445574356487336284775283336572372467376626887535687344753435441261141761331551664333532444
+236225356626321263631234733432532122217863566633725667447746588453345684243745863267773675523574827578685136411344611122414161343312335613311
+461442663642664613611212153714523655525727747886855882872352268628385875675656428682784745474866528478767465675454576242747556364563365533345
+235516112452617534221523251215633327684642774455582744454432653632663385788245473237856636588357775688555238612412764126237253373113125451211
+554126643325367353521466261744747333266574465262885865853664734835482232538827357464886342245884668488367534426742241621543122316311112143422
+234522524632163352713473132442554535244857335254754323244728372383524234632427343647438643288777723723447538538615457651524666555651133323553
+421261554413571373672433437574763482622586677388856845274774733653638779985648352732582782737337656453244353668867347455116615321754152551355
+351353342433572637145116624252437536486848242228584277342375854365493384594846835984253244438886785788423556782746626274532164152146451226411
+565564361172562162776327653656863878722422532276353247372336695938495676348577649877684384837355375252568666257834754374124472421164745256131
+244511514517375224665667415847488385867364744587645684567444899478367948453936433569898389277444822526553582555486471615744231363254776235525
+652231123276743453446765525768842635466257223326886959596965566977563679848768499386497935598725883564386578773876634317334376155476666666361
+345245346674114223653527462553638552564535727362364779936457969678493778946455544457554389938484785583632352473458263377762577143336473411611
+552332356127765265621174358564476888342482685288793375874696375865674397583436676496484594945959478537283242536427332483772374442134361626422
+544664154661637774671612856388833878588423434648656685779644585788369889539486837853367399757586957553246638464678374575426354675242173655231
+654664761756144662472474835855834643337643575954956454756888897566975879739687869679786677345687377654535233778635684687343237313445644316444
+634263424461271713551624366344576823288866938748445439359877487884667939977686534597945454845343888437227462467826648523786264337622226424353
+534213415514342132746272734737285627552459769494464677468358863997994876588384483784739443348534988434378735687243754252855245121611566552414
+355122664125227723657584672235778528835855996686857953596859554477547545793379466677864667539765633798988738384337784377745844677363654711732
+451422325171376461588422835654277873234597573963797648867697393465575359953985779866763935693657849885757872484472473354663766413125123116425
+147512513322221371582375845384746648976378649874469584566595439686588489397678738389363874888787646358993454837457822373726841637442143353742
+141735646163156428677787384268725769963479764954588699845558585487948796686489987745673587973768987468385489355376788865856366613213654642522
+753142372125655585458574476773623265377969854865338398634936774994444787445789948859777953686746484454675675365823773583453376314747433723146
+245741165457173375367474328273434489385936398553965897588676978864769895578556886689947899495557637368566938547737843727884854462267733116641
+375613234515634846466545642777365755453795357393577876695598897969846468468757674479655854896963498535988548556884652834655883682273147214633
+142334425663573763233676275843345697938553477537467464759569946578798565897685987549445888756748388657745485353386387227663425726776264536222
+767564476241124338562456283854764739563737343884848945786455459845865496987449966895748566577466368579359389887952773245638552665132432146247
+463376163734176445652626262675644877754446893657676454885864956448597499596686574544755588954697934488587684477693475458385324487421611722637
+342263463322646282757665638336586388666363837365679874675594977548656457484664755756449795469544648453994873854766476823882727678327753752743
+536735332312235682776826877553783699856378966889699966964784774876756656679464757499987699857775754777588835773395653723474737584784771111721
+443513421717782325685558455497447743798687484455746587687747485885766987648766946954747479956749563458637769787338496582846624785448364647457
+753474227124465665228478489473453899744356575469654569946744854954696845858878886794954758694657954647954959359669534873827685747672462515251
+666773657666348378827647379355936767948876947679556799489679669887486989565944456998489745848976699833349738396944355876672352832784464241155
+756277546626222245745368635866653447957845659595945845964659549947779889564878974487597446755956577666834539874978976947744422768766342631762
+213661414175386688225557549883756493984535966564858545675566765767967458947595746584954979759645588548965987873866369433574824364356865647623
+475232731233284282888284484565363366854689844644559645854858965885998559657775565656679845577769445767474378576883467978675588438642445244432
+445647145645642768385568686576858797736745578979749486765468599999556569859957586964459448744975555869754353886453585955777834222765323133664
+235557456253733727462485575776539655933954878445957898577958678785688955658676975698446975555979758765866654847379636544738687474828783113272
+441372758738567556557625995886765974997749798977978794644557558767698589685779599899994999758975985566995499676738695977574876455787484716541
+146433637657867633765369346677397965347675847545447969976699698765578679859577678599769555498554784889764585463945539556948842545685753217125
+465127582384587626363646996473775434854584597874669459767899976889775798699556986755887764558478744444746967385964594636358623772878283275312
+151364275768688482822979887983978368654988768445746678758856765576868669675879885597558755767789998644949765834357767477494467458587344836537
+215531732828587567752369839346579495474669469744599658997967678556589896568896657958858659968457946865556597877453984466747252368346276516124
+662513728842323542737634683376379586556864484999656685889895969958566559986958987679565696566878756558849448986596735353794443787685584781252
+523446885357236827248577378664659478999586866569477867567587565985576698568569978878667979896968799564757896656863973977667228857834256787356
+211311884258626284489634536357978888579475494697566565795757569957586575757796797578599577866597984997467449883986653574698538555647534287251
+466661736853662848357464753659894795557649797784959886857678779997585959769867956588896986875957765797784655855635599667948468453722587887424
+111312365225863284499986968566548849484466674544878859578796979586865777977957757786986685978765856785499976687845486996664586788738244423427
+516676232254833262768769468757544474889845796794857959656857589568567676676559755656595755999566644699458844654584566995859664754525573234734
+431142623233528247835635939793968687846795798578859585665955655988868989686778666789959685775667864978499688654474448688566477562428766376575
+744752732382447637675557544774786594864499878475668596965857658778796686969977999569658996578959569745955454969837788494794634734558736487132
+745342438238877336974635656794496898467587849466887659568588856668989766678967969767695687797676587769779978678649784653697586326842567744757
+511558425343666383989888374386845497985549767768967776755699897886788867978667789896579678595757995757496455586689746785665356436272232274874
+517388482454756428856774849647395997579444576876897597585987668967798887896997976778799576687969958694694854655977863788946485328384573885735
+155525775783888322494779755836365964487665989767965777789868897676786967888999779678689955858757585974447454596449973893339893782477456554345
+414135583473533472348796677746964957485456999888876886978878867989878879796668879768779987857879598649464456497568553563768898657327774852562
+246563665666434567734566795899959969765465859885787878875779998789878799977986699799886588579598585684648468775454978847495646436564862266347
+721765872733376428447398733987854688575957784658585756595579899978798676999789777896769855579956955785484477688985838887639387584372744832576
+341267842585563327386548739577954889658787478868695888556986986967777686799667787987787967788779888969877845885783658434554537828385837475276
+647534578864453238839885598334466485548987775569868585786968796867888687886696998667976959767685685944955987949584359764888686542226662533651
+671352655352423376848587599896565946785588687679956555697996776978667779886676887789757788869968589469558989978946388453573439338588887878575
+773347877454647328958545345989878475547689855769779777768687798877667978869777666976798975668879698976886584747859948554857358365342558386816
+474222633223386649873683946337959475569879697859679695685969688889676866766789669897986569977559865798649575968845737734358453445225752538565
+734467526268754489657844754745965979978964547997979588665888667899667697979898789768659996578766666944678859757965755398776564884633847735653
+121635723655736356439854587856574674598859567967966776767879686996799776986978688969866666756969667769446546744988563845954365564646683574555
+553455564664244582435793979683957776576876865887967759897698789999666687879899979698585896798579557958476764754784576974545345666646433535277
+572443376682437452569986763786684547947897485976779589778657867776787666897979678799679598969685998989485689596557473689736833583338772538443
+355425735685624285949664656689995695676798668687965568578886678869967776797779766887685857986666569958784694964779774856434534847876427833327
+256284528623652482678475496864775444668567778666576878556765687678999787666687677887789658995855559788699676996784683863948594435583773584317
+432667672286323844358788783784588999789488677779585956875668886679766678989799987958587975856757945794994794898559396639498895525555644526733
+721724477828346855977584387867654488494568456658999995559578567698877888778869798887875596896656695566667678969648968889583556446566785763656
+233724586442255363567669586745447976955569465769957895779599677688876686688668786687678655889858966644846877945979493333393586577565636285525
+164353383342837643243375573743785446587559644956655955757566675986989898899987776879557587755665465586846646587385947987459473277882686624217
+565615552853548658278684574495354868999778544646978987765787679877899696787798596865895767996788599979989457684345498537575466425857363577344
+345638656252748342759783375933956756584488888986977766989675895676799876877979565767968679686657454499856869988397765894994384562834667838467
+276464633643688525438848963996375876497759667649769967578577669575896777986785878556998565889979488447994498764798335873755946387647386525512
+556476548384684684747839463487747747677594499474576595898779999758866796585776759886965858755746846995766795976653668969959783533624474561716
+212147855848323775377774944587656698488794555859875598967989976985776588555555866698867577855796489796658644767835876766963823363486365587214
+263673778857574832648764734449445535744567448497459778677597566599869766656765857565896859999754658478975558478437475958444847845847476273744
+277173245483827546468738785757338546567649554479645655778957867866885995999596876955756998578487955486445556845876385553656278548368864853454
+346622225346485386555887553995389694598779685745655457756998757568777958966656676577999899779867655555897748584497989646873248468664855317362
+121564532233277785467583753698673764456478674948986445897598689759578886895878667796686599977686774986855974495963669656476725728684486246475
+727267373755567234376783444575783936676494959979964475575799866659969599756897976779865798845686498947858797884997685366438227426452525727224
+544314154452746278626779683776698388496656999794774878869686876989756687798859856569695546696654764997484765564793465593753756657424673645112
+426334173466474242576326976455988688774685598898876688474698698979878587678998978597959695499547657974957477634488643644654628642357645126715
+221164646742527333275258865488838554956796776454656649569655779675656956557679868979645596759877659969744684986483833796438784776777672444535
+276773631343388587538634786573364646757487464586455968447964488679899658757786667689855967648769967859789443377996348585427678846354674212555
+412765711352782282523537643489439646353657994468687664775658997986888668585558574847556486456575465684879488438554765376688766665652463231145
+261643766725828834835638353374944685754898794868958698974454889895556459864545868669699787965474688468757583763786935964575437863524456322324
+564744461547572345735766567587446969793798476859565846596869976868878595958645887698544979978858894564375459466569977587258267757583654755145
+571152457224545346785462736537659578388976485556494478497954994558794789449685487859545444867446674765565576834674976582237633633755833115657
+544243742657483528734476824455854585749959795549655554846777644449849755744784554768597599469549458535943659586549738764722227627247113674533
+465376454533465887782328464373539496444433376689568748879656679588657875979985754945479847494748669788474957993333495558862754882275517361356
+522322621562252546456278536847398793876444788798479684547767588595964476664494759564646558548687735683493588967658367324433447742287124454551
+754745177477547553447757642226496337774335895487988979857586455669469949769584688854546474799653989849543935898756576788787244358555631262267
+633716767167335633763823625659365464497635598768968988675757846669944657566444448944894694548848755879443674867377788377845564463846113372711
+771625161217123842748632367334558488575798675445794844994847467476867898555785468779759775667837969887446476385485428386854428238364656353455
+573163124275667733438428834356369879356846584785868438896479748788856645964966576548996869998837788758379474737453724553526238556135763452246
+723727545315762283447867476368348546385496955666674787875779994759568468957968989785798984436755669889954879796643463367436326236154445266135
+156132757137733552887547588722543874834866897443745339749665794586776885646899759884584467788768667369853963736858737556473582214663236721114
+671632221275173663768228645264555369399877384695855538534899854756498556779495697973457398593784783948455643485833583822838565253723565135257
+237655473243421665433644822854475846473746974765644955347585495667859979545876696958644443788537855668768449276543236877674458174341257711127
+435731365262641316665227486587283844346756574775677874499534998487987876689437557554456777386439768536843756462758384658258887726313711521241
+613311751267562472536846342365762357378444474497983935978575885936676364899959755856796583435534363867736547388663236457476351272751176751375
+423547215173421762125786572864653546375545683657564783447553476753478893688997596663438344697986539575784854728585287672742255751124541643323
+145515235317411572656357743633528662878548667354387847553686684498963934448633598365367766599766345873424334334778388678587173751363223615711
+232312761271227562413536578564848447252466393677443365548367793388663535648748559489934935578793686778233778252633832748575255475244651351716
+213221411636634731216722487428847864847744695445996383364364793899585686979695863867435549754853446436686745446562628572315154461516146515446
+132437367352246256527565357274656758625674565487337575895389538763857649765979488594697888867965394684274457388743764736571536116317224551224
+256346535731162646453573832224772648433633836785443833895633889444975577855979868348375559365635772233224556774552353753711414261632746143455
+134366355344175664142754446752768464562652524244249688948586897574665539499888694974745958535823367455382233686324826863721774142563453162543
+232521167626233775674441775355572237756262555387486675966785484954744857865639973874877576583274725757437785544482535171662457115144131356642
+535523551677464635576122764546285443426583345447328647379446733349879869463979947986693897776576274368676368623374463441224713635166567656322
+322554246276744511612756773585582344584388533824364675266783345399793854674435693886332378487228564643287886653285571223561126164434676232635
+133151525444131721267152434745367582475624526577543485874827268553547956497948985558268636462824482738878374373247745611327722224223516562164
+631113666321523115544756536623447836378675737477388484657467785742258365867785875347648572646383235437573357658646277371715771412637614613564
+613454432142746143246236746677746258526435255322868367366533448387566444222856357666444777253388426544473752443317652243566214327345531415111
+612552142334225716575367613772135736285434643266582676644278553428734447252373746338245386648224378542235327641417474274764425114344236654561
+566521154163322457512764656442315247474444466623647758737853344443466222847728583745538822776482775667884627272364424271734721746325642142641
+525433525365543323574127647653346564184466665437544833374488864824774274448577747533783768553354232856364621565362631775234372425263465413634
+641232642454261355565153272414365552253574756623558626286358742284346768687345838623743224473827446863626763421574575143445115131445425342443
+565615644253346552353573323243171115674268236734574476384323835756863446337746238734754823364243344332315322433524256212217414414524316232321
+144411644624563614616335155521431617445252863366554358636555762225656385543542577285355663277745374226126252535743144236225222326151213162114
+164465123453311466631745437761513754736163113523342655835562534742636588426578375584884542574286746172215171731433726362521252526125226316644
+266412313626412456352255523122162552246467472564672572624335752886865853443364264337252488686566447241463771242574574646723632616631165231566
+125243416621545466254631426261643517757142337233365327537426344452743478323433545334333776886455363744322261161533367475226466455121145421555
+243636124536216413242417371755621123365122522612246447676874322547422775322663555232775224452767462351722432314711417511366165335354121363443
+552314332145641535152245776413475576234176511166111374535652333587354682554337348283541653553653477621777653427172723523115611616466341145443
+433356555154161312562332651636363533565751644223741645722355435554442236322545558476342436565143746544227225743667122345363463455414415536235
+423154245165125624414155562224431557461334117361562221661757752155721727456434522371755771164266243445632653752753526633124126431462336111334
+124444552364152561665532531634233615724764471561612226344134256716317667432613647737247777667745522756612542716752564161336133565445451234112
diff --git a/AoC2023/day17/solver.lisp b/AoC2023/day17/solver.lisp
new file mode 100644
index 0000000..94598db
--- /dev/null
+++ b/AoC2023/day17/solver.lisp
@@ -0,0 +1,132 @@
+;; 11:45
+;;
+(ql:quickload '(fiveam arrows cl-heap))
+
+(defun in-bounds (field crucible)
+ (destructuring-bind (maxrow maxcol) (array-dimensions field)
+ (destructuring-bind (dir row col) crucible
+ (declare (ignorable dir))
+ (and (< -1 row maxrow)
+ (< -1 col maxcol)))))
+
+(defun advance (row col dir)
+ (cons dir
+ (ecase dir
+ (up (list (1- row) col))
+ (lf (list row (1- col)))
+ (dw (list (1+ row) col))
+ (rt (list row (1+ col))))))
+
+(defun parse-input (filepath)
+ (let* ((input (uiop:read-file-lines filepath))
+ (rows (length input)))
+ (make-array (list rows (length (car input)))
+ :initial-contents
+ (mapcar (lambda (line)
+ (map 'vector (lambda (c)
+ (logand 15 (char-code c)))
+ line))
+ input))))
+
+(defstruct (walker (:copier nil))
+ (path (make-hash-table :test #'equal))
+ dir row col
+ (track 0))
+
+(defun backtrack (dir)
+ (ecase dir
+ (up 'dw)
+ (rt 'lf)
+ (dw 'up)
+ (lf 'rt)))
+
+(defun next-direction (walker adv)
+ (with-slots (path dir track) walker
+ (destructuring-bind (move nrow ncol) adv
+ (let ((np (alexandria:copy-hash-table path)))
+ (setf (gethash adv np) t)
+ (make-walker :path np
+ :dir move
+ :row nrow
+ :col ncol
+ :track (if (eq move dir) (1+ track) 0))))))
+
+(defun next-moves (field tried walker)
+ (with-slots (dir row col track) walker
+ (arrows:->>
+ (remove dir '(rt dw lf up) :key #'backtrack)
+ (remove-if (lambda (d) (and (eq d dir)
+ (<= 2 track))))
+ (mapcar (alexandria:curry #'advance row col))
+ (remove-if-not (alexandria:curry #'in-bounds field))
+ (remove-if (lambda (p)
+ (gethash (cons (if (eq (car p) dir) (1+ track) 0) p) tried)))
+ (mapcar (lambda (p)
+ (let ((nt (if (eq (car p) dir) (1+ track) 0)))
+ (setf (gethash (cons nt p) tried) t)
+ (next-direction walker p)
+ ;; (destructuring-bind (dir row col) p
+ ;; (make-walker :dir dir :row row :col col :track nt))
+ )))
+ ;; (mapcar (lambda (d) (next-direction walker d)))
+ )))
+
+(defun finish-p (field step)
+ (destructuring-bind (maxrow maxcol) (array-dimensions field)
+ (with-slots (row col) step
+ (and (= row (1- maxrow))
+ (= col (1- maxcol))))))
+(defun path-cost (field walker)
+ (let ((cost 0))
+ (maphash (lambda (k v)
+ (declare (ignorable v))
+ (destructuring-bind (dir row col) k
+ (declare (ignorable dir))
+ (incf cost (aref field row col))))
+ (walker-path walker))
+ cost))
+
+
+(defun try (options known field iters)
+ (let ((next (cl-heap:dequeue options)))
+ ;; (with-slots (dir row col) next
+ ;; (format t "i: ~d cost: ~d/~d p: ~a~%" iters (path-cost field next) (hash-table-count (walker-path next)) (list dir row col)))
+ (when next
+ (if (finish-p field next)
+ (progn (format t "Took ~d iters\n" iters)
+ next)
+ (progn
+ (dolist (newm (next-moves field known next))
+ (cl-heap:enqueue options
+ newm
+ (path-cost field newm)))
+ ;; (print (cl-heap:queue-size options))
+ (try options known field (1+ iters))))))
+
+
+ )
+
+(let* ((field (parse-input "input"))
+ ;; (maxloss (apply #'* 9 (array-dimensions field)))
+ (options (make-instance 'cl-heap:priority-queue))
+ (known (make-hash-table :test #'equal))
+ (w (make-walker :dir 'rt :row 0 :col 0)))
+ ;; (setf (gethash '(rt 0 0) (walker-path w)) 1)
+ ;; (next-moves field w)
+ ;; (carry field w maxloss 0)
+ ;; (cl-heap:dequeue
+ ;; options)
+ (cl-heap:enqueue options w 0)
+ ;; (cl-heap:enqueue options '(rt 0 0 0) 0)
+ ;; options
+ ;; (print)
+ (time
+ (let ((r
+ (try options known field 0)))
+ (list (path-cost field r) r)))
+ )
+
+;; (let ( (w (make-walker :dir 'rt :row 0 :col 0))
+;; (y (make-walker :dir 'rt :row 0 :col 0)) )
+;; (equalp w y))
+;; (make-hash-table :test #'equalp)