day 9 part two inefficient
authorMart Lubbers <mart@martlubbers.net>
Thu, 9 Dec 2021 07:00:02 +0000 (08:00 +0100)
committerMart Lubbers <mart@martlubbers.net>
Thu, 9 Dec 2021 07:00:08 +0000 (08:00 +0100)
09b.c [new file with mode: 0644]
Makefile

diff --git a/09b.c b/09b.c
new file mode 100644 (file)
index 0000000..a332dd4
--- /dev/null
+++ b/09b.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <uthash.h>
+
+struct point { int x; int y; };
+struct entry { struct point key; UT_hash_handle hh; };
+
+#define push(x, y) {\
+       if ((x) >= 1 && (y) >= 1 && (x) <= maxx+1 && (y) <= maxy+1)\
+               stack[sp++] = (struct point){x, y};\
+       }
+
+int basin(int grid[102][102], int maxx, int maxy, int x, int y)
+{
+       printf("calculate basin for: %d,%d -- ", x, y);
+       struct point stack[1000];
+       memset(stack, 0, sizeof stack);
+       struct entry *visited = NULL;
+
+       int sp = 0;
+       int size = 0;
+       stack[sp++] = (struct point){.x=x, .y=y};
+
+       struct point p;
+       struct entry *e;
+       memset(&p, 0, sizeof p);
+       while(--sp >= 0) {
+               p = stack[sp];
+               HASH_FIND(hh, visited, &p, sizeof(struct point), e);
+               if (e)
+                       continue;
+
+               e = calloc(1, sizeof(struct entry));
+               e->key = p;
+               HASH_ADD(hh, visited, key, sizeof(struct point), e);
+
+               if (grid[p.y][p.x] == 9)
+                       continue;
+               size++;
+
+               push(p.x+1, p.y);
+               push(p.x-1, p.y);
+               push(p.x, p.y+1);
+               push(p.x, p.y-1);
+       }
+       printf(" %d\n", size);
+       return size;
+}
+
+void insert(int tl[3], int s)
+{
+       if (s > tl[0] && s <= tl[1])
+               tl[0] = s;
+       if (s > tl[1] && s <= tl[2]) {
+               tl[0] = tl[1];
+               tl[1] = s;
+       }
+       if (s > tl[2]) {
+               tl[0] = tl[1];
+               tl[1] = tl[2];
+               tl[2] = s;
+       }
+}
+
+int main()
+{
+       int grid[102][102];
+       for (int i = 0; i<102; i++)
+               for (int j = 0; j<102; j++)
+                       grid[i][j] = 9;
+       int x = 1, y = 1;
+       int maxx = 1;
+       int c = 0;
+       while((c = getchar()) != EOF) {
+               if (c == '\n') {
+                       y++;
+                       x = 1;
+               } else {
+                       maxx = x > maxx ? x : maxx;
+                       grid[y][x++] = c-'0';
+               }
+       }
+
+       int tl[3] = {0};
+       for (int cy = 1; cy<y; cy++)
+               for (int cx = 1; cx<maxx+1; cx++)
+                       if (grid[cy][cx] < grid[cy+1][cx] &&
+                                       grid[cy][cx] < grid[cy-1][cx] &&
+                                       grid[cy][cx] < grid[cy][cx+1] &&
+                                       grid[cy][cx] < grid[cy][cx-1])
+                               insert(tl, basin(grid, maxx, y, cx, cy));
+       printf("%d %d %d\n", tl[0], tl[1], tl[2]);
+       printf("%d\n", tl[0]*tl[1]*tl[2]);
+}
index 68c8c53..c1bccfe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CFLAGS:=-Wall -Wextra -O3
 LFLAGS:=-f
 
-BINARIES:=$(foreach num,$(shell seq -f '%02.0f' 1 8),$(num)a $(num)b)
+BINARIES:=$(foreach num,$(shell seq -f '%02.0f' 1 9),$(num)a $(num)b)
 
 all: $(BINARIES)