From 008833b0df723c000e0b8917cfb444898472422f Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Thu, 9 Dec 2021 18:25:08 +0100 Subject: [PATCH] Add solution for 2021 day 09 --- 2021/README.md | 3 +- 2021/day-09/Justfile | 6 ++ 2021/day-09/common.c | 84 ++++++++++++++++++++++++++++ 2021/day-09/common.h | 15 +++++ 2021/day-09/inputs/puzzle.txt | 100 ++++++++++++++++++++++++++++++++++ 2021/day-09/inputs/sample.txt | 5 ++ 2021/day-09/part_one.c | 22 ++++++++ 2021/day-09/part_two.c | 70 ++++++++++++++++++++++++ README.md | 2 +- 9 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 2021/day-09/Justfile create mode 100644 2021/day-09/common.c create mode 100644 2021/day-09/common.h create mode 100644 2021/day-09/inputs/puzzle.txt create mode 100644 2021/day-09/inputs/sample.txt create mode 100644 2021/day-09/part_one.c create mode 100644 2021/day-09/part_two.c diff --git a/2021/README.md b/2021/README.md index 8bab0ec..2c0500c 100644 --- a/2021/README.md +++ b/2021/README.md @@ -12,7 +12,7 @@ | 06 | ✓ | ✓ | [Inko] | | 07 | ✓ | ✓ | [Swift] | | 08 | ✓ | | [C#] | -| 09 | | | | +| 09 | ✓ | ✓ | [C] | | 10 | | | | | 11 | | | | | 12 | | | | @@ -44,3 +44,4 @@ [inko]: https://inko-lang.org [swift]: https://www.swift.org [c#]: https://docs.microsoft.com/en-us/dotnet/csharp/ +[c]: http://www.open-std.org/jtc1/sc22/wg14 diff --git a/2021/day-09/Justfile b/2021/day-09/Justfile new file mode 100644 index 0000000..511a4fd --- /dev/null +++ b/2021/day-09/Justfile @@ -0,0 +1,6 @@ +@part PART INPUT_FILE="inputs/puzzle.txt": + gcc -std=c17 -Werror -Wextra -o part_{{PART}} common.c part_{{PART}}.c + ./part_{{PART}} {{INPUT_FILE}} + +clean: + rm part_one part_two diff --git a/2021/day-09/common.c b/2021/day-09/common.c new file mode 100644 index 0000000..b26eada --- /dev/null +++ b/2021/day-09/common.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include "common.h" + +int MAP_WIDTH = 0; +int MAP_HEIGHT = 0; +int MAP[100][100]; + +void read_file(char* path) { + FILE* fp = fopen(path, "r"); + if (fp == NULL) exit(EXIT_FAILURE); + + int y = 0; + int x = 0; + + while (true) { + char chr = fgetc(fp); + + if (chr == EOF) break; + + if (chr == '\n') { + y++; + + if (MAP_WIDTH == 0) MAP_WIDTH = x; + x = 0; + + continue; + } + + MAP[y][x] = chr - 48; + + assert(MAP[x][y] < 10 && MAP[x][y] >= 0); + + x++; + } + + MAP_HEIGHT = y; +} + +void print_map(int map[100][100]) { + for (int y = 0; y < MAP_HEIGHT; y++) { + printf("%d: ", y); + for (int x = 0; x < MAP_WIDTH; x++) { + printf("%d ", map[y][x]); + } + printf("\n"); + } +} + +int with_low_point(result_fn fn) { + int result = 0; + + for (int y = 0; y < MAP_HEIGHT; y++) { + for (int x = 0; x < MAP_WIDTH; x++) { + int cur = MAP[y][x]; + bool is_low_point = true; + + if (y > 0) { + is_low_point = is_low_point && MAP[y - 1][x] > cur; + } + + if (y < MAP_HEIGHT - 1) { + is_low_point = is_low_point && MAP[y + 1][x] > cur; + } + + if (x > 0) { + is_low_point = is_low_point && MAP[y][x - 1] > cur; + } + + if (x < MAP_WIDTH - 1) { + is_low_point = is_low_point && MAP[y][x + 1] > cur; + } + + if (is_low_point) { + result += fn(x, y, cur); + } + + } + } + + return result; +} diff --git a/2021/day-09/common.h b/2021/day-09/common.h new file mode 100644 index 0000000..f12a72a --- /dev/null +++ b/2021/day-09/common.h @@ -0,0 +1,15 @@ +#pragma once + +extern int MAP_WIDTH; +extern int MAP_HEIGHT; +extern int MAP[100][100]; + +typedef int (*result_fn)(int, int, int); + +typedef int (*collect_fn)(int, int); + +void read_file(char* path); + +void print_map(); + +int with_low_point(result_fn fn); diff --git a/2021/day-09/inputs/puzzle.txt b/2021/day-09/inputs/puzzle.txt new file mode 100644 index 0000000..177132a --- /dev/null +++ b/2021/day-09/inputs/puzzle.txt @@ -0,0 +1,100 @@ +7988912498775677899976544676789212346793989896459876543679986778999879896543234965421014567898756757 +6777924987654686789987632345678954569894978789398765432456895569998965799765459876592923458987541246 +5456896987823545569876543566789995778999765678979986544578923459987894678976599999989899567987620134 +4345699876710123499987994677897989989998754567954397755989013498765953566989989998766678978998321345 +2235689765324648578999789989976768999987643678964219876789129579654212345898767987654568989876543459 +1024569879534787689998689898765656789643212567895324989899298998732101256789959876552456898998765668 +2137978998755698798987596789843245698775103456789765693998987899899912487899849865431545587899878979 +4346899659876899987656434695432167789874312569899876964987876789987894568989723987420123456789999989 +5657896542987899998543326479943278993965643678956989899876755799876795779876545696541344678996989999 +6788976321299967987632101267895389012396864989643498798765434598765689889987656987655456789865467899 +7899985410123459998843212348996498923987878995432987659878321987654898992398997898769767897654357898 +9979876653237598999954423456789987899798989789544598434987210398765987821039998929879878986543234986 +5668987954546987899985534668899976587679998678995679645696531239878976532129999212989999775444129875 +3456799875659876899876645789989897434599902456789798956987642449989876545298789423495497654321012954 +4677999996767985689987766899876795323989893487899987897898743658999988656987679934984398767443199743 +5789989987979876789299898999975689919979789678999876789909869767919899767987567899876209976564987621 +6899979999989998992199979898754599898667699789989545678919998978909765979876456789998212987676798510 +7998769897598679999988466789876698786544578999875533569398987899998954599765347899989323598787987421 +9878656789434567898976365679988987695433489998764321239497676899987895679874267999879946679899876532 +7765347996545698987654254598999976543212568969976443998974545798946796799842157898768899789944987543 +6673234789956799798762123767899989874323678957988769887563234587897897987652046989857678996432498667 +5410123567897895699543013459989998765435989348999898765432123456789979876543135678943589789321298798 +4321244789998934987676434678979999896546990245986987654321096567898765997765647899432423578932349899 +6532345998999326799898945889768799987667899366965398965439989778987754598978956895321012456944569935 +7643496987894315698949767999654678998789978979893219878998878999996432989989767976532123467895678923 +8789989996789504987656989798773239999993467898799101989997656789987599778997978976546234678987799212 +9899879985679423498767894659982099987812456987678919999986547892198987666896989987664345799999989903 +2998769864568945589978953545894989876543667898789998899876535989019896545799993499875456896789967894 +4987654953456896678989542123799876997864789999898976789987323569198765434878932346987667985699856789 +9876543212349789789199965345698965698965678999987965679893210378999767323567891234598778974598768999 +9987764101234678991019896459987654569876789788965754598765321289898653210379990123479899653459879998 +9999853213345789432199789767899932157989893567954323459898535696799864321245689294567939778567989986 +7998765435456898953987678998999893249897902467893212699987679895999978442467890989878949889679895354 +5679979545567987894596568989998789998776212379989301989699789924889989766579931979989999998798754213 +4343498758799876789987879878987656889654323569979999876529893212679999878689999868999989989899842101 +3232349767987915679999998769898645778965434598765789765436989101567998989789987657899878978921943213 +4101234989875423467898764546789434569197545698764678976545678912345897694999996645678967967939876454 +3213445999995434898998753437678928789019678989912467998657799424556789543239865434567956756899989876 +4324557899976545699999542123569219678998789974326579349779897435678897654345986323478943445689391987 +5436898967987676789987541012789901567899898765987891298989986545679998767459875212357921534789210198 +6545989978999887899987432124567892457892949976798932397997897656792129879679954323569210123494321249 +7679978989989998999876573336678953767901234987899793976896999877891099989898765654678921234989934956 +9798867899978969899989876457789764889212346799978689875699899998932989999999878965699632349877899897 +8987656989767456789593987567999875999329987989767598986789678999545978929876989977896543659766789798 +7757645779854345995432097678999989998998998976553467987894579899999769019865699988987654599854347689 +6545434567943257896543998789998999997987899965432438998913689789887658998764569999998765987843235568 +7432123688954346789669899899876899875676789876510129999524598598766546789543488957899899876452123467 +6543334799765457899998789998965698763245678987542247896434597439854235699854567899989943995321036799 +8754455999879568999887678987654569654356789876543346789675986429863146798765679998768994987432145678 +9965667894998678998756569996543479875456799987654567898796975310954345679897789987656789876544287789 +9987878943459989989545467897695689976569898798967679969998976429865766789999898996545789998955398999 +8798989895698799879721256789789896987678999659798789954599986539876988896789956789434589219765456789 +7659395689987698765430145698999965499899998734569898893989697656987899965689345678923478909896667998 +8543234569876549876981234567998977345998989123456986789876569767898998764578956789014567896998978957 +7654109678989656999876545699997894239897878935769975678925459899999987653469987892123478945789989546 +8869298999598767975987656789876789129776767949898764599212399956798998532357898943234569435678998734 +9998987989439899864398967898985789298545456896999753479901989532987987620578999769357678924579987645 +9987675978921999872109879967454599987434345965987654567899878993986598321234899998998799314699698656 +8765423567890199943223989954323459886521239894598965679998756789765459543466789897999894323987579868 +9754313458921987654434599893012398765430456789969988789893344598764349874678994786898965545999456989 +8742102567899899876546999762124679965321345899856799899672223579653298765679563535567976659898968999 +7653212348988789997999899854345789986732456789735678987521012699862139979899432123459999798767899109 +9854323459976578989789789987467896597653468898623489996432359985989345989987541014598998987656789398 +8765434899865459876566678976578999439796589997544568987546598874695456794598672123997987897545678967 +9876646789654321995434589987689997929897699989659678998669986763498768893359987439876876989439999856 +9997797899995210987657991099999896899998789678998799879878985452349879921267896598965385678998779645 +8998998999889921298968993298899765689999894568999893656989876321245989542456987987854234567987656434 +7659789988677892989879589987698954569986953467897932347999988454346797656767898976542123457897542126 +6545679876566799878989679878567895698765432399976431349899876567857899777879979987643235578998631018 +5432398765455989766899789767458999789876591988997653498789998798767979888989765698954545678997632346 +4321298774344678954668998654345698999987989876989768987678999899878965999698913999875659789986543457 +9543987685123789543459876563234567899899878765878979876556789934989893234567899878986789998997654667 +7667898543234696432345998434145678998798765674567897687445789123499799013498998765497891237998876789 +8799999657345679321236987621012789987679974553456799543234591013987678934989987654398910956899997895 +9988998765456789910449998732334567897598763212345698987445989125696568945978999873219999899943459923 +9867899876587997892348999644645688935459754323457987896589978934987479899869345965423988798991292101 +9756799987998966789556798767856799322398767434598996987679867895699356798758996987554977657989989212 +6845789998989655678967899878997899901459878875699885998798756789898769997646889998699866545976878943 +5434677999876543489978978989298998892347989986988674899999348898989898785425677999987654439895657895 +1012346897998674568989569592129556789456796799876532789993201987878997654304556789875432129754345699 +2129578956798785679392398431012345997579985689965321679987512986767898743212347999986573098975212688 +3298989245679898789101987549124459899998764569879433598998434975859999856423467898987654987654303567 +4987892134598989898924597698939598768899878698998944567899549864348989998644568997898865699965212456 +9876989012987665967896698987898698656789989987897956778989997955287678999757689456789976799864343567 +9765678924598574456998799756789798638998799986986899889679876543124567898768794347893299899875456878 +8954689634999432347899898945899909545999698765455798997598765432013478939989894236789345976996567989 +7653499549898921258789987834978919696789569654344567996439896563123599023598943145678967895987698999 +6532368998767892345678996521467898989893498743243456789545987879234789146987654235989879954599899549 +8743456789759789557899865410356987678954987652102567898756798995365693234598964347899989893434999698 +7656587997645678969998765321269876569865698843213678929877899876876895397699895456789398732129888967 +8767899987657899878979765433345988778978789956523799545988954987999976989988796568890297643498767456 +9878999898767999989568986544578999889989898765434999796999313399987987978979689979991298764989854321 +4989398799879889995467897655678933991296929876645678989876501239876899867464578899989999879878965452 +5794219654989678976345898766989321390965410989876989667988213398995679954343456789678878998765987674 +7984398763494567898656789879995490989894321297987899545599754977894569865212367896564767999954598895 +9875459982123456789878895998976989879789432996798978923498769865323498765423498998323556789863989976 +6996569971012358997999934987899876565678949875439569212459879973212549876434569657212346999872975498 +4987698763123457895432129896798765484579898764323459103456998764301234996545879543101867896989854329 +3498987654235767996321098765789994323456789871012348914577899878412346987656989754563778965498754312 +2109998767346878976543459434679876107689896532434567899789913987523457899767999986774689764349962101 diff --git a/2021/day-09/inputs/sample.txt b/2021/day-09/inputs/sample.txt new file mode 100644 index 0000000..6dee4a4 --- /dev/null +++ b/2021/day-09/inputs/sample.txt @@ -0,0 +1,5 @@ +2199943210 +3987894921 +9856789892 +8767896789 +9899965678 diff --git a/2021/day-09/part_one.c b/2021/day-09/part_one.c new file mode 100644 index 0000000..aaf98bb --- /dev/null +++ b/2021/day-09/part_one.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include "common.h" + +int calculate_risk_level(int x, int y, int cur) { + return cur + 1; +} + +int main(int argc, char *argv[]) { + if (argc != 2) return EXIT_FAILURE; + + char* path = argv[1]; + + read_file(path); + + int result = with_low_point(calculate_risk_level); + + printf("%d\n", result); + + return EXIT_SUCCESS; +} diff --git a/2021/day-09/part_two.c b/2021/day-09/part_two.c new file mode 100644 index 0000000..f1cbdb7 --- /dev/null +++ b/2021/day-09/part_two.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "common.h" + +#define BASIN_COUNT 1000 +int BASIN_IDX = 0; +int BASINS[BASIN_COUNT] = { 0 }; + +int scout_basin(int x, int y, int marked[100][100]) { + marked[y][x] = 1; + int count = 1; + + if (y > 0 && MAP[y - 1][x] != 9 && !marked[y - 1][x]) { + count += scout_basin(x, y - 1, marked); + } + + if (y < MAP_HEIGHT - 1 && MAP[y + 1][x] != 9 && !marked[y + 1][x]) { + count += scout_basin(x, y + 1, marked); + } + + if (x > 0 && MAP[y][x - 1] != 9 && !marked[y][x - 1]) { + count += scout_basin(x - 1, y, marked); + } + + if (x < MAP_WIDTH - 1 && MAP[y][x + 1] != 9 && !marked[y][x + 1]) { + count += scout_basin(x + 1, y, marked); + } + + return count; +} + +int calculate_basin_size(int x, int y, int cur) { + int marked[100][100] = { 0 }; + int basin_size = scout_basin(x, y, marked); + BASINS[BASIN_IDX] = basin_size; + BASIN_IDX++; + return 0; +} + +int cmp_basin_size(const void* a, const void* b) { + if (*(int*) a < *(int*) b) { + return 1; + } else if (*(int*) a > *(int*) b) { + return -1; + } + + return 0; +} + +int main(int argc, char* argv[]) { + if (argc != 2) return EXIT_FAILURE; + + char* path = argv[1]; + + read_file(path); + + with_low_point(calculate_basin_size); + + qsort(&BASINS, BASIN_COUNT, sizeof(int), cmp_basin_size); + + int result = 1; + for (int i = 0; i < 3; i++) { + result *= BASINS[i]; + } + + printf("%d\n", result); + + return EXIT_SUCCESS; +} diff --git a/README.md b/README.md index fc488ff..31b39f2 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,4 @@ - [2018](2018/README.md) (0% completed) - [2019](2019/README.md) (0% completed) - [2020](2020/README.md) (16% completed) -- [2021](2021/README.md) (30% completed) +- [2021](2021/README.md) (34% completed)