diff --git a/day17/c/day17 b/day17/c/day17 new file mode 100755 index 0000000..dd3d13d Binary files /dev/null and b/day17/c/day17 differ diff --git a/day17/c/day17.c b/day17/c/day17.c new file mode 100644 index 0000000..5a442c4 --- /dev/null +++ b/day17/c/day17.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include + +#define LINE_MAX_LENGTH 256 +#define NUM_0_CHARCODE 48 +#define equal(a,b) ((a)[0] == (b)[0] && (a)[1] == (b)[1]) +#define MAX_NODES 128*1024 +#define MAX_PATH 1024 +#define BIT_0 0x0000001 +#define BIT_1 0x0000002 +#define BIT_2 0x0000004 +#define BIT_3 0x0000008 + +typedef struct node { + int position[2]; + int weight; + int dir[2]; + int forward_count; +} node_t; + +void insert_to_queue(node_t *nodes, int *nodes_num, node_t node); +long dir_to_bit(int dir[2]); +void set_tmp(node_t *tmp, int next_x, int next_y, uint8_t map[LINE_MAX_LENGTH][LINE_MAX_LENGTH], node_t curr, int next_dir[2], int fwd); +void find_path(node_t *curr, int start[2], int finish[2], uint8_t map[LINE_MAX_LENGTH][LINE_MAX_LENGTH], int x, int y, int min_fwd, int max_fwd); + +int main() { + char *p, *buf, c; + + buf = (char *)malloc(LINE_MAX_LENGTH); + memset(buf, 0, LINE_MAX_LENGTH); + p = buf; + + uint8_t map[LINE_MAX_LENGTH][LINE_MAX_LENGTH]; + memset(map, 0, LINE_MAX_LENGTH * LINE_MAX_LENGTH * sizeof(uint8_t)); + int x = 0, y = 0; + + while ((c = getchar()) != EOF) { + *p++ = c; + if (c == '\n') { + p = buf; + x = 0; + + while (*p != '\n') { + map[x][y] = *p - NUM_0_CHARCODE; + p++; + x++; + } + y++; + memset(buf, 0, LINE_MAX_LENGTH); + p = buf; + } + } + + int start[2] = {0, 0}; + int finish[2] = {x - 1, y - 1}; + node_t curr; + + find_path(&curr, start, finish, map, x, y, 0, 3); + + printf("%i\n", curr.weight); + + find_path(&curr, start, finish, map, x, y, 4, 10); + + printf("%i\n", curr.weight); + + free(buf); +} + +void insert_to_queue(node_t *nodes, int *nodes_num, node_t node) { + int inserted = 0; + for (int i = 0; i < *nodes_num; i++) { + if (node.weight < nodes[i].weight) { + // Shift to the right + for (int j = *nodes_num; j > i; j--) { + memcpy(&nodes[j], &nodes[j-1], sizeof(node_t)); + } + memcpy(&nodes[i], &node, sizeof(node_t)); + inserted = 1; + break; + } + } + + if (!inserted) { + memcpy(&nodes[*nodes_num], &node, sizeof(node_t)); + } + (*nodes_num)++; +} + +long dir_to_bit(int dir[2]) { + if (dir[0] == 1) { + return BIT_0; + } + + if (dir[0] == -1) { + return BIT_1; + } + + if (dir[1] == 1) { + return BIT_2; + } + + return BIT_3; +} + +void set_tmp(node_t *tmp, int next_x, int next_y, uint8_t map[LINE_MAX_LENGTH][LINE_MAX_LENGTH], node_t curr, int next_dir[2], int fwd) { + tmp->position[0] = next_x; + tmp->position[1] = next_y; + tmp->weight = curr.weight + map[next_x][next_y]; + tmp->dir[0] = next_dir[0]; + tmp->dir[1] = next_dir[1]; + tmp->forward_count = fwd ? curr.forward_count + 1 : 1; +} + +void find_path(node_t *curr, int start[2], int finish[2], uint8_t map[LINE_MAX_LENGTH][LINE_MAX_LENGTH], int x, int y, int min_fwd, int max_fwd) { + node_t tmp; + tmp.position[0] = start[0]; + tmp.position[1] = start[1]; + tmp.weight = 0; + tmp.dir[0] = 1; + tmp.dir[1] = 0; + tmp.forward_count = 1; + long visited[LINE_MAX_LENGTH][LINE_MAX_LENGTH]; + memset(visited, 0, LINE_MAX_LENGTH * LINE_MAX_LENGTH * sizeof(long)); + + node_t *nodes = (node_t*)malloc(MAX_NODES * sizeof(node_t)); + memset(nodes, 0, MAX_NODES * sizeof(node_t)); + int nodes_num = 1; + memcpy(&nodes[0], &tmp, sizeof(node_t)); + int next_x, next_y, next_dir[2]; + for (;;) { + // Pop first node + memcpy(curr, &nodes[0], sizeof(node_t)); + + if (equal(curr->position, finish) && curr->forward_count >= min_fwd) { + break; + } + // Shift entries + for (int i = 0; i < nodes_num - 1; i++) { + memcpy(&nodes[i], &nodes[i+1], sizeof(node_t)); + } + nodes_num--; + + // Check forward direction + if (curr->forward_count != max_fwd) { + next_dir[0] = curr->dir[0]; + next_dir[1] = curr->dir[1]; + next_x = curr->position[0] + next_dir[0]; + next_y = curr->position[1] + next_dir[1]; + + if (next_x >= 0 && next_x < x && next_y >= 0 && next_y < y && !(visited[next_x][next_y] & (dir_to_bit(next_dir) << (curr->forward_count * 4)))) { + visited[next_x][next_y] |= (dir_to_bit(next_dir) << (curr->forward_count * 4)); + set_tmp(&tmp, next_x, next_y, map, *curr, next_dir, 1); + insert_to_queue(nodes, &nodes_num, tmp); + } + } + + next_dir[0] = curr->dir[0] == 0 ? 1 : 0; + next_dir[1] = curr->dir[1] == 0 ? 1 : 0; + next_x = curr->position[0] + next_dir[0]; + next_y = curr->position[1] + next_dir[1]; + if (curr->forward_count >= min_fwd && next_x >= 0 && next_x < x && next_y >= 0 && next_y < y && !(visited[next_x][next_y] & (dir_to_bit(next_dir) << (max_fwd * 4)))) { + visited[next_x][next_y] |= (dir_to_bit(next_dir) << (max_fwd * 4)); + set_tmp(&tmp, next_x, next_y, map, *curr, next_dir, 0); + insert_to_queue(nodes, &nodes_num, tmp); + } + + next_dir[0] = curr->dir[0] == 0 ? -1 : 0; + next_dir[1] = curr->dir[1] == 0 ? -1 : 0; + next_x = curr->position[0] + next_dir[0]; + next_y = curr->position[1] + next_dir[1]; + if (curr->forward_count >= min_fwd && next_x >= 0 && next_x < x && next_y >= 0 && next_y < y && !(visited[next_x][next_y] & (dir_to_bit(next_dir) << (max_fwd * 4)))) { + visited[next_x][next_y] |= (dir_to_bit(next_dir) << (max_fwd * 4)); + set_tmp(&tmp, next_x, next_y, map, *curr, next_dir, 0); + insert_to_queue(nodes, &nodes_num, tmp); + } + + if (nodes_num == 0) { + printf("No path to end\n"); + break; + } + } + free(nodes); +} diff --git a/day17/input.txt b/day17/input.txt new file mode 100644 index 0000000..8f39001 --- /dev/null +++ b/day17/input.txt @@ -0,0 +1,141 @@ +322222331232132221112333141131141421432535111315454231154425333445331325214334352425212345343422113421533234333342231121312224211232132331311 +112222221132312141233334323313423341313142332514144441221332524235451353431144233453551355535521415123254413343222433142441412131232231122221 +233311211132123132221413413342313144254415324345245135411343525533355513313524342444244552154352343444341241224233132212231434412321112213132 +122121222123133442422242231341123325225213254443245241522123133531323555532233151534115233215142445532322342151213321214342313432231323113123 +333221122312222411121442113241232534233432521555121441223215535431542235361313542254543322532531154144522513554533443441341444111111321121333 +211331211214432233123223424223124532151344214214542223331353264642443432464436224423224313223252125355413525423152224342423114131411112111123 +321223112344113433231424123325532125514251543332123251155363265243452334535223565553644354421552113311325513113444511443343413432243231313333 +331112133142443233432421114422112423521245553211111523242563534534562453423253433464252355615233351324133352335421242442142134213132421212232 +123123132324211421233414412211533554345522213452545454536356224246525264445422262363524343225625252212421135334423251133211443213214112122122 +121221241431433223122131445353552233142144512443252243362553462252633665622344555425653436444465214112414411121121114514124141222324134111222 +133112144124112314211245532541231542542135512356236336563252252643564354434566234566342436235632443531431233413141321355444213214223322423332 +322132441311211324331354355511325535454343332336355243323534546646445434666434356245233443234355464421551444314452551232413312111222342422132 +332112144311441331145235233355512421155156656566655324663456462643234333652442646456526324524435666264354525124554151514344111232333123121232 +112322143122443321255444531524442254522435344466544446225563232454254336646644453432456442265426224633364413545552141231232342443134312424322 +211112433314214414121554231413313431264645245424625662356556356363526434463335423263455622432234243652233651124423324145351422433444413233242 +123412313414223441541432354411133533264565324623356522334552452232222235346254322544256225266444465563624663145242355442225325131344441434431 +122232241113233344414343445245334526626224652262554436326624425654546753366453737333434566325324232256666566465541522125315544113322131424313 +441131142343322224354232433122154334244453262644636226432735355445376336457435675653434424226226554263663436634131141121112212521241142321232 +444124213331242524531555541123263435226643536536425642566335447454777555373634744664333634623364456664254352535441433522414143232432133312141 +142323312314135231332412115353444646325624242262433637566663535477543343575346673575566463756653266553236665325236325123231544443414221443432 +133332214211214512511334522363626634345432634234666347475673545334567454333665333576563637635363565362524656455244455214423524135332241112343 +114332313215243122212252352362462564564232565327436544463373743636663353454736374665776566476746432522662336422255461425241315315553244323324 +244113213443433453312254442326242365253345446477645575746733344546446356353436466556776654557445633664365364254554262454122333435243234441244 +123133241351413144322431436253253364555363566547664357364763645337356755445663333755367347437736645644534466442424465622335515552345223114132 +141313223214133413535525225635234556344253774463564757456364334433557373347466336733657334573673434763453634355653256221125514413333512421413 +211121435455322131411522253334522524622544466575377334767736555357537733536675363657467556556673734365355346223246664252445312521512143341213 +332112111553531125445446523366463445537367445346365446335537556536434636555356675375456337733736757365346555654534526656553112414115442343431 +334323341513433241114523442435633456453436453567566443375366734684585655664865675435643534674434744767767333656223563665331323153212455312432 +214314422254423141124253362526654246747334664673454533366676454748888877776756674465474764467464765335636744663634563446233514225243123132134 +221422142552342124425653343364465434643664433546553363355685647884564674785885575486566465774563367363755763646622533526434545511232231432332 +131433153555224431352333622333525534653646537757446733746685664657876486887856687457474885575443346475434476536426665533526555423525114543143 +414241342153331114533342663553345453557573336633565378468874774454686655858846664676674578677565646434577735336422624662264235213343545134142 +422244331152252533356444644642455653634367437537666758685886576658586455555774455576784768545547457776764576377324655644335242441215542311123 +224514311332324242565636562655637475653434634444657476468485645887444747545566846648888555466687367765343444634536335554435446552553424521452 +324235324155152356524453432522667443344757556358656654687574754764658686465764884887485465874455475445346554773356334265444255333253343144414 +422155422455233453265254553566435573557344535678585454448445848876874775857565648577744784557686584733547637647666563335352253255433145143325 +433522423543246253243562266265653675734363374788654878446558787775868774745648585768584467654645865464634776476743662656334634244532254554223 +112345432553324646256344452563676533734565448486848444474866678688445746558464865554564485485545584764747547774754536532455325263313454154144 +421331512554232363542455634433545333654378757764885664588484868588998998685995846766466678454557847578576466763755573652655565366235332454123 +134154422313262464256254654773353533337648867775767446685857787668566778565568657556848888464545675546643744436744557236545455522654511214542 +112411314514523646326445544635655366776764888547846646744467988655959979885758577589657656577576456686655353733563633344446625362364333345133 +211512544551565256423432474775576664545654687446758847488965895996789986579865686776897658554775844545786545467636655664426546522431523233541 +254121351444222654563456537446766653446447844486786747879967767776888966755788565956589746644586858548478855347636455665553425352625443222352 +451334343256326255354425675633565746775544566747785759695789698868776866668598597658557566666774884648467566677366444334355264652355223454352 +155151522152425333432626354533656634555844757447476698598879888959659585587795857588675958656788578667867657566633733344526545352652553311352 +323311225332555322334644436665373337767457786854668867567985596968898656885687676977785665879777747478584778573345654757554562666335411321112 +142444221335424244536656477453464455744887865446887787855585777685796976868758586897765699887954868887755464763476753644534362545225642333444 +311125151633663542456465333376767765786657565778767955557876559955689578586576585797986779967698764667848668665747635664435235222536423442522 +144554313565643664236735676567364486685774468847969997585567999667988979868896977566559989556677745448577455763634475546563246245333642251442 +124214126256353433325473676455454666788856858698575977697766599669866999879567996989966899797576864675847466646747644765443545446645464154342 +234124226225525534535674553355765857686864865767897575989977768778898969976676695899888665967559967644586575564767537765734326524333465354225 +111551143364233333665643467766438664557567678787898866578797588868798779999699767655579989956698785867665846684775346733737464263262223423535 +421142363333253664544635635565747785478446775558697785969987878967866898678977898767665798797676555777844866875437565537556343535323245315143 +345451135266466434675467566347387784585488857975558655988686966879969689867987676689658669555877886654554844677874374375647452532563465323312 +242344235526446225574577365666857586685844858595768997599866987776696969789998767977998688696585596748446874845767546643477356665366322243513 +532115353236434346534634733555468887444458798785586687666896797669699668879888678989789975575797967797446777787773765636465353253444235324124 +235252242332246463467535455567845748488877859896995668669999977886978787798967787789697986965568759965575866767684446575767766556534632223343 +143343325563554625676677466736585746688768796796597668897988677999977687767877778687688699596756555977655786864458675757535765244622653564445 +545315646456655266556653677767587445855588796556985766998667888899887979788686979978889977557598975555844475855845377463446464555262342631255 +225323565454336424365556773756857467464878759576599956696878999969999898888968786667778988659878759657948786484475467365633534655233653353235 +224456254554422567564536775664546477547496965696857878869687787688788689898868798866776677786775879975586787856564673365735573535355336643124 +543456555444426224545554573586765657466559558587778966798787896889889977799898886898997977867687585566966546665755565446657556435234526266454 +315536325363343234433576335774558558648696679779999987876899698688897777878779896786769797695668779777566586765854453534633757444253423625124 +151216343662665453744746445345584547677965779558577699779886978978777897877977999699897967999896857857567477554548633463477463436533242564425 +543355354446632363335673367868545465458855986855886769967868668887898997997779797889797789986979895575796847754484547453753543325425346663312 +535322533226325265767647536855854855778979965879769897779967969888779887797988788766667777977689986668684474868785466476357456665654234465422 +231556524524226674547774473577586775489576795799987997979988777988878798898979988779998877686665678579598888858487544564677765355264626364355 +354215356635232277535766636447878578669956779799558778996768979798988889979889779967876877966557957959587447848557557543533356453246253366234 +544153364554564456764536556464688677765858958656696869678987689977798987889888897977876867798796895759888764846576743454376377365453456435242 +525152435566645637336466733788745548648698786968877688677769779987978987789788999968789887968656659668895788467868645643335453444225226564223 +554456254232442545777435733656455785856855968689797989978989998979989887797777797976786767789995886788998575456486644647567746642446655425652 +552564443563356465645755534444484775746676866969686899686988899789877798797987988877867977966776888778685645444876565554734346554535452535642 +532426532465544566736373337854774776469589868759887699866868799987778898988888988986999888977689658558785555676674563743364767746445624552333 +224355342623332446467776757776465567785866775787976966967786797879987977979887897769767669698676797997899887656865744456675564542545425242511 +423424563462454366676567475856764458447599968889989679788788997777777789778778978869897867878976867889765758656648566746737475334465564536233 +454354245243524276633735643586686864846687557668997987876996879788778787797997888887866789999996989598656747776576584434473565343422544655523 +134213565432233465576366665487445544577887868868667869978999789878777988888787798679687997698658996767868685676666886753643377763624563546545 +532526426424453576553556543646845455884766968656687677789798797787887887799978988987868899889988659759595786484466747636434764443634222623112 +542124434443543643563654343446677677865867697586879688897676867878998898978989799997897676878989798989894674848855564375747446466225322665122 +255252546255422477374435674555867867846875859668568976669679866687988897888887767987676867685686896869984666465866436477476453332334245662542 +521356225624562566737635377668646645674597898979975767987777986999779797979787989767687876969858658797875578475575844544575376744663524426112 +445433354652342445476743633654745688748585786556759599669677668868787887798779686867799996687885695767966766658677433575764544533355666466235 +233545323366363443337334575665656688465679988569788899696799768867686879798678896669999999678786979799758457575467834667547446422625542453532 +324551224454322244447567665378587865658577789765599566876768689788999686766989687679969779997585677767748848548857743346556535524656256542114 +351542435666443534653733675577668888446688685688566896889967698777767679879699797968969696779957888876558466675655337434566444452232256353141 +311234446553626523657447336368764547755445787587888656797968979698698679799878676799677787958798569698645864667884564337475477634264343454123 +115512526244454342364454343545675548487884588995597578869968989986689887798879779679776976775797956658748777646557343436344353622662465244111 +122211552645355262744655766376755587575864856558998666687987677799978987698878777798777775786979767587568477585747657336557735534625335232455 +425345443424245433375455547633778546574776765755765855888797968989997799876668999797669979886787688876547677654773776745434562333653263224523 +555251326362654363237546435473346468884476467796588875986769677679987979967879988869668699867555669955445674845675654745564655365665446543555 +251445423464566444547337744665776567644578465769676786559588667977677786989966798688666778655767877684666874657464563343775666634426234234531 +341355143244643626455357536755754585648456787595697879688996577986866979878868977979659969966867565678667484454756454375754462663543452534243 +411222154254544422667433433675666457848545545989798668975957675887979988699687798967697968568959784658856455566644673776554336545643436145141 +111122522642643455345565565336453847775464574889689865766896866699599898777567755897685679777856958657445858653767456364347624464332533335154 +524241542223363646625344447455676474586754455669665886589999589768559775556599589956665988786989478684546555454663534636576332446266461343514 +113533134433523524446375667645566447688876847855859957979767989878967979789999855959685696789985867764675664874634464336565224222646642321321 +245124345333555642252444454546376467867578884786479978989977659769956667868756689966765555985878864575655545774476473456565366462243363441453 +325354232436363363425333443734637667468756576648479988858967756758868779757888957989878668976654457564455648465766544656664643642266233352414 +451353323252436433336444757666564636547545444868484855686795879665895669878698685666795967568575477757788876676753437756326524635444422233212 +314251335526245463465344464664557574685576548854568759856996687769699776867988576768857557867678466888568855544765437763432222442344311351454 +221343454312356446253652533564454347687864847866685854878977995585678858876868579559676767585687778868678774743747547636565333442562245414433 +153334455244353565443262456744343467578487478747457785674998657698766957675569587698964765845684864574444667455745635532662234653645215513531 +323253541413342552245663443343675376543647876878458575556559588599988855669797967599547868547544658877584635537465644556623626662242233113253 +534434414252452225355655323757543566777567687485754846887585887865899558767759999578775754644485876644443336476447545444244442464511524114225 +142314213444164544544553446364555576745367646487857876847657447545869776658985875747755667746444686784736465576454773642446666332553312311413 +214112112255155462442242365344557773467374544846466557747448576848476667446464875867465456748844657557337475753345766254556234333342332325121 +244153353221226223323534344244636436774454367767748485587468775458546674855876677774876558575784878757743364775773736226355466624115153114123 +441232413554323455446346354233666374764645356675485547668775864485587868865755854785774464468786577433435436446443526356433456631223524422345 +143221413241342433544645523533734733466374434458654454486545647675776478466854875865487576784867635667346353555374563663532446535324324323523 +323131242415143225354352262324364766355466653533775477687544766487866677554777558458758787667587564446675477346743353245263356544252335112343 +421335544413315446545626342233335667476654573777557766545848667557886768867758486784545665457636443337735636345564533262244236355135432322131 +312244554415442331522246453334533637436756764474737765568656744654876674686547644877844868736646336544336346545536354445556333222132135454443 +321333454221512143442325262626664335573736534565367744484775854448556587586646887786475476467666656577334434366334646444445335553141543541233 +341133211142213555542466322563256567337574674733364756537584587757866448657755774474664364453535637443745353553456662464533532454235524451123 +421223541232113225443246365633626264757357575466645334557538454665677655677477786664433654335355636634647763565546635663546221155245241142144 +323422431143311254424526246335546255453335743347554637636473547445746785666646745773655646565733765464747364365366655543643333425255152231113 +433444113153233523221332663653526543537447366535353747643746373675543536536676575675536557447354456764537266436522466222351315532533422224334 +124222124142422434345123524266324224352356353365644745467673444747464463633433737347353333763357453336762446354252356335425421133544211144442 +412231321555333442353123332362425543424533553573666735637763454533745366765376746433756447475333356464464222432332345352341525223324314223324 +331312433213455231253313366665632226633556433475477753337363656373433773757536533656447774556433367326623645656523564215343224513551431132223 +224112234222241332225213354662554264323422253344474667333733456554564565467557537447534475756667355536646365532333536213215244225153322244412 +244113243235224213541532412425436353634323524524735645546553763765557473655733554645336476657756623642432424252542344521515245415325122342431 +333421331131543452331544433322665453665253334334233336445435345646447373734355537674545543737663646626335655635662215142322433242354342243112 +133313231314112552244245534355643622352352432342233334476466373555376336634767555645553454753662546264266543564554134444222253115423131221131 +131231412441413152554252155332345653224645365352224252676774544675574675674375465365754635336426223222236455655231354243412255433333333111224 +332324343332244323555523343522424636242334346443522643425664563557445657753663433433742554644552342556462255264545525242315522431444111241243 +242131114222434333535315551155432535643423333423326353532254255655746367555476375465645466663246524345534363325342524554524235232124123342242 +213443214424214122543235113333321125533542665643265452423232525225353624456522652323524352424663342645352244451451351414355352332211232222141 +331324322142214311244251224225412153666422233553532445352342364235225362266256253442662643454463636563552424333135251344313153142323433132323 +133324412321343111133453143214253353444663336233236323356323263332552632535244356555555246466334633636434214335153524233455513241242143233331 +112312232341121314233341331125215255233566334652552425242266535646254524434335664425346234266623244222224122425211534551415411323432223422431 +111221111132441212123422453234455112532453426625322352463453654552623534226653432234662654524636336532544221415524444135141242433424422341213 +132112142443434332213144334542214243531213325566463422625562222442645236252323332463366466355454556441122343223223544533444444111223232343312 +123132114141224134221142521153123435354553455566553265365362456544335254345555663536355522235262422254555111123424125513443122342334241423213 +222111222213331423242143325343351111342555413323153635663634225423236363264256253225335432323241313143325535154411221431341241322112213222333 +233133121221424112412441244521151213235233325252323226243435524643246242326265222442643346314111554114124523453333352131423344424422332112111 +313223121314322131323232111313433421514531352544111512123656226536435625655252522552646223335233154132134344324541142331432322433213231333223 +122323311123331314242221442331134445133211444341324335245235554244244535654565323631324113113435231541311524113422324131342433243442233332323 +131232121222413342213424423134225553425223335324412235455552131523111656231531242452533234455554145512342144111144431122223424423333132222113 +111322123121134213313111224233414112541332235125122353234451522411134512122545415145522212213525144152312255153143114113221323132422321321122 +212133123312121131311312443214311325443433324425455124152235512334253433334522144532143435341332543332153335423423341414241221311221213123233 diff --git a/day17/sample.txt b/day17/sample.txt new file mode 100644 index 0000000..f400d6e --- /dev/null +++ b/day17/sample.txt @@ -0,0 +1,13 @@ +2413432311323 +3215453535623 +3255245654254 +3446585845452 +4546657867536 +1438598798454 +4457876987766 +3637877979653 +4654967986887 +4564679986453 +1224686865563 +2546548887735 +4322674655533