From a141be10ff9212eee053804a79599de3c1db6d5f Mon Sep 17 00:00:00 2001 From: Jake Pullen Date: Sun, 17 Dec 2023 09:38:30 +0000 Subject: [PATCH] day 17 done, added inputs and puzzle text to gitignore to honor the copywrite --- .gitignore | 2 + 2023/day_17/input.txt | 142 ++++++++++++++++++++++++++++++++- 2023/day_17/part 1 solution.py | 86 +++++++++++++++++++- 2023/day_17/part 2 solution.py | 91 ++++++++++++++++++++- 2023/day_17/puzzle_text.md | 79 +++++++++++++++++- 5 files changed, 394 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 7e88e93..4a62400 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ session_cookie.txt +puzzle_text.mk +input.txt # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/2023/day_17/input.txt b/2023/day_17/input.txt index b221142..711eb31 100644 --- a/2023/day_17/input.txt +++ b/2023/day_17/input.txt @@ -1 +1,141 @@ -Paste any inputs into this file. \ No newline at end of file +545452221113224242466233542635423355626253426445443455757673665557347647355656433643746353634644662254525636256443646245624542442323123124434 +423123553224156354662663652662565323453542525447336537477575644434676433736577536377777334455463373535224645325663632555343244432114515143455 +412533154242243224353222366252356526355257367576363643744576774435663654744573466766563337774647645676664423643264353633522462246212343543534 +312324515521642422652636445534644554523665356655534343537375547744446437364446564476574363354465364444335526246456466465534642522545221525355 +431513132425342544645256323442532642676557544454577773477553376746647356735654457637736466555435447757676662446326565224355645426536544353433 +152515313256642445666534554544332644373336536336456577474544746374336345737444775367547736546647553566343437636426552263525243344634253243155 +135443325556463563643622655423352436666776776734633546375567453734754553445667477777766555547773656573443454755625255564266524452554644145234 +241513543232556336524232462424435737746743746575776755464666467353446767477357654573667646735353777447336743456434254233635466225242632525121 +442114466425542236636355532623577635665736777673573577436763575554353467744376756337466776666746547776573643366373454532562525346426364521212 +541155622643423523354262433657364363646354575667566357546477534336746476674745444646634665776653773333473375747756253522266653336465444335443 +315134623523366526522266354747643547566373676536336653534764337367777657666544734333553663574737675665473765764555363545425566323646362446212 +353142355424432653444565325346456566644744764673467744633777464737845775474776766376767444574545433637456635633567664644636222333626546663624 +315262562366632565525535545577665554665674353536337736534348577475484854557474447578374345363774654336434544754674634746633244226523442264433 +335545645535423623266436675456635746457674747674657776647557877646646675874757745664876653556564444533753335375443577665252425255534456546245 +553355652652264636363367377346645567667346557653434567688677545486848565546546665444456784473354343544647657374633433333555233425565253533356 +243333363523322443663544336473347367764656335567475568787767645554484767666557847484654575478446467365374457346344653755573346552525256565322 +666223435352636335653467647754757343776765635446446788867658547858868785684748487568855845688555756333373536554535476756744646434652424342333 +645455232354462344243445636673564336664747664878865467785568865677886748754847884644784467558578757766455653753346354754754655533565264232532 +466264662434546564673354575575444753656373744566465676768746765458687768457555786448878877475448775543545436357333657537436536626255346662656 +654524643332325657443773473345666645437437457786476648665876645875844657466548548677668648768478465858346357657453545354733536252225236325324 +245235543533534454757574456473757344733876884576864756557877774546778774555757444877858775558546876676464645537473477737556335324623665264554 +552235662634536547455366376357656336444664848888574766754875756656755876868444465858655555676566668664686665663544655356774567736546326366635 +353542423524446556643335547536347646576756685775676766655557774844768557867884484585678554847845646654865854437565545635345436754335643323263 +326635253342553646346557637354574467764875575745775547574584574755667545768464448746656755546475444547874465334763664737345747437656333254563 +653335566256277556643667467346775367576846755455468867867557557555887765578448878848456454866856764644668486873436476677765536767642445626356 +353255366565746364356754435755657577566867745558644476548588748884548574488784666876485787774565875677468876756676547447547545755532634442565 +526256464444756734475435756673776484768854466755657745844446568666657957857746556588454768855565754764675454455437656334744533657457623236224 +345546363576475673635365446743587548544658648758765765475847775665595995997557889547584448655877685856876666444644644334674665743567346233266 +533654332435774354776646364446474846575477447574584776856576779765587966968987698878988545587567868486876764888877575753575453556376745642566 +633636424573637734764776635667487684676748668665568566866889869557556755989955889797856987487464457458644645786764873746476745365753365432463 +436434525766744544555467765487678745586567856888558789667967898667788975588775596575969899765767668556484474454574865565553453736343757423566 +562564353763677646656565447585778775865488767878759868968558979588977867688659588986697765665477854856584885664466675345566465573666456355365 +232544366666336545573336765565884686888688676464687896586586865697669996659769557995958979656645555844656646558777648564373757645766465564263 +325226433577434645734663776868484484574546847759659798668887755976978658579669665775876995696766765667567564857767757436736433534574356375464 +233434647657566365675564855678657456764555868565669776899967977985978785677658977569987558877878886856748745484877655877536777645733565672553 +346247373476565353376638555656666547878646777776699966987887775565755667655885557989588579667655656868844566557565885884763657647737363335464 +532243475547755575777345844444764678745788878877675956599689759687889958677777568677756559957698788764847454855744856566777557736766676435464 +262676537574457653774457566747874566475585789698955597778655878869799695678789958999766885657857566894858485757754485588476476734355556634663 +554273745665445654454755465755788884874769777895865665659996575789596765989769785679566759565995579779754867476767446844747337344367377354722 +223443465575665667345468464778664565646768567659578566988667856788688568878858975798856895758586987665776878777467678677846363447364466655752 +356675376476767636478486488564575777675577587995586676557599976687578955896587568597887786867768768799584654454457787674446666776457355366334 +446346746755447335376878747444548484767989866757676988577659767879598868996657877558889985695985588655575884455566754554678576776575736753747 +554354566643337445757665664854558565869858866656857656695755689989897768888898967697656665688856899957759956444477448748884634353575536635376 +534454344735356453685855755866568857866855877775658577698557768996777867979869796665786759779765759587979888785478444554847485657467766647545 +443436776547774645468645577867656488896978758777798895598889679866888688869967986666655558857856758797976585648874675868764677345555644357543 +257746743747434447467858858468464667666857679685959656776766788988696989987877767689978775665995977695959698477585465847875658656777474576447 +645547747335346637656657768676586568997777755987596665968768787877997778697867879896899888669887779959895769844445545565666568367653644677547 +553466736466736684746886666654678758976976679578775799668666689897777666887669787796967877596969796967796888966448555755588488566576673775433 +776446577567576687686786446648658876958999656689977798667789899869887868779686996797769789857565999575769965795557567748557544647767643763474 +445356637656674775556644475678659975969567657958685979868977878989668969687788668968878769775976789797698975665486687555884857456546534543563 +463645333465775785746547746866865768899858897765787788669686689668888676768786776797687678987958668775876759975857585586487667853553464535457 +564477673374747676645744768548578875768658857689997867667699686677789987896686787796899786989869758579587756857588556884768666757763734637656 +753556345564735887488486654567965956577557956858677778979967788997886678979888678999679867786776689598666566999857586845478647775545436555553 +345365637574455675565456864445579975865657859877896789776886696797878887676788766779699976687768989758796767975696688486546867688535773437576 +563643757353635744777558764668598788688667657587699768679877688999788976678779987678888899988696779888988599798896845755458568487466666645664 +543444466456568748754448767568587899956585778776877666796699889797797698667887698787866798988969666759756886776686778745884658447476754743675 +775555364536476764685787847556888796868878858669787979898869969899798699976896877676666868866868676677787775667578585574574466774833577574646 +634564673656787575774464768665888587665968667897896986988997878998889897878779887897997869989668679679957889756995447574784558575577733545643 +577736376747365476448748478477796768757799598789868889798968776688779897897789868968889799788966888869898975668865987448565667558857736635643 +466345746537546444778477645588885858759799788669769866667686687799778787887998988778696998968788686886759968759855878458545755745583464766353 +367655547534675485475587886859656798596775967889999876777668999898997779779999977967889897689698666959958577896968754558887878487466364554457 +653764635533546656444544748669777855769689666767996998967768787987877997777789877879797669966789688659586895965976884575646866457567553356675 +446653547537785576645688746776557769889589679688779797969868988999887999799878887798996677697677978795956576655686964586475875475887577735776 +344564775776467555666785757659665856977858698769987778997678797998997999999897899987886899987688889897695889685799576867746777467646546576365 +654736333377688685576656654998969878958759867686996898766689989879877978777889778787868686788887869786797867597879898644784877645754354536375 +767747647435455487886768675697877659896578787788669769779799998887879887889788888997789687686768666868776559656566955647588756888764347454776 +774457766435866645686575458679965688767955998897969876799898877798778987778797797888997778868978867995859657556696594555667474878485536473347 +366445576358856847557447789956599979755857769987889697967987878888879779878778977978986998889968887667768699579866588587785767748754376363554 +766344743577475764568847579997598855976966669699688996999998987878789798788998777778898668697689869778596566556756677764576558674474576657474 +736745557656466465485456767695967885795567669968688899788877778797997779788799999888779699767799986898695888998859665878677555646544465653554 +577753734565685574848584466665798865998576787897887876898999799789897997898988879777977976686779986687656986997797786567785888786465457333447 +543537356746774554476444747757978996777959898679879879898977897778987978898988989978978897768898866666796995878796566477765667684545335437676 +437766576438547766556675687655968789988677789998678687769788997898888998987997777989979796877677699676678769556989886464447864567655446374465 +774667644357778464657467446768777587599896669768898996799998899788777877898778789789886686796669799666668777585998986876745458765677776336474 +673456737734575477884884555698977778886667898889798678889979888778788778978887888777789669779686678965957559675775777488875554667477337777664 +665743475468848468864485465868588566687856668986879966888979797778988898997999899999898796978989787969699597586995555564868557476684777756734 +646554756444674645545745554559686885658675878898988999988988999789988998987879997879776797879869887967979579868767585566467556584857466573677 +364764647433677788866778744599756867979797699869867787666678777898999787898989797789767698987787689975759897675779695758585566676486736437565 +535657367676788744488555688866567598959667976889768897689998888978878888799897997777877889778777976969959559979798875545858676548565476756446 +633363763563454644784858847895797557969965876677987878976787878779988997777977799998877787677976867878977587865957557486665588466457543463635 +375433566546784568846466745598558655679968776668798787899889779877878988779887997778797888678778996867596666657866874675645464786473443555447 +434655743646446455646846467678988778555555686866869776667867788797877999888887888976676979997998988976998588698965984485774787566574577553376 +757663464775848684556667686775675566755668979679877689867998687897999788888899797969769667797686789969697795968885567685786664865545733646333 +436536333433585884585488446757557568878876857999666686869666787778897988977877887686867777689966698889899988598867685787566778656564477735445 +436574534734348886888756757498889965758885899878987888866677979798879779777899977868767868996877788995778656675966566755867567565574633456555 +564764653563688455554454885545886885979986956966688986677768987888887788888986967968696889979678777755778658995959858577865848685846647676536 +774666566543587578854654454459798858796687579678788997996798879976879988877696966976978868687797675777579588669865747866555654646757563764356 +334653746666747767874888446759658578686597896567669986768687786769869666679968799886689699667888658865797857988986544445767866746843445663555 +775344654767678685848468464575877876687899677597996789798676698776979787769968688886967768966777857569696867798987665668774554657436543557567 +766543343765565746568886858757686865568578796657979967896798688987979798966679878979878987979679598685776666567766775448885878555657665547357 +636655364436434455888845888778685568678599896776668766887767676667867787968869876966876666689866987776969877858886687745584764557354464333464 +675765663744534578545687478578698557858656798867678988867967999777996889699687796687898679786896785675995877868655448555846488877754667477734 +376666657777454776866467685478859857875585897867777886776668979799679889766696977797676899977576857679985779975754888884877866665753763656567 +553656636455355675644444444747459698859777767998579698866968997767787668988968899867897668767998695767758686979684446467848778567374445455366 +754746745637544445664687865676568868689986785689987697689689969698679786996868877777898786786677866785998778985766777464665886563347736757447 +744657466646636774744445554675666676868675955555767858786996667879668878978868776888798796869879978857865577996565788644766846855557536433763 +446745655755373767857866885858587788668877866696695565989667697677966767697869689788978969797665869856666577584454657576664775376733565354756 +654636755367566664586687484447778479787695578876796699778799789899898676987968866887987986956877768755999996846745684654755648755434654444754 +635344556537573455855776668478688447578999955979699999695669968667779887688976668788756786965858995755576656777877658545555555647667534575366 +435747556465374336665458878467447445675959779776975698666756899678787988689897869778795885896759756577958888884545566466868655534765435574357 +437767766643564433747554467577668757587776755668689999998555765778667999677696988696955786556876667667988974746747864478454737537664677453677 +664347635467563437656868568685484468455677569986876985879577699879986797878559965665568857786598876697898847446667476764656445454547563774635 +335453357433477464545778558588687458646696878686798565588759596859598855679658897766897786687897896866587457546877768774845653576735343735752 +655777543774646674548678844477675556474688567958786967887956958887675987768675555986588965589688887889886444888584878476586567343575354445663 +235453363477465436646567678856678577655849767566798556879779898997989755658656559688876996696676858559457557464577456788673465676535365674745 +653557535667556645354467867774587468586488865599677669989755886567678697988757889697878875858955878776457675775448445776473464477477767663723 +423647457774664567367567688588786455886875877685666999576569666558878966575579888958887568875959897748876746485847657558833665657763667534445 +642244736374347334553476484454457886864876777558556996776685999679967876675775769557785885758655565867454657858447768578474753663535574334625 +336436733375445675473664646565856555648864767887656769899695675757975675565687699957587897798858758888587654455645575843733477364463637346554 +335435534663443676666667487578676657684784777487588895569858889859686655956678559995599665976775765566474568674477774565755333637557456443362 +544553574555543574737357456786577646746577857444859685759965869665959565775665768787565556566764745674557877684464784337435554455363447424542 +532466367673434664644354657754588778676755775886768666885868799568878785557855988668678578786766445778646767754547786674353344647665577622636 +254546266574455447676333746874647468845746684454766755965578588856776657996755995866665756584754744857764888446555686474747766466477373363255 +266564352377575777574547445766866788765476854777647777755855596796559556988877659996958566787777584545576775754474473767554467654656553554332 +522256355666446675564456747738664767486874667675476687786478896698989959668656659687968467645876545646468576457566664435353565756335325455423 +444323436545645543755363664545566464457866856586678787858786757778956969568579798946747584467867878657848746487767644665534735673753556344635 +323454432324636457364755566663657568465848475587778876786656855775678985985658687848774858847777567884787865845753573673347657574545444662333 +634265532422373635667776375763433576454587888546578776578558775467647857865566478665585765455686464585664454657577753367736355637473456622255 +622652422623346667557377766536775386775555647476757786588468585876875775475874454678454778445754858785856648473657737554774554374752234543644 +626444363465537553657447547553534338748756846655465484858676444775654756856447485566556646575845685575686466474566556633663543776752343555663 +535442263436653363546357777754675735775658785476758746846756747484788667788686756847555568587746787644556655745755367533554735377434563655355 +554342625636334436643667447345746337765466846668685587767846687654478458468576565878864858748845754784458634476773434474546454344452263624345 +565345336254245667667673464644643655375486646848574888844888558867884754554747767566586664467557686445654336335375474476363464323325434436625 +332442354652352554553756635666445463456537777656657588588744485464885685786874588448866685887758677684775654736344634537577646434553463233633 +264423644454226544363333743363353543453764748557767447766744574745865865746448687884547865745856555847664474444567466455356545323344624233336 +624364424324325525254434475736744543756757746455757545887885684854876555585578764754564576867554753746356355666473343373737424256554255423523 +662433222232665256245775334733557673537364464544457667464687655758776565487564647678487555685857676544475746676457447467754565543233223432355 +335526225663422356565753436745336336337473673334447858766557576685575848668868544646668474687675476677666534474734376777532524234366425532456 +224434544223322234353647375646454645545464356533655787476846747488548474786866778666778547634433667755755733766475767655364426634454342243225 +115343665234633546565263376447534744657646576367346453768575867668478755786458868487856743347563663553647377756353665654344434266256634336435 +542522653445666245465264554744743545554757337454635474734676576664554868545884455857744457443343774776545543664436646636526654445346625264641 +212345454243326345366432525643537663566453477653467557566745535745888465744676443367676664343457436353346547364465644462456633524632446434245 +152256444334346664644636266764544353565677537647674477765463657665645367433374777437633774465675755553674563647647452223353432253226324623542 +543314543643455255443324653447436466475546347473733756375574455574647736546663676737753633747536667644363433373577625266565562536523653263531 +323324156556533366424334223663556664354675665737455445654473743546365645433344367436563477354677564675374746774552632626523436564364436333125 +235252143234364223446642636543224575373637463676356753733454753456563336535346777535556775743565435544465673644434525462634226464524365541444 +132152313563645443345466655333626644763757433545675545554636757343657777557575474647543744454353557547677667745433252345352224344346244251442 +145324252553642322332363652223266265665333337557545545565467373344435373577653536363764744455463574577733745442455342654643644622632454545141 +532551554325522544422365464343624222657554543453736435733353775644654357356557335773453777745644576533447446326624326254632635265444511254421 +231415354245432533366263463246653334334533336463333665345436677477356745734756355353637773745467756534536353223454622442252244524633251135155 +115313455335154364554632663442562633255536347755433457547673466773633747543655343555654635633737643533463222323433222456626424343225333455422 \ No newline at end of file diff --git a/2023/day_17/part 1 solution.py b/2023/day_17/part 1 solution.py index 3f8c986..8dc64e3 100644 --- a/2023/day_17/part 1 solution.py +++ b/2023/day_17/part 1 solution.py @@ -1,6 +1,88 @@ -import os +import heapq with open(r'advent_of_code\2023\day_17\input.txt', 'r') as file: input = file.read() -print(input) +test_input = '''2413432311323 +3215453535623 +3255245654254 +3446585845452 +4546657867536 +1438598798454 +4457876987766 +3637877979653 +4654967986887 +4564679986453 +1224686865563 +2546548887735 +4322674655533''' + +# Read the input data from the file +#input_data = test_input +input_data = input + + +# Split the input data into lines +lines = input_data.split('\n') + +# Create a grid from the lines +grid = [[char for char in row] for row in lines] + +# Get the number of rows and columns in the grid +num_rows = len(grid) +num_columns = len(grid[0]) + +# Function to solve the problem +def solve(): + queue = [(0, 0, 0, -1, -1)] + # Initialize the dictionary to store the minimum distance to each position + min_distance = {} + + # While the queue is not empty + while queue: + # Pop the position with the smallest distance from the queue + distance, row, column, direction, in_direction = heapq.heappop(queue) + + # If the position has already been visited + if (row, column, direction, in_direction) in min_distance: + continue + + # Update the minimum distance to the current position + min_distance[(row, column, direction, in_direction)] = distance + + # For each possible move + for i, (delta_row, delta_column) in enumerate([[-1, 0], [0, 1], [1, 0], [0, -1]]): + # Calculate the new position and direction + new_row = row + delta_row + new_column = column + delta_column + new_direction = i + new_in_direction = 1 if new_direction != direction else in_direction + 1 + + # Check if the move is not a reverse move + is_not_reverse = ((new_direction + 2) % 4 != direction) + + # Check if the move is valid + is_valid = (new_in_direction <= 3) + + # If the new position is inside the grid and the move is not a reverse move and the move is valid + if 0 <= new_row < num_rows and 0 <= new_column < num_columns and is_not_reverse and is_valid: + # Calculate the cost of the move + cost = int(grid[new_row][new_column]) + # Add the new position to the queue + heapq.heappush(queue, (distance + cost, new_row, new_column, new_direction, new_in_direction)) + + # Initialize the answer with a large number + answer = 1e9 + + # For each position in the dictionary + for (row, column, direction, in_direction), value in min_distance.items(): + # If the position is the bottom right corner of the grid + if row == num_rows - 1 and column == num_columns - 1: + # Update the answer + answer = min(answer, value) + + # Return the answer + return answer + +# Print the solution for part 1 +print(solve()) \ No newline at end of file diff --git a/2023/day_17/part 2 solution.py b/2023/day_17/part 2 solution.py index 3f8c986..b579d01 100644 --- a/2023/day_17/part 2 solution.py +++ b/2023/day_17/part 2 solution.py @@ -1,6 +1,93 @@ -import os +import heapq with open(r'advent_of_code\2023\day_17\input.txt', 'r') as file: input = file.read() -print(input) +test_input = '''2413432311323 +3215453535623 +3255245654254 +3446585845452 +4546657867536 +1438598798454 +4457876987766 +3637877979653 +4654967986887 +4564679986453 +1224686865563 +2546548887735 +4322674655533''' + +# Read the input data from the file +#input_data = test_input +input_data = input + +# Split the input data into lines +lines = input_data.split('\n') + +# Create a grid from the lines +grid = [[char for char in row] for row in lines] + +# Get the number of rows and columns in the grid +num_rows = len(grid) +num_columns = len(grid[0]) + +# Function to solve the problem +def solve(part2): + # Initialize the queue with the starting position and direction + queue = [(0, 0, 0, -1, -1)] + # Initialize the dictionary to store the minimum distance to each position + min_distance = {} + + # While the queue is not empty + while queue: + # Pop the position with the smallest distance from the queue + distance, row, column, direction, in_direction = heapq.heappop(queue) + + # If the position has already been visited + if (row, column, direction, in_direction) in min_distance: + continue + + # Update the minimum distance to the current position + min_distance[(row, column, direction, in_direction)] = distance + + # For each possible move + for i, (delta_row, delta_column) in enumerate([[-1, 0], [0, 1], [1, 0], [0, -1]]): + # Calculate the new position and direction + new_row = row + delta_row + new_column = column + delta_column + new_direction = i + new_in_direction = 1 if new_direction != direction else in_direction + 1 + + # Check if the move is not a reverse move + is_not_reverse = ((new_direction + 2) % 4 != direction) + + # Check if the move is valid + is_valid_part1 = (new_in_direction <= 3) + is_valid_part2 = (new_in_direction <= 10 and (new_direction == direction or in_direction >= 4 or in_direction == -1)) + is_valid = is_valid_part2 if part2 else is_valid_part1 + + # If the new position is inside the grid and the move is not a reverse move and the move is valid + if 0 <= new_row < num_rows and 0 <= new_column < num_columns and is_not_reverse and is_valid: + # Calculate the cost of the move + cost = int(grid[new_row][new_column]) + # Add the new position to the queue + heapq.heappush(queue, (distance + cost, new_row, new_column, new_direction, new_in_direction)) + + # Initialize the answer with a large number + answer = 1e9 + + # For each position in the dictionary + for (row, column, direction, in_direction), value in min_distance.items(): + # If the position is the bottom right corner of the grid + if row == num_rows - 1 and column == num_columns - 1: + # Update the answer + answer = min(answer, value) + + # Return the answer + return answer + +# Print the solution for part 1 +print(solve(False)) + +# Print the solution for part 2 +print(solve(True)) \ No newline at end of file diff --git a/2023/day_17/puzzle_text.md b/2023/day_17/puzzle_text.md index 44367ed..60d2955 100644 --- a/2023/day_17/puzzle_text.md +++ b/2023/day_17/puzzle_text.md @@ -1 +1,78 @@ -# Day 17 Puzzle Text. \ No newline at end of file + +

