Day 9 Checkin

+ Heckin covid booster shot...
+ Neat little queue implementation from this though
main
Joey Hines 2021-12-11 15:51:53 -07:00
parent 9427259bb4
commit b9bb36966a
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
7 changed files with 467 additions and 1 deletions

View File

@ -3,5 +3,5 @@ project(aoc_2021 C)
set(CMAKE_C_STANDARD 99)
add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h src/day_3.c src/day_4.c src/day_5.c src/day_6.c src/day_7.c src/day_8.c)
add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h src/day_3.c src/day_4.c src/day_5.c src/day_6.c src/day_7.c src/day_8.c src/day_9.c src/queue.c src/queue.h)
target_link_libraries(aoc_2021 m)

100
inputs/day_9.txt 100644
View File

@ -0,0 +1,100 @@
3235678976543234569109899875456987676387679999878953234987656895457998743212347892123999912987632489
2124899989932145698998789994329876545235567899768995349898546789346987654423656789339889899986541678
1012567897898756797987678989212985432103458987656789456789435691235998775634987897998776798775430567
2343489956789987976798899578901299654512578998545899567894326890449899896845898945899655987654321378
3455697645678999875679965467892398999323456789656798998952018921598799987896789235789544398765435459
4589789432567987764597654358679497878954578996987987999543459433697689899987892123498732129879646589
5678994321456976543989543236568986769895989654599876789765569555987578778999989014987653234998789678
6789875432349897659878943123459875458789996543298765678987678976899434569019878925998754345679898789
7894987654599798798768932012598766345678997692199854567898789987998923978998767899899987456789989899
9993298765987689988957899129679953237899989989987623456789898698987899899998756798789896588899878967
8989109876796569977845678998998767129949876979798544587899954569876786799987546989656799679999865456
7678912987965498765434567897899643298939965765679656798998768998765125899997639876545678996598754321
6567894599876329896545878976987654987898954354598787899999879129654014768998549865434568995439863210
5456789678997547989656789454598767976767976123459898976799989098643123456789998754323456789521994921
4347998799987656978967894323789879765656891012567999765789899987654354799999876543212368996542989899
3298949898998799867899965434678998654346789123458998654576789298966455678935987654345679987759878788
4989534987899987656789879765799998743235679254569876543445679019878766789124598775656799999898765667
9878921256999876546899989878987879865123789365678989521234695434989899893012349987878898989987654545
9967892345987655434989999989876565986239895478789998432345696549999989932123457898999947678998943234
8756793496796542323478999898785454987645996589893987643456789698999878943934578999986434567899932123
4345789989987641014567896797685323498656789699912397654567999987899867999895689598765323456997821012
3234699879876532123479965986543212349987899898901469895689109876987656789789791459853212349876543156
0134589965998743234569534598655304558998910967893456976789999965496544345678992398654101256997643245
1234567894569854375678976789766412367899321256789569987896789896986432234569989987653212397987656356
2547678923456975676989997999896567898996432345679678998935698789876531023789877999765323989998975457
3458789212689876989299989123987878979987593958798989899123987678987632234989765789876439879899876568
5569896345678987892109878994698989767998989899997898789239899568998544345678954567999949768799987679
6789965456789998943498767789899694545899878789986787679398798457899765459899543456798798656689998989
8992986767898969894989345699986543236789765699875656568997656356789876567989212378999659543567899992
9901299878987656789875234599997654697999873987654343459789543235899989678978934567998943212578923901
7899988989876545678984123678939765789876542198843212345678910124589998789567895979876432101458939892
6798767998783234569873234569219896899965431097652101234889321234678999893459976789987943242357898789
7987657789656123698764675678909987939878592198963213455695432348989876932347997895699894343456789678
9876546678943234999878786789698998921989989999984323567789543567898765421286789934598789658767893467
9965436567894549898989897896567899993998767899876544568897654578919976982345690129987678969878912345
9894325476789698787898999965456789989897656791987675689999879989102989876456789398776579899989423456
8763212345998789656797897654239999976798745690998786789899998996212399988767891987654456779997678967
7654323466789899645685679793198898765679659989879897896789987895475498999898910399743234568998789878
8876434578899998921434998989987679954549798878764998945698976796786987989979521249432123456789892989
9987545699998987890129897678976567893234987654353459936987895989899896878965434598543234587899921094
1099786789997876789298786567897789964645898983232345899876764878998795769896545697654355699999992123
2199899899896765678999543498999899875776789872101236789965743767896543456789676898768456789998989934
3987989998765434567895432345699912986989899654312345679874232456965432345678987999899567899987679895
9876378987654323456989541016989993997893998765459569797662101247894321234569998999999698919876567789
8765459876543212345678952345679889898912999877568678989543212348973210123459899989998789909865434697
9896567997654101456789763456798768789909899989679789978965343459765421234598768978999897898954323456
3987678998783216598899874567987654567899769998789898869897654789987532345987659767893956797895412345
2198789659854427689976985678995453478999878919899987656798765678998743456976745457891045976589101956
1019894345967838798765696789984322246789989434989998745689977899987654579875432345679134989678999897
2129943259878545897654987899876510135678998765678986534567898945998775689976543678989245698789989789
3498899198989656976543498998765421234569999878789198645778999439899976789989774567899876789999877676
9987788987698767897662349899896544346789789989891099876889789598789997898798765679943989899998764565
8976547896549878999743456789987675487895679797992987989997678987678989998549978789952199978999543634
7987436789432989987654589992398789598934589656789976599986569876569878987634599897893298767997432123
6798545697653498998765678990999897679545678934699954349875498765498767896545987956789987659876541012
5569658789894567899878799789897998798696799129789897598764349854323458997659876545678998434989752123
3498767999965678945989895699766569999989894298998789987543212976212356789998987676799129323499843234
2349879569876789234997964578957346988778995987688678999674309765301235789897698987899997434568974365
1234989435989892199875453689541239879569789876576567898764312943213376898767539398999876567899765486
0145895323499953987654312795432498765489678965435456999985429894524567999754321239899987678969876597
2256789212989879876543201976643987654344567894324345899876998789634789698765210156799998789943987678
3457894109876989987859349897656996432253456799210236789989897678945797549874321234567899999899998789
7568943298765799998998998799787897641012345678921234999896789567896965434989939545689949876788999899
8678954369934678999897687678998999832243658789762349896765689456789876629897898956893235965457999999
9889876459895799999765458567899998954354567899943498775674578967899997898766757897932101294356789998
2999987598789899987654323457899987895465678999899987654323789878998798987654646798943912989245679987
1989998997678989987543212346789896789878789989768999765454789999997669597543434789799899878968798766
9978999986569678998654343677898785698989899877657898986565678999976543496532323597698798967899999854
8867898765474567898767654578998674567899998765434587897878989989898932989421014976597677657999878975
7656569876343569999898767689776543456789679879523456789989999879789891978993429897989556547689969989
6547434987212345899999878797654312367996567997612346789599899965656789767989598789876443234567898795
5432129998323456789785989896543201498923489876324457893456789654345698654678987698654321015798997654
7321098999974567897674599987654432349314567965435678932969898769296987563567897549976572123456789543
5432987898765678976553678998865543458909689976645679659899999898989995432456789432987654234569899654
7649876549989989865442345679976754567898990987876789798789999987678986321568897643498765365878978985
8998765430199998754321256989987866678987891298987899898698789876569854310978998756789876476989767976
9987654321248999987532347899998978989876789459998923999569656965498765423989989867899989588995456897
3298765442357897598675456999899989896765678999879212679678949854349876534599878989989997678985345789
4109877675456789459986587899788998765634789989765424598789799765456988545679767495678998789873276789
5298988786767894367987898997697989654325699978996876969897678976567997657889654323567899898762177899
6987699887878985499098999876586478999438798767889989853934569989698998768999767015678976999654567977
7996567998989876989139798965432367878949899848779998762123493194989879879999899524569345999965678956
9875456789991989878945697654331456567899995437567899643434789012978767989989998434679999889876789545
3984345678910198867896989963210123458999876523458998755645678999767856899978987678798788768989897632
1296456789321997457997979894523236569996543212568979877876799987653345678969998989989678456896999743
3989587898459876346789868789754347678987954323678965989987894699542126789458999899876543267895989654
9878999996598754265697754699965498789599875434567894395998913398653234892347898757995432126789878965
8767898789987662154986543659876789894323987565678943214879901298764345891276789549876574235678969897
8656797678996543012965432348997898965634598986789432102367892989865456789345678932997865348789556798
6545689589898784329876541557889967996789679797899543223456999879876869995457799321099876789894346789
5432123497659895839865432345678959889898797698998674334567896567987878976569899932989987899921256999
6563234987643976749877565456789545678999896549019775476878923456798989987878979893978598978932349898
7854599865532397956988987667896734567899975432129896587889212769899690198989458789867439569899998767
8965987654321298967899998778954323479989876543599987898992101278943591989693245698754523498788897656
9876998765434349879998999899655212345678987655989998999653234568932989876562134987643212989697789643
9987899876545656989587899976542103456789198779878999998765356789549979989431023987654109878576679932
9898943999856767895456789989653214567891019889767899979976487899998768999545124598543298765434567893
9769432349767878974367895397654323456789326998752398765987599959897656598657234987654998654323478954
8754321239879999865458943239765464567895445987631259854398910145789543498765345698769876543212356799
9653210123989439876789432129896875689976556796532349876459321234895432349877456789878987643101234678

