Day 17 Complete -> Love a bit of dijkstra :)

This commit is contained in:
Luke Else 2023-12-17 21:27:18 +00:00
parent 7d9f472948
commit 760881cbc3
7 changed files with 344 additions and 16 deletions

View File

@ -0,0 +1,141 @@
112222221323213113333323322444342424324235235513233424441521421241545143411145334442432543231425554512423123113114232422242322323132322123322
112131321311322131441423422433434243225123132352335324453212345444231322442352145135542552454212421113553344423244123342442124331123113111113
223121133222231141414442234343234443245521353512543323315242154222243251314332452411341515252321341252252352412443224334334423431311331233132
133112222131222314441334144443223232435425542512121331552541522242524442232241453321512312523525314513351154532323413141343411122222321112113
322223332322123343222431144122111132424322253553532251352141344412415524331232153525524452112552433423233331423314432421441433324223121332321
312131333112441323343144232223412255122131134231531222121445422642255246544344351542431215224223522125434152553131142332211443134312222231222
211211333321123342334144132241233125151214321445224333231666326363643365422544542253625335334412231343533453513253132434122214434413233322212
322212232222212211422412332251353342454542231312144243545346225253223636324233543632334462331141244415524124153133313132412224312222312331223
322113211223113212213314342153433525433231555553242434356463363265563563645342336263523343224234524225243335241315411121134133421334443112231
333131212121412343141114435445224133135245342435446335634363353522253334334325533246432443233534232533451511221534433232211341144331442123133
233121313211411344244133551335321151454244115435646626433463222346345336345563626454252442243263621312153524415454353452143344333231232312131
232232213113312132313315315212344412523141424345323355233264433452535644442424523432345335464524334555424255155321443253342432143244233443221
222312133141411241134354244325155122343355365362644533322246255263355522354533563443355326646646264224131252312153525411224323444133232224333
111244131344141222413414145434311435455622444665232334443532362335566323622352345532434556256524446255655425132232533115524333143121243132233
111244311324141411414353111524355312152244242424233562353222623365626223436624662663526623323346624635656242241331544213244531411322111321212
121424341321422213253122452544151441266334352453236555222246466353633533663225535523525353526632362352264321242524154533123152333422233411413
214234314114323314314113432131313366255232425525656542422233234633675447633376624644353253553454655364562265441352535145552134124131432133133
332424433411233341444552444214425242344536442265562456663425666554773446347346677757322356235433365252453666562542223545254213234341442413224
224324313224121122231213334354554464222243262245563446443457534436665553377347573536453754242646426644353462646354224534444454111443421424223
344113323141223424312532325552433532226426525244252545567446457377467376776453446546455346324422243324355266242461231132521221421334244122132
121143243442251514121142215433466252326566252463554376575564647554466444643663736743735467656325234634366624462435225541155451213542412123321
144144141413521534533235234243446622523424443543366754775333444667747447575555647346575553475442432323322363533534442254251333554224321322412
133134234431121245414221455544552355254533333554765767646635755346377456576745633435554465565446753562643346625663554454551533413451121411332
421312141414151251534535145545334635454544355454537445775735777476335374453663376445743543376477537535536333666253254644241451115445221211442
214221242454533512544542256445353534624666364447645454474464366777664554366343344656674345645533773656334632346233242444145331553411113233212
334433322134135114521523436665566232456236775457364736647343457564436443366747573543346756667346554433432625455645563443212442225353141432132
414243144525445132532252446445235642322545533565647777645656674454736444665656347675347444337755333633734244653456533533542525542355122224112
143433235535325323514555652344336622663673333376467736757366664764488787546574753344663735335476637633573446363332324444531212212313224243124
233241124442243342213456255656564436473537636467545543637434558584544455845477658673347754347766475535563665626236564655445414511114453531231
122413431433152134134564353264624256377643443645443356354755477477464754574766768774754774457343446345773673563325242632444445145241315521422
444312155313125142555226522564323545655757443647535433658788465575486755656545676476875673454545753454675776324224234622254632245552231332241
412315422413422234626446663654536753546573463454737467446466876468567577575758846484447444874336553567564657772425335653334653113522255423321
321153543234545221364664522445565745475535455445777484645858586885856446845646587785657668865545453463765545366662426263665424333352132235312
343333453445435345642254343233244467557455636777477667788648478884457487868658844576875548665767473445373444736746656464542536352221113114241
341253351244311554666363623465443773334565554654657584758574446865455758468854764677665687585678646675377744747475523236366532643224332224132
344411335532124555324434522354736737343764736657764444844874845687784647454874576766784678446644654643667667447774422566532425225453355452534
335114112251353562263552553356673377666433457758767754655756747844667745777466447655544468855548654754473737743747666234326455632232214442144
225222425444416653643232666446467743675765358546585488658774865746464678468857578676487567565468775655664634567643732532643543645445522444252
221255251443542444423662624434743655647647485755544664645558854665855956758744886447777544574446664753567664347436446423353325652523452455435
212553341123245524653233356344465547467357844646488645867475658779695667557996865565887876875848758555665345676567653345354543456553242425211
124324252454252354346666635555463356466366764765564874466577697988975997976596879775875785557748456786436363464536777534565566666415253122423
325111152445523442355232556376357645446586854565545874487796699987869778898789789758796467676847647687674374754666446655266222342222512121453
422455452455632236346335347563767755665865664864458577856687697697897757575876756975777785766686667467465453645675354336442536246544213311553
152431153324634643246634634574537534484787765688676758867558678897769985796587985868567587844664676845854866536343764366223224355552413433533
455225414512433464335335554663376546777756858575857696858895899995956775869658676989888796556684445857454545543366637447263623326536514243141
524115342224323436366656644773636343546686555477778786687586657565875696796775787557759768554777664886776547534776477347433234244365333451111
215421333526242353653636465465357547566845467548755577777977975755678656957696899555969955788858768884546477536443756377733456462466513124145
453343353526463442543557773466473748788746547586678875958676769698799659999768879799765585569898888576564856535336575675425634662626651252524
253412222242626222432346567563634477887454588479765758656676778675685677967575678658786557595758658646657856867375547544646264635345664312123
555512245345353565334333554535755475454656658475955558765596999697659889686775666956766657687698888564546674855535355576535662632423563514352
452155524642465255567337367636637568458754776657699979565958998997688697897669678659885685585577665678484556547576343653353623364236355342114
251134115535345254646474773557574754667855574897588975769766698986877969996889996798555695987767765456474685856753434536637534365446546512524
313234422435246652257534377665385687648665645596788569696786789978786697996679987795559598588796966846754675786557357475557342553432222432235
513131443646224422574544654546745887444758657899677778786859698688967688698899668788865595556967568456774646675464566566563565465344345254345
425125562464224254466637537343365546548668599688675897685696699869799969676788969876779977789779687665687584686536777347563423253545665611435
345451266444536222376475754743554648687454696595769789668789768977899967996966968676969576965995986698566866588446465347463675654666324235435
451335564564336426355565754567747765474654777658589876896768999867979697679676878696679769696986599685888778787446443344556555455335666511243
431112634665335644734656445467555484658575796976986567877688978866769989766996667677998695589967789886865766456575464745767465445354254533555
512433632236422233776664544337856564786655959898796968679978969688866666876789969976769966596887996859656746868474343474555433522552365631223
411221632443326333353345355538785468788457759675657968899779969977968978967766967698786999959959586566666855866545536435345655225424564333435
125553244225343663554546647668554777488497895977977977989879976889886699798769789866786966768689855869648544654476666754667546332352656242232
224355554426226427543567755487476465685779895867885986776697769877977788779899876877696866699898577596667865786755446366656764525345346652214
543353654443226563375653756685788855864976688677656786798678878968897888877788787766767677667999799788777566658554736376453746656236265643521
333454542665465244564546543385875577484956879587989997976867878688779877779997867998896676779588599977986446846457857575453375222324526534133
434423626556545553466446475455488856664559988679798669679776696977988889799798779898769886668685688567568867666455766733573375324254424424333
533225466264523655453666547787757785688796959979698979796876798987899788779899877998899786768966859997774474747556755453774466746452244254133
233236435436355253673373463578478745456869858986757697679796869799978879987997889769887987869577565596997487848475864337675756432243623633531
445443645256346277544755436848467557768969758685688896676868978787989887899889787997687789898558998998759547884884863344635566465645554432354
124155465565526266556563654686677668556868898599757776778797887888988977897779988999686788676895975665899884754748675746476666446366566434122
311322632636455664545565356654586555459659758788888769778889878778989888889879977768787868689659588787568645657844856674376747333534522446543
524415343336265273534645664487885774877899958977789878799887987999778979989898899778678779769976887767897486768856865666347536432242456664542
252235255524462643653563335787488774465758755559966788767688888799777989978789988799689669766798657798896668866556647757454363523233452432141
554143266442623573465776464864468677779678896788767696997998798878978888989787987789877668977695698668769775476667456764644553534342535266444
455413536263265454754374665847578657465756887596786796998797979999999888879788798976888688779769986569696858754764553336674566736535245655151
512114234634634573767444646846458576775777999777987768878789699989887887989897788796676878897867796888566884847756544464756535425534226455315
251156443463246365364555474875454467479655999887576896968768978899998788779887897789889979989657699786956644467567774435633753363336532323342
141445426456345265535356746554548684745767559885568779778776768799879777888789989989668769966686595795575865744764765734475776446243665665312
255313332435652474564576376656756744686675669655557676666679698877997977989998789697979798797968689787957447875468666344755353652563622632155
224116423563545324743733743365788745646698588756789896999878687998797899999988899798788669896659858787568855455865464643565533564255544546532
221516236634252257644567373678456477746958667867869687797688788679787789789998988796696699996767866797867748675884834535654553562232462446444
222111335644233545747443657487587784678587675977665966796988869888777989989898699667968869699867555599766476745664645666775635552226635533431
241152326523236647636365537758576574785686665687979566967789886979989789789999979697678878765757779675564544876778754766557633432263335432511
452223665243224356754333346474474678677576675785985599688668677799798698998996677899997797955699567757685668857564347474546464442225462343142
423515353434446536474447535756864467675796567988858996897968776977898767879978776999866889875659796568976567787558564335566653354235265322524
424351365564252244474735573334647754865559586567858786889698899876966797798786877779998665988798657599446747744777353735666344633653366633443
454144532463464222765445754444565446664875987986567866796969889878799879989896887889676866687857579687846848686587656737543663254363266523324
331243324542246263764737537754874877567844787886598656877688968766898868666676679898686677588986579575675875455856366535446674342646656345133
522321542452233626434565356637848767848544675968869858758769778767787777697696689977777857969959787976545865565865465336346655334223624541112
114331336626665542353463356774785875587465466585655765656796669877699989689897868896886595898867759985887768874677765363433443254336656344332
532434544636522322376363476457655864656568487987665885799596699786688688769896699999558576757757888564444674457475554463333463564635325254234
124123254356322652374367365435367755646457565868966797857755878988869898778676899889996578895679979747465484577746366674577562655552665354451
355345424663263264544445543664667585455685786595786779565869857888798889686986766559566865596859874668875885786376666576364542563332653314542
325314554354552336545637736754754776744876584485778875668658679979997779896976785597858967597985685845674676484745335436656336624544354211412
425414121655523344243575357763653747765444854467696766899955596658589979895566586798588797797556785654784457786766733553775344335552245323245
321544144325652343334575753536347564556577486666588986855888695796688659778786685995788887556958887766558666576735457565562453342546642134133
233224244454245562454544567466375464478684468664878689799895787598577866567558998656655957865877684666685656557544654575652253325644325245452
223253325222626422232344673743536775484847887564746977799768676589955866865598778776977777898654875857658564566565663763455236326342652254352
155252422533226225634556656344354654464548688886765789889959975988897978898976859996899559995865644767458876575545536564442453242363535453552
153151534534626342354465665744754474644684754445886465878699957799687876669595855957865598785658456874788777337375336333556425554625213551524
114131451313553442645435336474563565464846784747667764766877599656867686898598866888669594748747557867644446754575776643342566446456354515545
341445155413444265442333676464335657464657465576446677768796997589788878566978557586958648788844587858746674657357537556434652546423525233113
145555453252246666354553464435564354555574754444686748488899567775759856599667996866868645877786666486875457454653577562363344343353254313251
143522431434132223562456236436453466574664556457854457784587698566798687887857966579455846478558567867734776443433564663645232333432153533433
215322345321224335635562467377454444547736774447848748685756479895588579586889995685457756468565465686547776773475577554245422325222111541441
341322153154514433556244432436566644465665747645578576487455785788898555578675846854548778777465446786763336667574642346555656344514521212431
211411151325556343533222434533637444454335645656474784747848585745568857858857586746545487766766747654736763544346624246343635345312442334513
332121414344532346433322666546554556647353675587785568474748578865644484548648855868467678744684584637444373533334343524243655231512424415224
411524544331513352322333546664576374474473653477646577688768554444786477486457545666878757754774535354377435745536263264224334353132254241153
422211332253552135663623352665455534446547756657668474757847555474767757448784477787467885884668463377464774543773322646356226324142454115544
431332122243114415654234442342364454375577436734766474846574566767468866458556744747578844486837345647756635665625464262633224523334511522341
224251132223221313453424254225224554354467533673735745545644556487888454588447577457458774746447435534547557657555442633434462324134522544331
424111421545541554645653335265444456575347757673576457844645675546487464587674555767765667574773374336533537762544524643353364111515335224142
223234224455241252363466635222362536376655666633577657645755565564687447466785887788764433664575544537646477666565263426556245422143414551114
233332452421231352335626354345244256743777467745433457776474466468687755585566566647444755553777776556436777656425255542455334512253244152412
422112411545554131124444622334525554545646447374565554535566388477546575685584468734376566346747454644555546562335642323543314133325522324241
413442321241543521354365362526422436656465774657774354765753344464456467766744635674434544657564573463535455526336266353232123151224155411344
242422423415151112523146354525226366645673535545673375435674565354736655476666475464746664643334676575555355355232463523215233452253211124213
111143333432524413523436454324432264544544735574336367535553357366667456753344674646463476344445756576624653253446454635325453235235252223333
332333142443531535113424432366223346242652573755667573455376754446553553657745475456557634557655643365263544656433326353222124154251511343123
242134112312545355525535253554536455434525565747777346444335464356647647753474356773646733654433665663546244642563345314421211224122331322323
412433132142141334132434543252622264425454662573753773655373564475543446637637735373477366634444666525263445424664645423315312343452144244311
344332114244241351525142214566224356456452462326344354764475363746334746646337333637737763345332536642426666635663354355254312322132131323131
131122332241242144224432125432263364233255422242226745577455737735337775364433433366454374736353664344646633533423434332335151212214413243223
234242214234112333232155555512323532255465263462233466676735734343577734764766366647564433344543423333456355223241544213123541311212142221331
141441132112224233454451555413534354322564665444243625534333444434643766364477757477656655464463335535563452453345443233435353224242123124343
144331231314331344132242232413551365336335442534566254452555534665767376357467637446622223646365466462446552542232412554553522134322422114312
134214113434441242441523343323532134326253624355324322446664554225677656353747222453535646643544355352452322613134131514514525142433223323211
323134243341144411245145214232341245635335566666345653633536443645465225362662534525445362323226632632245641512241442214122313344131411414343
212343323343433323221422422313553433425452324663245554536655554326624422435443626436552256464424624352636413242143535411323321222212134414313
222324211434321334233532534143131311242353465646253224554652653653422435642254245663622245433355456445562454412533254545222221344143341311122
322212341224344341433245241234425555552453423346256624666222456636325563532446545362553526364423256422345114245213224541344314433124323411131
111312132413122144323135414215543225153444362322356525452452452356345555632553532222235354333665362624225212425414412334544114331333221143211
122332344243113114144314534123511252331523132652452542663432643565426622464544366423233522464666352534215412214222541334342311424433423333321
211223224243324444224441431521434131252451135224333623265442642225653523535653324236342424534552252111413255122212415314111112313322241221222
212113121424143212343224342212325341112231455145336543333365466455536246252462365264643466655354352314115541222243143143414144342122431213211
312323312132421232244144211445241435551135245234253243242342262455222645633446444243345655121234353431542515144235524141411311421233123132122
131232212122341312221232341344525554312435154254534131334556526542542653426346455252353331523443244421444242555313322312124434113321333111133
131133221312324313412312432243212515351341414545433521154451412333542424643536635512413124341333222141133451421242143433422134122332233323331
231113221233222341232124132321211451441554134441534455422411151422513425131244433145554542343113552114533523252113111343313323213211121131123
322213212211112222114333144342114324353155512533222525434225114221442421414253341433251532554455214224244211311142212433411431311232111313131
212312221113133244413331343342212424534414254421312155554511123444113433511542332121333125153343511524122121333132411431123332413332322311213