--- Day 17: Clumsy Crucible ---

The lava starts flowing rapidly once the Lava Production Facility is operational. As you leave, the reindeer offers you a parachute, allowing you to quickly reach Gear Island.

+

As you descend, your bird's-eye view of Gear Island reveals why you had trouble finding anyone on your way up: half of Gear Island is empty, but the half below you is a giant factory city!

+

You land near the gradually-filling pool of lava at the base of your new lavafall. Lavaducts will eventually carry the lava throughout the city, but to make use of it immediately, Elves are loading it into large crucibles on wheels.

+

The crucibles are top-heavy and pushed by hand. Unfortunately, the crucibles become very difficult to steer at high speeds, and so it can be hard to go in a straight line for very long.

+

To get Desert Island the machine parts it needs as soon as possible, you'll need to find the best way to get the crucible from the lava pool to the machine parts factory. To do this, you need to minimize heat loss while choosing a route that doesn't require the crucible to go in a straight line for too long.

+

Fortunately, the Elves here have a map (your puzzle input) that uses traffic patterns, ambient temperature, and hundreds of other parameters to calculate exactly how much heat loss can be expected for a crucible entering any particular city block.

+

For example:

+
2413432311323
+3215453535623
+3255245654254
+3446585845452
+4546657867536
+1438598798454
+4457876987766
+3637877979653
+4654967986887
+4564679986453
+1224686865563
+2546548887735
+4322674655533
+
+

