summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-12-17 00:58:00 -0500
committerJesse Luehrs <doy@tozt.net>2023-12-17 00:58:00 -0500
commit594ffdda222751e1042b36f7c6b14506740c95c2 (patch)
treeb6d3fa53cdf15b992a9ed6999178c70e00d79199
parentf527e4fc95ce1a49239e1d42255eee044fefe64b (diff)
downloadadvent-of-code-594ffdda222751e1042b36f7c6b14506740c95c2.tar.gz
advent-of-code-594ffdda222751e1042b36f7c6b14506740c95c2.zip
day 17
-rw-r--r--benches/2023.rs5
-rw-r--r--data/2023/17.txt141
-rw-r--r--src/bin/2023/day17.rs307
-rw-r--r--src/bin/2023/main.rs2
4 files changed, 455 insertions, 0 deletions
diff --git a/benches/2023.rs b/benches/2023.rs
index 337da46..b8b707b 100644
--- a/benches/2023.rs
+++ b/benches/2023.rs
@@ -33,6 +33,8 @@ mod day14;
mod day15;
#[path = "../src/bin/2023/day16.rs"]
mod day16;
+#[path = "../src/bin/2023/day17.rs"]
+mod day17;
// NEXT MOD
day!(2023, 1, day1);
@@ -51,6 +53,7 @@ day!(2023, 13, day13);
day!(2023, 14, day14);
day!(2023, 15, day15);
day!(2023, 16, day16);
+day!(2023, 17, day17);
// NEXT DAY
fn bench_2023(c: &mut criterion::Criterion) {
@@ -72,6 +75,7 @@ fn bench_2023(c: &mut criterion::Criterion) {
day_combined!(2023, 14, day14);
day_combined!(2023, 15, day15);
day_combined!(2023, 16, day16);
+ day_combined!(2023, 17, day17);
// NEXT DAY COMBINED
})
});
@@ -96,5 +100,6 @@ criterion::criterion_main!(
bench_2023day14,
bench_2023day15,
bench_2023day16,
+ bench_2023day17,
// NEXT GROUP
);
diff --git a/data/2023/17.txt b/data/2023/17.txt
new file mode 100644
index 0000000..b59c02f
--- /dev/null
+++ b/data/2023/17.txt
@@ -0,0 +1,141 @@
+541124133262451223521555526415276442427476343542227112451637471165414555151445454712454341172717216244554673426331675113611336525553116216161
+216246356135665341465651745361125364667435557366657532213174472542324723756444764276575745314151355626517252171152452753143342641343535341643
+511432556635151124356365624567326737674625471676366347728432645832862468428826825445437217233162337157727677622361472763243256662122426413546
+546253165144123564565126753612254261376366656643125484757263622755762486282865743452675786722527174536627344776324355226674561126445651233161
+464542541213553436112263253742122565746732255237625385286324253572545668547763845837765875237751566362666536122224343617435731113364342125442
+425265521665564566616452722572345273774126143636276222883728478383866852323664782657744234528642447671654574125377313356276116513336254136366
+113462665133442414745271173175425136461611673754425357887588865245472585587624472762747564742742348762671544133714773472143656213145661511223
+365534543555333117131155463354516144146444348637635735364728866262533572827473865562484675383273372638531327411244544427446446525512433133125
+316444624224317727576252423312552276366426262658558856273776443437847225874583324366382863365233534785723557641245277157414567664514421543126
+233464463355625231666663725445224242247537826586882876583488555235362583488762785287557745767775783265275413323254462237333227326665611366626
+423236451541625531353617356673331367654274547433455876537823232836523877368285328742588345536436483364762826655422633235535472114723443616415
+652265655151573762735332265522316326835553282848468526237232444544466588248322253452357783783557238373546576467513345257616152644771243525551
+142133223657427374436541275716662458244368226343847533652636668548625374554746588654558236437387855633554755762416235257357413271622564132215
+461125252422562763222173473353448333332632837346745438633285257552477243777468525243374345562526567862672766283235563116424236475244365142564
+633111662754461314664772313416553236556477876535762735686276672824385285487677762665528834786744728757435478383276272162272562344465717152521
+261416631612551345345263776486673587826647274488422236347727349545996466853489956272648248282258727782488576773362672766123253433412337524354
+554314236755656551277276743685288625646233282427645636555754768494675795374663665683976467488273474283345848886888746715664774333246514736552
+245166641514633214526734348487465675427683363235278378473888949464365945564559398598535737277277878884453535534862528354123177446435756131446
+445252551751624474235724322832267772528783788824563939957474785443575536356776995447965956335764532532873848765582774582624762275613463452544
+515535274147316672215458278467858825754867565555636397995696946454395795755834748963656664839737243826335773884572557883742765513233161746535
+412377555216675372731265265685682265477736722446499746779389486547464865488539754743455899953599647547226682356465372762855174244763631162121
+641622517573627265526575734675552236788536686888485475667579744944365897357838655693949736879594682752554855678678426442281753575231264113213
+661631323435221675234373786465727824823628874965858778744385787868556483954496963668587874755336358972635363658337322476366472214234711522242
+444665132524656627184254426663688285684854579567557947483673733339546646443848944648586448576895956847443262238278566874476823151125764472464
+457171454575521755222648767223463534726599367348893554588935445674659959476337558939974857654569396484555642536223536486382722357625221372122
+725453716657752744452643353668675565449364465377598773756366437648843385995743898354643699898743833765865682465324522824887352237725316162466
+762617136517343156485246725566886637678358587435469779534894769848868575333953486955567739665594896378568968624465764423458845377421277313411
+211517712522236526756834722583533344754639687969689937386749975568686759768778457366495766478796735587335594242634426238534778275334647343767
+546251635532377565255387828858332597498573757376983885785954575758355438395795368368536574589479987677746539868586784772246244623617322215357
+745342174632625723622632876778283565577965676494747486588433583948458664874448456594659436469358648793695983342266564778585272548433311756437
+664456154235754524863283587447855545794963858559637469865734869888685954445969764946679695893854479353745457985678775358633454664751372361427
+211743776645182422633734537588396968754944554467369569559669984567654776745465886764989989633783389738579336555732774637377457732833546426141
+445225234331855262574863625277757569944885879548784536494847899954558967648897679974799494844464655675636587784383257277333766264363244661172
+164741414222856844477268352875949446797875576635695744585456996958888699585885946789998696834533548393368749437353653428482774758366372553453
+432441614247558744387526878845945376586788559476679858986677994446945846759989956767975698746846765899967489743689775338867487322276532212267
+446324355667635265874847886749985479834744856576685746575687779894956688949999764845479654796794379445846466769978673626567456463252814276422
+461221454642833238426868575393896463594497994348565654885678765678585956885994885748967878557879989979989657864793798663444422625844434624631
+772144666287756336475776336765796439859973945786998558454489998857655589677599467576487877874565589737457869554969987663823846275328636734455
+276552556465265685254474863485757498573978469859654477795478695996677477874869986954466769847466955855567365555744544746634626883728455173176
+556275175762333222673738837578958339898933985778667789564698777999846489567877787648664975686845479749636749756876569345466446664745743415174
+517772313582826544357665933333484863668533447457457796774988988747844655547687996647784847657846689944977569448359996345544875222268265616321
+441251583752284558567359644363557853376958558998954894594697678475858496497585497595568668944957484746434854698859885863588853344652875813264
+147274567623883766276425664396537675898864866559685755888566884566878776956896778445476644466979945945947865744387636473474342534375586846132
+763662457757258725866283878983734487465757985877996998746544679666667869578754995444575878754779758569648676889435485647953647224352727571323
+276473674426624274442448498456577684957666976484768799685488558765956865585965968989589459487885574776779969657679563337845854483686437237322
+566326646827276582252366869758579455648556956596586486675585898678997765757675585879487699888657455865956468756377653359677753725377522473251
+555766532442847326466636985493376556799796888597657994546495755697879985679997895767967697758557465686677475343948989564336463282635432545461
+721716335462545252789567979994759448894896489658667797647699595857777577779697859558585657744579777976558868634794479783363844876364567736131
+113173638728532682635647556834835497794967446765779864686675667999856885678757969899977688697966947555695686464998354963674838824754277685456
+423326273244373654499876484833987639746479797686945594956889887877985699658888777675859559855694559957997668536463984465695766688756722585577
+324682675853728857269643494447885678485858999874448568866576776866777898668759577696799655545758588545946676878393359334948524265854882538811
+765486357552344885849569769669858477598475979469585568576657955697989889887859996797875579594769868477896886539863597678978762444478833773423
+766848786558634444336697858786538758869857846689799986887685578579958578869579669556956555887894678998584698456933444986673778753887573627785
+676777856233875682445679738578539799775775858795785696565798959685599868679968597665869669997486569867878446865965594447463664242763866727747
+434882224247467287779478858699697584648899445944856566689958577655788989657888867987995897987985746976489557768897794464696758483866652836887
+527246827685666236485633453787699986466697984557677967988977559877766668685596666856888757687775776598849894686987354357433349572756254282577
+222868423852323374659795967747669795868797894979879756798796967766565955875569798558799588577677889576654797567587539665474638242856548657637
+773872842753863884539444975878567965747656487696568775768995859766695988995875997985788676965567969449669984859969983866549576446257842537458
+623723723226665647798837757993388687974767666995987767889769588995888896966989857567576779767876576795568454659997879554346436575848835334677
+736648382475673787577943537457578598877479775666668658565665757998877999888967757575899869568576894655889676994877873974759449772673625536524
+663572438622233433875643546759975686569564676878698679767587785977899966699879676555569757565756775688477958476577699749784435562242425738257
+478226865532345885367559784373796989654797585995757777578975679777786876797777977757795869656799677685695887858486954344984784683268435688546
+588584554868426584369387849449556476986646899679587587656575898878696778997777666669787688995559854749447477446894573484798359835555486427433
+632428552754847873448376883879779744699448686669555769897595888689978668887798897989869776965969957769976845678793476958434764688788425475552
+246337247848327968935783355579757765485679945557666688956877686989769788697898966766677768897589968678659489969774373484975989967855224637427
+223375675284826496644743769584444558499677598859598889977966867997687776796778777676565667588655557556595565655487863554397585972334778324776
+764633328253254937496368456497495746445689445956588597798586968696799976979688786697975676999875768786997657669845753377353975597636626523733
+688382682827245937467954744444754797866745997995666689877697688986889677779967787899898867658557959984696746744446845573689464677842425252853
+778382366648283986997655736938567465996556597786765855955966789888987676888669788679859585686796998668994857955647338469347574887636855354274
+622526353488524848964979945979746599785458995886866985956999986676897668868779778979685577875697956565964574578495467957463598882534726737677
+563345466883264754839866699968878679465846658688866585767989776678667869876998988669695869897598966667796854778886868775979975847658525683743
+252454333852337588787753853567788485875476785597865797759987899796687778987999999997868586597789789687848875857548586467983476576586366724587
+347278637485285767966774749346486697684749977966698759697797997899698786676778897999695799556868887876458959766876348753636354932544365764746
+522652358674344548484373838647546998949779486597767578759789797676666978999979689969895858985596998754766775664578557557964834743247442442333
+668272877546857487998675796687598545759696598987888789556586788778879799977967676787989969777997859949976654776876335869744568344586436254542
+776543744856724673567466565997469696685995687556876765687769869899769666668968797687899679665987767888858887466879685639469396583434472748568
+433485286232554637657839669435566867455578478977998787669878978769666976688867976778995796967977575844687586744645787354844388554786655323654
+434448665325566548797756374944659597767557959589578986579576898687687688768989769786597677797868667847969884986665435467954574462665242266776
+623436374863654685479837455765768488987649957597766888779596897867966877998776689987976677859668778546987856697797743547964399885632853468762
+643472884824542736457989449949889444488866659685788556969965899798887979989697677799896877778756956494494958644475759689449965333267646668842
+125253675735223439863798454643799477978495694979975789698558996888979798666688768655596685967965894864698499544494985563955799835884325853582
+455522483385654374837835843554474864559965479879657658996878567667899797879976996755657865969565569646754746668764654953348944973667483236773
+532754364876725238956876398675594757475546554786897668987585676967786888696886899566977896659795555665586744855579885779694579772474653564253
+516883687682545558788369453348874994979445958955869695867979688886688877887869668686586868566887997644447465844444888544335574937286254564887
+324738837785445267693746866554744688887448567897675579986558667568799979698678777859585888869665689677864599947736986477867967638377286684422
+547484484875435536454846783536869798477979977597679958578775896965876968977685785685597868669587446775666577777998948536636347324562322855632
+648847236834583864595644498739545945759998469678699885559965556595695977797856757967788557899677546666647867778866857599734494644385554865534
+532354476476357835788945957784774866988768494768879898788788878697968559968559685956858955888654674655655574655685753454797463263244574382333
+253833335637563766345754764769947586576764896745696795775758986989659869798888885576678956776767698446878464587855455597857944422347558255283
+544522367456587436335876765363688546754649878597449679955875558876589778676985877759896859978599646647489497989548367989497587467275528776843
+562287882476824537768377654457974946794685658646477688665856859865969696968758855878795887666678876989457569685598343989686454552848762782677
+161255272856748855865968497558783799948759459887699758756878587975697989959967957879598585959495984848884497543664879387977778384736238473227
+622347655563885787565539859896848355889596466786849589568799768967858899588656767576885977655598864495996499768549757754997474828754824666343
+275257247275786456644744457653343894854779685956894877597878959557768896965796668966778576797747498877686675458494496985746572386274324687411
+176788754368332628829575876953955856697786767895695948488558977555655787857976675996789966996494885964976686933384837556586828237862846754313
+154234746863664648636793996966679983859595948984684648589597886887955755676657669676898755788568544969687859487734678464965425434667238364717
+633358763248872422537776485447659483959568974574545676544868679765589777756768795955948596676845677479499495344593656853592264766722768625175
+651352846373377634772574995575483594476898694657486848669966869797787698688859566965757659485686688659487583599383344873735744555426672587231
+547711568462527442634436877538597496698565575476744678568944879867677797567867765846767789586497488976949969538938658383437487346352327582745
+646344426633278444662848868989384788865947654795448648499899689755887679577859674964844976858679564755483443676355748568542268545238768321546
+676771325226366485872479995636847458586649587846758449569454445945955477676499588656848868978698597654546758875389886695252875543227253516532
+175364176886325336646625374584654676937884549696497875778585668699994896788664478748886798864584986888859684547869363648474647782747622633214
+414543468425388746374783585935938376637894947884767687586655855975788946879565876654798444859444779474459453954885333344622747333787538523564
+721442215435566686676252286557639746698646485576654558876746967979879567554487997574889457498454656965985838598775853875843757366634427246354
+431421626872437587333876244795456558968874399999774975584796998678468888489657749967998878996447444863648764949348859356334477666556345115667
+657714122753232462483356747689864636476764349579677889448798447575855584947864965764778787684957485556483453438397793334344637632466767727757
+432727742577333522682756588379538469465834566938589484895778499745456566687549957968858758999697887575673835635785347853533882375257214151362
+773134646552437552868832772845635738553365439368496944677996959774784965759974956649468586665678884439544384785659624787665327546766857444563
+651452637425432357682836742869757577437858589558358988694949979858686495998488658658544965796567835436558375956499782278683423464864713155441
+661547253256776528874728433646888549877443954535869689469798946858977664794879655466645758744436657654387658668396834546824454542666753462522
+674747421227555372327325752726498738946734697734786893656479754776649794599959558456585598568477587996673596658894373726288426873825274651344
+476371623647166652832352547786479343466773483377676983968549998844687858946799597557968973557957858967465478785434528358737637332622664632746
+714514166125237763337247723253287564576746335486783478739563949774667995764659458594843983799463468377733599355866233665448235624153766635226
+627511516776574473758758873678763543785753899796397679374488745455795795654796349498686576597548349694543797494642278343428532337447723111343
+324677612412615763562285367623273669544693456386977586478655637587678996944496854553374585639858863635479594653243527828725838742123344446257
+234655527622631633824874344754427578539458944687435483387467943895359553964346588477399365456938767836846885748483636468554845837321676756531
+455274712154431773468787457577372875343977544496978384537478536376687887583733895558743934699448589546739952868322653233866476317427641333563
+577574627454147736423384633425845248884858749543874675938885435749773455684397775474365445463383563854487685727656545622827286476516251433323
+141122113234111734748738646537835274453789685677686994335694785379979358669877897484973755978859575576365858266357248662742264741676344474244
+127543641167235155764622222578573666728559894473568565398844868934853794963346356553896944566998575478786224847486585362388525533362323151757
+117331114155213212147262765635885233324347374784388983348385465783335845553967648545877754748455835377463464666222427356578752161356674347553
+265426116321115134141728238475737383425787253589357336437667835648588563368765636858454677453577867835444556847435647333552336456633727717621
+325213662212452137173586522673885547884343285379394835944383474356795833796998963657598463456984668683233837567484674522431546535767274215162
+465663244744521424637154746273377766872448575277637649745947995769735446435763699867443757756747443438656385264345387827523457576171123714515
+543333636123373647522762534643227857526568532862465645445856955444538753745973943953865988994385455827283448446576876683261725547565735545316
+226656143655332271175546442354837885876528422577757268466884764837989583477799593569746858474688734787823356875455277862656645351564473731423
+451636211537615736717354463542857634767686682876358637842988883565335963683756489856652724228628362876886254365787242364734566574772447535262
+443314621324114377232722667736443278484634528873642844827845349567357763885469946458835434485754465257776726283288676374637266313415317512354
+534514443765625131357455525333623746872752367478463487756634233424474738767363664464768264548385676485487326283442342611643165713174367543352
+553355631434732317337532563472458647845383338243338556673733824446666232375285478582368252327837625856873833328516454461645113452664775621355
+223215212514443224412413552231335723624742467886357886232222787626766874532382677637836567322825638644723553753123144233474656256233614313152
+331133361261214462262642725456467457474873432536745434465738885528276284688856832565533823474836446688472588711755715374514612365224633216546
+224141624445117524343643736344332547535644784627465246246586478568227234877875288272223427676883844642747327324637723233777356361614421264423
+312233453415564643415755227733647452253283588333752424355454686354734487846454833378637728427688476672846254746411275433761146523614563155465
+633515223133641764715373652772752222354385526752648737883586473686262562563584268457537762546225732458672267236144676263566147112546133622255
+515512536131461612616754254471745533477372453485372464368567452487853478237334682773428746542877265843754212557577453421133415115631224661523
+113615441345564515447162714627461522623564178352784782648645736854876775283274346372237563742334723773471226137255644565741276242546553343112
+442314663435134161777665136333535756342721422358655824652778285834385252432258267545672854223457273611573633471763121245347262616114546424526
+652111225125264554563114246365537446161475222471827325683735744787842737672374276285638528462874367333331351634762226442775224351461162221244
+423342414526323421256715215553527732544175456475657784684724534867522272744634638572352338481741555274437151146775627157656331112536461234534
+336435661126655334611243615635574176321515566343472712444546756738683283578482678425383373371521437331137621445631235166234215163124151536144
diff --git a/src/bin/2023/day17.rs b/src/bin/2023/day17.rs
new file mode 100644
index 0000000..b1579ca
--- /dev/null
+++ b/src/bin/2023/day17.rs
@@ -0,0 +1,307 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use advent_of_code::prelude::*;
+
+fn add_offset(
+ row: Row,
+ col: Col,
+ row_offset: IRow,
+ col_offset: ICol,
+ max_row: Row,
+ max_col: Col,
+) -> Option<(Row, Col)> {
+ if let (Some(row), Some(col)) = (
+ row.0.checked_add_signed(row_offset.0),
+ col.0.checked_add_signed(col_offset.0),
+ ) {
+ let row = Row(row);
+ let col = Col(col);
+ if row < max_row && col < max_col {
+ return Some((row, col));
+ }
+ }
+ None
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+
+impl Direction {
+ fn from_pos(row: Row, col: Col, new_row: Row, new_col: Col) -> Self {
+ if row.abs_diff(new_row) == Row(1) && col.abs_diff(new_col) == Col(0)
+ {
+ if row > new_row {
+ Self::Up
+ } else {
+ Self::Down
+ }
+ } else if col.abs_diff(new_col) == Col(1)
+ && row.abs_diff(new_row) == Row(0)
+ {
+ if col > new_col {
+ Self::Left
+ } else {
+ Self::Right
+ }
+ } else {
+ panic!("invalid direction ({row:?}, {col:?}) -> ({new_row:?}, {new_col:?})")
+ }
+ }
+
+ fn horizontal(&self) -> bool {
+ matches!(self, Self::Left | Self::Right)
+ }
+
+ fn increasing(&self) -> bool {
+ matches!(self, Self::Down | Self::Right)
+ }
+
+ fn turns(&self) -> [Self; 2] {
+ match self {
+ Self::Up | Self::Down => [Self::Left, Self::Right],
+ Self::Left | Self::Right => [Self::Up, Self::Down],
+ }
+ }
+
+ fn offset(&self) -> (IRow, ICol) {
+ match self {
+ Self::Up => (IRow(-1), ICol(0)),
+ Self::Down => (IRow(1), ICol(0)),
+ Self::Left => (IRow(0), ICol(-1)),
+ Self::Right => (IRow(0), ICol(1)),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct Crucible {
+ map: Grid<u8>,
+}
+
+impl
+ advent_of_code::graph::Graph<
+ (Row, Col, Option<Direction>, u8),
+ (Row, Col),
+ > for Crucible
+{
+ type Edges = Vec<(Row, Col)>;
+
+ fn edges(&self, v: (Row, Col, Option<Direction>, u8)) -> Self::Edges {
+ let (row, col, direction, length) = v;
+
+ if let Some(direction) = direction {
+ let mut edges: Vec<_> = direction
+ .turns()
+ .into_iter()
+ .filter_map(|direction| {
+ let offset = direction.offset();
+ add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ )
+ })
+ .collect();
+ if length + 1 < 3 {
+ let offset = direction.offset();
+ if let Some((row, col)) = add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ ) {
+ edges.push((row, col));
+ }
+ }
+ edges
+ } else {
+ [
+ Direction::Up,
+ Direction::Down,
+ Direction::Left,
+ Direction::Right,
+ ]
+ .into_iter()
+ .filter_map(|direction| {
+ let offset = direction.offset();
+ add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ )
+ })
+ .collect()
+ }
+ }
+
+ fn edge(
+ &self,
+ v: (Row, Col, Option<Direction>, u8),
+ e: (Row, Col),
+ ) -> ((Row, Col, Option<Direction>, u8), u64) {
+ let (row, col, direction, length) = v;
+ let (new_row, new_col) = e;
+ let new_direction = Direction::from_pos(row, col, new_row, new_col);
+
+ (
+ (
+ new_row,
+ new_col,
+ Some(new_direction),
+ if direction == Some(new_direction) {
+ length + 1
+ } else {
+ 0
+ },
+ ),
+ u64::from(self.map[new_row][new_col]),
+ )
+ }
+}
+
+#[derive(Debug)]
+pub struct UltraCrucible {
+ map: Grid<u8>,
+}
+
+impl
+ advent_of_code::graph::Graph<
+ (Row, Col, Option<Direction>, u8),
+ (Row, Col),
+ > for UltraCrucible
+{
+ type Edges = Vec<(Row, Col)>;
+
+ fn edges(&self, v: (Row, Col, Option<Direction>, u8)) -> Self::Edges {
+ let (row, col, direction, length) = v;
+
+ if let Some(direction) = direction {
+ let mut edges = vec![];
+ if length + 1 >= 4 {
+ edges.extend(direction.turns().into_iter().filter_map(
+ |direction| {
+ let offset = direction.offset();
+ add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ )
+ },
+ ));
+ }
+ if length + 1 < 10 {
+ let offset = direction.offset();
+ if let Some((row, col)) = add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ ) {
+ edges.push((row, col));
+ }
+ }
+ edges
+ } else {
+ [
+ Direction::Up,
+ Direction::Down,
+ Direction::Left,
+ Direction::Right,
+ ]
+ .into_iter()
+ .filter_map(|direction| {
+ let offset = direction.offset();
+ add_offset(
+ row,
+ col,
+ offset.0,
+ offset.1,
+ self.map.rows(),
+ self.map.cols(),
+ )
+ })
+ .collect()
+ }
+ }
+
+ fn edge(
+ &self,
+ v: (Row, Col, Option<Direction>, u8),
+ e: (Row, Col),
+ ) -> ((Row, Col, Option<Direction>, u8), u64) {
+ let (row, col, direction, length) = v;
+ let (new_row, new_col) = e;
+ let new_direction = Direction::from_pos(row, col, new_row, new_col);
+
+ (
+ (
+ new_row,
+ new_col,
+ Some(new_direction),
+ if direction == Some(new_direction) {
+ length + 1
+ } else {
+ 0
+ },
+ ),
+ u64::from(self.map[new_row][new_col]),
+ )
+ }
+}
+
+pub fn parse(fh: File) -> Result<Grid<u8>> {
+ Ok(parse::digit_grid(parse::raw_lines(fh)))
+}
+
+pub fn part1(map: Grid<u8>) -> Result<i64> {
+ let crucible = Crucible { map };
+ let (weight, shortest_path) =
+ crucible.dijkstra((Row(0), Col(0), None, 0), |(row, col, _, _)| {
+ row == crucible.map.rows() - 1 && col == crucible.map.cols() - 1
+ });
+ Ok(weight.try_into().unwrap())
+}
+
+pub fn part2(map: Grid<u8>) -> Result<i64> {
+ let crucible = UltraCrucible { map };
+ let (weight, shortest_path) = crucible.dijkstra(
+ (Row(0), Col(0), None, 0),
+ |(row, col, _, length)| {
+ row == crucible.map.rows() - 1
+ && col == crucible.map.cols() - 1
+ && length + 1 >= 4
+ },
+ );
+ Ok(weight.try_into().unwrap())
+}
+
+#[test]
+fn test() {
+ assert_eq!(
+ part1(parse(parse::data(2023, 17).unwrap()).unwrap()).unwrap(),
+ 1076
+ );
+ assert_eq!(
+ part2(parse(parse::data(2023, 17).unwrap()).unwrap()).unwrap(),
+ 1219
+ );
+}
diff --git a/src/bin/2023/main.rs b/src/bin/2023/main.rs
index 842092a..25f7c4d 100644
--- a/src/bin/2023/main.rs
+++ b/src/bin/2023/main.rs
@@ -27,6 +27,7 @@ mod day13;
mod day14;
mod day15;
mod day16;
+mod day17;
// NEXT MOD
#[paw::main]
@@ -49,6 +50,7 @@ fn main(opt: Opt) -> Result<()> {
14 => advent_of_code::day!(2023, opt.day, opt.puzzle, day14),
15 => advent_of_code::day!(2023, opt.day, opt.puzzle, day15),
16 => advent_of_code::day!(2023, opt.day, opt.puzzle, day16),
+ 17 => advent_of_code::day!(2023, opt.day, opt.puzzle, day17),
// NEXT PART
_ => panic!("unknown day {}", opt.day),
}