View File

@ -9,5 +9,6 @@ int day_5();
int day_6();
int day_7();
int day_8();
int day_9();
#endif //AOC_2021_DAY_H

288
src/day_9.c 100644
View File

@ -0,0 +1,288 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "puzzle_input.h"
#include "day.h"
#include "queue.h"
#define MAX_WIDTH 100
#define QUEUE_SIZE 500
typedef struct {
int ii;
int jj;
} point_t;
typedef struct {
int8_t map_data[MAX_WIDTH*MAX_WIDTH];
uint8_t basin[MAX_WIDTH*MAX_WIDTH];
uint8_t basin_count;
int16_t line_width;
} map_data_t;
map_data_t map_data_g = {};
parse_ret_t parse_map_line(char * buffer, void * data, uint16_t index) {
map_data_t * map_data = (map_data_t *)data;
int8_t * map_line = map_data->map_data + index * MAX_WIDTH;
int16_t line_ndx = 0;
while (buffer[line_ndx] != '\0') {
map_line[line_ndx] = buffer[line_ndx] - '0';
line_ndx++;
}
map_data->line_width = line_ndx;
return PARSER_OK;
}
uint8_t get_map_data(const uint8_t * data, int ii, int jj, uint16_t i_len, uint16_t j_len) {
if ((ii >= i_len) || (ii < 0) || (jj >= j_len) || (jj < 0)) {
return UINT8_MAX;
}
else {
return *(data + jj + ii * MAX_WIDTH);
}
}
void set_map_data(uint8_t * data, int ii, int jj, uint16_t i_len, uint16_t j_len, uint8_t val) {
if ((ii >= i_len) || (ii < 0) || (jj >= j_len) || (jj < 0)) {
return;
}
else {
*(data + jj + ii * MAX_WIDTH) = val;
}
}
int8_t is_min(uint8_t * data, int ii, int jj, uint16_t i_len, uint16_t j_len) {
uint8_t middle = get_map_data(data, ii, jj, i_len, j_len);
uint8_t up = get_map_data(data, ii-1, jj, i_len, j_len);
uint8_t down = get_map_data(data, ii+1, jj, i_len, j_len);
uint8_t left = get_map_data(data, ii, jj-1, i_len, j_len);
uint8_t right = get_map_data(data, ii, jj+1, i_len, j_len);
if ((middle < up) && (middle < down) && (middle < left) && (middle < right)) {
return 1;
}
else {
return 0;
}
}
static void print_map(uint8_t * map, uint16_t max_i, uint16_t max_j) {
for (int16_t ii = 0; (int16_t)ii < max_i; ii++) {
for (int16_t jj = 0; (int16_t) jj < max_j; jj++) {
printf("%u", get_map_data(map, ii, jj, max_i, max_j));
}
printf("\n");
}
}
static void part_1(uint16_t len) {
uint16_t risk_sum = 0;
uint8_t basin_count = 1;
for (int ii = 0; ii < len; ii++) {
for (int jj = 0; jj < map_data_g.line_width; jj++) {
if (is_min((uint8_t *)map_data_g.map_data, ii, jj, len, map_data_g.line_width)) {
risk_sum += get_map_data((uint8_t *) map_data_g.map_data, ii, jj, len, map_data_g.line_width) + 1;
set_map_data(map_data_g.basin, ii, jj, len, map_data_g.line_width, basin_count);
basin_count++;
}
}
}
map_data_g.basin_count = basin_count;
printf("PART 1: Low point risk sum is: %d\n", risk_sum);
}
#define WALL 9
static queue_ret_t queue_point(queue_t *queue, int pos_i, int pos_j, uint16_t max_i, uint16_t max_j) {
point_t point = {0};
if (get_map_data(map_data_g.basin, pos_i, pos_j, max_i, max_j) > 0) {
return QUEUE_OK;
}
if (get_map_data((uint8_t *)map_data_g.map_data, pos_i, pos_j, max_i, max_j) == WALL) {
return QUEUE_OK;
}
point.ii = pos_i;
point.jj = pos_j;
if (point.ii > max_i || point.jj > max_j) {
printf("Invalid point attempted to be pushed onto queue\n");
return QUEUE_DATA_INVALID;
}
return push(queue, &point);
}
point_t q_data_g[QUEUE_SIZE] = {0};
static int flood_fill( int pos_i, int pos_j, uint16_t max_i, uint16_t max_j, uint8_t basin_count, uint8_t * basin_counts)
{
queue_t queue = {0};
point_t point = {0};
queue_ret_t res;
init(&queue, q_data_g, QUEUE_SIZE, sizeof(point_t));
point.ii = pos_i;
point.jj = pos_j;
res = push(&queue, &point);
basin_counts[basin_count - 1] = 1;
if (res != QUEUE_OK) {
printf("Unable to insert element: %d", res);
return -1;
}
while (queue.queued_elements > 0) {
res = pop(&queue, &point);
if (res != QUEUE_OK) {
printf("Unable to pop element: %d", res);
return -1;
}
if (point.ii > max_i || point.jj > max_j) {
printf("Invalid point popped from queue\n");
return -1;
}
uint8_t val = get_map_data(map_data_g.basin, point.ii, point.jj, max_i, max_j);
if (val == 0) {
set_map_data(map_data_g.basin, point.ii, point.jj, max_i, max_j, basin_count);
basin_counts[basin_count - 1]++;
}
res = queue_point(&queue, point.ii + 1, point.jj, max_i, max_j);
if (res != QUEUE_OK) {
printf("Unable to push element: %d\n", res);
return -1;
}
res = queue_point(&queue, point.ii, point.jj + 1, max_i, max_j);
if (res != QUEUE_OK) {
printf("Unable to push element: %d\n", res);
return -1;
}
res = queue_point(&queue, point.ii -1, point.jj, max_i, max_j);
if (res != QUEUE_OK) {
printf("Unable to push element: %d\n", res);
return -1;
}
res = queue_point(&queue, point.ii, point.jj - 1, max_i, max_j);
if (res != QUEUE_OK) {
printf("Unable to push element: %d\n", res);
return -1;
}
//printf("%d: (%d, %d)\n", basin_count, point.ii, point.jj);
//print_map(map_data_g.basin, max_i, max_j);
//printf("\n");
}
return 0;
}
static int find_basin(uint8_t basin, uint16_t max_i, uint16_t max_j, int16_t *ret_ii, int16_t *ret_jj) {
int found = 0;
int16_t ii;
int16_t jj;
for (ii = 0; (int16_t)ii < max_i; ii++) {
for (jj= 0; (int16_t)jj < max_j; jj++) {
if (get_map_data(map_data_g.basin, ii, jj, max_i, max_j) == basin) {
found = 1;
break;
}
}
if (found) {
break;
}
}
if (found) {
*ret_ii = ii;
*ret_jj = jj;
return 1;
}
else {
return 0;
}
}
static int uin8t_cmp(const void * a, const void * b) {
return ( *(uint8_t *)a - *(uint8_t *)b );
}
#define BASIN_COUNTS 250
uint8_t basin_counts[BASIN_COUNTS] = {0};
static void part_2(uint16_t len) {
uint16_t max_i = len;
uint16_t max_j = map_data_g.line_width;
uint32_t basin_size_multiplied;
uint8_t basin_count = map_data_g.basin_count;
int16_t basin_ii = 0;
int16_t basin_jj = 0;
if (basin_count - 1 > BASIN_COUNTS) {
printf("Too many basin counts! Need: %u\n", basin_count);
return;
}
for (uint8_t basin_ndx = 1; basin_ndx < map_data_g.basin_count; basin_ndx++) {
if (find_basin(basin_ndx, max_i, max_j, &basin_ii, &basin_jj)) {
if (flood_fill(basin_ii, basin_jj, max_i, max_j, basin_ndx, basin_counts) < 0) {
printf("Unable to process basin: %d\n", basin_ndx);
return;
}
}
else {
printf("Basin %u, not found!\n", basin_ndx);
return;
}
}
qsort(basin_counts, basin_count-1, sizeof(uint8_t), uin8t_cmp);
basin_size_multiplied = basin_counts[basin_count-2] * basin_counts[basin_count - 3] * basin_counts[basin_count - 4];
printf("PART 2: Multiplying the size of the 3 largest basins gives: %d\n", basin_size_multiplied);
}
int day_9() {
parse_ret_t res;
uint16_t len;
res = read_input_single_line("../inputs/day_9.txt", (void *)&map_data_g, MAX_WIDTH, parse_map_line, &len);
if (res != PARSER_OK) {
printf("Failed to parse input: %d\n", res);
return -1;
}
part_1(len);
part_2(len);
return 0;
}