Each city block is marked by a single digit that represents the amount of heat loss if the crucible enters that block. The starting point, the lava pool, is the top-left city block; the destination, the machine parts factory, is the bottom-right city block. (Because you already start in the top-left block, you don't incur that block's heat loss unless you leave that block and then return to it.)

+

Because it is difficult to keep the top-heavy crucible going in a straight line for very long, it can move at most three blocks in a single direction before it must turn 90 degrees left or right. The crucible also can't reverse direction; after entering each city block, it may only turn left, continue straight, or turn right.

+

One way to minimize heat loss is this path:

+
2>>34^>>>1323
+32v>>>35v5623
+32552456v>>54
+3446585845v52
+4546657867v>6
+14385987984v4
+44578769877v6
+36378779796v>
+465496798688v
+456467998645v
+12246868655<v
+25465488877v5
+43226746555v>
+
+

This path never moves more than three consecutive blocks in the same direction and incurs a heat loss of only 102.

+

Directing the crucible from the lava pool to the machine parts factory, but not moving more than three consecutive blocks in the same direction, what is the least heat loss it can incur?

+ +

Your puzzle answer was 1246.

The first half of this puzzle is complete! It provides one gold star: *

+

--- Part Two ---

The crucibles of lava simply aren't large enough to provide an adequate supply of lava to the machine parts factory. Instead, the Elves are going to upgrade to ultra crucibles.

+

Ultra crucibles are even more difficult to steer than normal crucibles. Not only do they have trouble going in a straight line, but they also have trouble turning!

+

Once an ultra crucible starts moving in a direction, it needs to move a minimum of four blocks in that direction before it can turn (or even before it can stop at the end). However, it will eventually start to get wobbly: an ultra crucible can move a maximum of ten consecutive blocks without turning.

+

In the above example, an ultra crucible could follow this path to minimize heat loss:

+
2>>>>>>>>1323
+32154535v5623
+32552456v4254
+34465858v5452
+45466578v>>>>
+143859879845v
+445787698776v
+363787797965v
+465496798688v
+456467998645v
+122468686556v
+254654888773v
+432267465553v
+
+

In the above example, an ultra crucible would incur the minimum possible heat loss of 94.

+

Here's another example:

+
111111111111
+999999999991
+999999999991
+999999999991
+999999999991
+
+

Sadly, an ultra crucible would need to take an unfortunate path like this one:

+
1>>>>>>>1111
+9999999v9991
+9999999v9991
+9999999v9991
+9999999v>>>>
+
+

This route causes the ultra crucible to incur the minimum possible heat loss of 71.

+

Directing the ultra crucible from the lava pool to the machine parts factory, what is the least heat loss it can incur?