View File

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

View File

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

View File

@ -24,7 +24,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
Box::new(day14::Day14 {}),
Box::new(day15::Day15 {}),
Box::new(day16::Day16 {}),
// Box::new(day17::Day17 {}),
Box::new(day17::Day17 {}),
// Box::new(day18::Day18 {}),
// Box::new(day19::Day19 {}),
// Box::new(day20::Day20 {}),

View File

@ -1,15 +1,8 @@
use super::Solution;
use crate::utils::Direction;
pub struct Day16 {}
#[derive(Clone, Copy, Debug)]
enum Direction {
Up,
Right,
Down,
Left
}
impl Solution for Day16 {
fn part1(
&self,

View File

@ -1,20 +1,78 @@
use super::Solution;
use crate::utils::Direction;
use std::collections::{HashMap, BinaryHeap};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
struct State {
cost: u32,
pos: (usize, usize),
dir: Direction,
steps: u8,
}
impl Ord for State {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
other
.cost
.cmp(&self.cost)
.then_with(|| self.pos.cmp(&other.pos))
}
}
impl PartialOrd for State {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
struct StateKey {
pos: (usize, usize),
dir: Direction,
steps: u8,
}
impl From<State> for StateKey {
fn from(value: State) -> Self {
Self {
pos: value.pos,
dir: value.dir,
steps: value.steps,
}
}
}
pub struct Day17 {}
impl Solution for Day17 {
fn part1(
&self,
_input: &mut Vec<String>,
input: &mut Vec<String>,
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
Ok(Box::new("Ready"))
let mut grid: HashMap<(usize, usize), u32> = HashMap::new();
for (y, row) in input.iter().enumerate() {
for (x, col) in row.chars().into_iter().enumerate() {
grid.insert((x, y), col.to_digit(10).unwrap());
}
}
Ok(Box::new(self.dijkstra((0, 0), (input[0].len() - 1, input.len() - 1), (input[0].len(), input.len()), 1, 3, grid).unwrap()))
}
fn part2(
&self,
_input: &mut Vec<String>,
input: &mut Vec<String>,
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
Ok(Box::new("Ready"))
let mut grid: HashMap<(usize, usize), u32> = HashMap::new();
for (y, row) in input.iter().enumerate() {
for (x, col) in row.chars().into_iter().enumerate() {
grid.insert((x, y), col.to_digit(10).unwrap());
}
}
Ok(Box::new(self.dijkstra((0, 0), (input[0].len() - 1, input.len() - 1), (input[0].len(), input.len()), 4, 10, grid).unwrap()))
}
fn get_day(&self) -> u8 {
@ -22,7 +80,97 @@ impl Solution for Day17 {
}
}
impl Day17 {}
impl Day17 {
fn dijkstra(
&self,
start: (usize, usize),
end: (usize, usize),
lens: (usize, usize),
min_step: u8,
max_step: u8,
grid: HashMap<(usize, usize), u32>,
) -> Option<u32> {
let mut dist = HashMap::<StateKey, u32>::new();
let mut heap = BinaryHeap::new();
let st1 = State {
cost: 0,
pos: start,
dir: Direction::Right,
steps: 0,
};
let st2 = State {
cost: 0,
pos: start,
dir: Direction::Down,
steps: 0,
};
dist.insert(st1.into(), 0);
dist.insert(st2.into(), 0);
heap.push(st1);
heap.push(st2);
while let Some(
state @ State {
cost,
pos,
dir,
steps,
},
) = heap.pop()
{
if pos == end && steps >= min_step {
return Some(cost);
}
if dist.get(&state.into()).is_some_and(|&c| c < cost) {
continue;
}
for (n, d) in self.neighbours(pos, dir, lens) {
let next = State {
cost: cost + grid[&n],
pos: n,
dir: d,
steps: if d == dir { steps + 1 } else { 1 },
};
if next.steps > max_step || dist.get(&next.into()).is_some_and(|&c| c <= next.cost) {
// For p1 and p2
// Streak gets too long
// Or a better solution/path already exists
continue;
}
if next.dir != dir && steps < min_step {
// For p2
// Making a turn but previous streak is too short
continue;
}
heap.push(next);
dist.insert(next.into(), next.cost);
}
}
None
}
fn neighbours(&self, (x, y): (usize, usize), dir: Direction, (x_len, y_len): (usize, usize)) -> Vec<((usize, usize), Direction)> {
const fn deltas(x: usize, y: usize) -> [((usize, usize), Direction); 4] {
[
((x, y.saturating_sub(1)), Direction::Up),
((x, y + 1), Direction::Down),
((x.saturating_sub(1), y), Direction::Left),
((x + 1, y), Direction::Right),
]
}
deltas(x, y)
.into_iter()
.filter_map(|(n, d)| {
if n == (x, y) || n.0 > x_len - 1 || n.1 > y_len - 1 || d == dir.flip() {
None
} else {
Some((n, d))
}
})
.collect()
}
}
/// Test from puzzle input
#[cfg(test)]
@ -44,7 +192,7 @@ mod test {
.unwrap()
.to_string();
assert_eq!(answer, "Ready");
assert_eq!(answer, "102");
}
#[test]
@ -61,6 +209,6 @@ mod test {
.unwrap()
.to_string();
assert_eq!(answer, "Ready");
assert_eq!(answer, "94");
}
}

View File

@ -57,3 +57,23 @@ pub fn gcd(first: u64, second: u64) -> u64 {
min = res;
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Direction {
Up,
Right,
Down,
Left
}
impl Direction {
/// Returns the oposite direction to the direction specified
pub fn flip(&self) -> Direction {
match *self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::Left => Direction::Right,
Direction::Right => Direction::Left
}
}
}