View File

@ -40,6 +40,9 @@ int main(int argc, char * argv[]) {
case 8:
day_8();
break;
case 9:
day_9();
break;
default:
printf("Invalid day ding dong!\n");
return -2;

46
src/queue.c 100644
View File

@ -0,0 +1,46 @@
#include "string.h"
#include "queue.h"
static size_t next_element(size_t index, size_t max_len) {
return (index + 1) % max_len;
}
queue_ret_t init(queue_t * queue, void * data, size_t max_data_size, size_t element_size) {
queue->data = data;
queue->max_data_size = max_data_size;
queue->element_size = element_size;
queue->queued_elements = 0;
queue->pop_ndx = 0;
queue->push_ndx = 0;
return QUEUE_OK;
}
queue_ret_t push(queue_t * queue, void * element) {
if (queue->queued_elements >= queue->max_data_size) {
return QUEUE_FULL;
}
memcpy(queue->data + (queue->push_ndx*queue->element_size), element, queue->element_size);
queue->push_ndx = next_element(queue->push_ndx, queue->max_data_size);
queue->queued_elements++;
return QUEUE_OK;
}
queue_ret_t pop(queue_t * queue, void * store_to) {
if (queue->queued_elements == 0) {
return QUEUE_EMPTY;
}
memcpy(store_to, queue->data + (queue->pop_ndx*queue->element_size), queue->element_size);
queue->pop_ndx = next_element(queue->pop_ndx, queue->max_data_size);
queue->queued_elements--;
return QUEUE_OK;
}

28
src/queue.h 100644
View File

@ -0,0 +1,28 @@
#ifndef AOC_2021_QUEUE_H
#define AOC_2021_QUEUE_H
#include <stdint.h>
#include <stddef.h>
typedef enum {
QUEUE_OK,
QUEUE_FULL = -1,
QUEUE_EMPTY = -1,
QUEUE_DATA_INVALID = -1,
} queue_ret_t;
typedef struct {
void * data;
size_t push_ndx;
size_t pop_ndx;
size_t queued_elements;
size_t max_data_size;
size_t element_size;
} queue_t;
queue_ret_t init(queue_t * queue, void * data, size_t max_data_size, size_t element_size);
queue_ret_t push(queue_t * queue, void * element);
queue_ret_t pop(queue_t * queue, void * store_to);
#endif //AOC_2021_QUEUE_H