summaryrefslogtreecommitdiff
path: root/14.c
diff options
context:
space:
mode:
authorAdam Spragg <adam@spra.gg>2022-12-14 19:05:45 +0000
committerAdam Spragg <adam@spra.gg>2022-12-14 19:05:45 +0000
commitfc9e74ea0e6388f2544e99e7abc9f14bede025d1 (patch)
tree478b875a5a9ff56c65fe88bf71ad467fca64d1ee /14.c
parent300454fd7c51de7383f7cf816938204fa20d79fe (diff)
Solve puzzle 14 part 2
Diffstat (limited to '14.c')
-rw-r--r--14.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/14.c b/14.c
index 4a51c76..d100253 100644
--- a/14.c
+++ b/14.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#define arrlen(x) (sizeof(x)/sizeof((x)[0]))
@@ -80,14 +81,26 @@ cave_dump(char * cave, int xmin, int xmax, int ymax)
int
-main()
+main(int argc, char ** argv)
{
+ int part = 1;
regex_t coords;
char buf[BUFSIZ];
char * cave = NULL;
int xmin = 500, xmax = 500, ymax = 0;
int grain;
+ while ((grain = getopt(argc, argv, "p:")) != -1) {
+ switch (grain) {
+ case 'p':
+ part = atoi(optarg);
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
if (regcomp(&coords, "( -> )?([[:digit:]]+),([[:digit:]]+)", REG_EXTENDED) != 0) {
fprintf(stderr, "Bad regex\n");
return -1;
@@ -162,6 +175,17 @@ main()
}
}
+ if (part == 2) {
+ // Lowest floor is 2 below original max, of infinite width. Only
+ // need to keep track of one level of sand below
+ if (cave_resize(&cave, &xmin, &xmax, &ymax, xmin, ymax + 1) != 0) {
+ fprintf(stderr, "Unable to resize cave for %d,%d\n", xmin, xmax + 1);
+ free(cave);
+ regfree(&coords);
+ return -1;
+ }
+ }
+
#if 0
cave_dump(cave, xmin, xmax, ymax);
#endif
@@ -177,8 +201,9 @@ main()
break;
// Don't go to "y <= ymax" here. If the grain gets to ymax, it's
- // falling off the bottom as there's nothing below it. And an
- // attempt to look at the row below isn't valid.
+ // at the bottom and either falling off as there's nothing below
+ // it, or coming to rest on the infinite floor. And an attempt
+ // to look at the row below isn't valid.
for (y = 0; y < ymax; ++y) {
if (cave[cavepos(xmin, xmax, ymax, x, y + 1)] == '\0') {
// Do nothing, drop down one
@@ -187,7 +212,6 @@ main()
else if (x == xmin) {
// Fall off left edge
--x;
- break;
}
else if (cave[cavepos(xmin, xmax, ymax, x - 1, y + 1)] == '\0') {
// Drop down and left
@@ -196,7 +220,6 @@ main()
else if (x == xmax) {
// Fall off right edge
++x;
- break;
}
else if (cave[cavepos(xmin, xmax, ymax, x + 1, y + 1)] == '\0') {
// Drop down and right
@@ -207,15 +230,35 @@ main()
cave[cavepos(xmin, xmax, ymax, x, y)] = 'o';
break;
}
+
+ if (x < xmin || x > xmax) {
+ if (cave_resize(&cave, &xmin, &xmax, &ymax, (x < xmin ? x - 10 : x + 10), ymax) != 0) {
+ fprintf(stderr, "Unable to resize cave for %d,%d\n", x, ymax);
+ free(cave);
+ regfree(&coords);
+ return -1;
+ }
+ }
}
#if 0
cave_dump(cave, xmin, xmax, ymax);
#endif
- if (x < xmin || x > xmax || y >= ymax)
- // Grain fell out of cave
- break;
+ if (y >= ymax) {
+ if (part == 2) {
+ // Grain at rest on infinite floor
+ cave[cavepos(xmin, xmax, ymax, x, y)] = 'o';
+ }
+ else if (part == 1) {
+ // Grain fell out of cave
+ break;
+ }
+ else {
+ fprintf(stderr, "Unexpected part %d\n", part);
+ break;
+ }
+ }
}
printf("Grains: %d\n", grain);