diff options
-rw-r--r-- | 14.c | 59 |
1 files changed, 51 insertions, 8 deletions
@@ -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); |