From 4f5a4920182eb904eabd09db7cc2c70cadd603cc Mon Sep 17 00:00:00 2001 From: Adam Spragg Date: Mon, 5 Dec 2022 13:50:44 +0000 Subject: Add support for CrateMover9001, to solve part 2 --- 5.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5a.c | 136 --------------------------------------------- makefile | 2 +- 3 files changed, 190 insertions(+), 137 deletions(-) create mode 100644 5.c delete mode 100644 5a.c diff --git a/5.c b/5.c new file mode 100644 index 0000000..f404440 --- /dev/null +++ b/5.c @@ -0,0 +1,189 @@ + +#include +#include +#include +#include +#include +#include + + +struct crate { + struct crate * next; + char id; +}; + + +int +crates_move_9000(struct crate ** stack, int stacks, int dest, int src, int count) +{ + int i; + + if (dest < 0 || dest >= stacks + || src < 0 || src >= stacks) + { + fprintf(stderr, "Invalid src/dest stack (%d/%d/%d)\n", + stacks, dest, src); + return -1; + } + + for (i = 0; i < count; ++i) { + struct crate * c; + + if (stack[src] == NULL) { + fprintf(stderr, "No crates available in stack %d\n", + src); + return -1; + } + + c = stack[src]; + stack[src] = c->next; + c->next = stack[dest]; + stack[dest] = c; + } + + return 0; +} + + +int +crates_move_9001(struct crate ** stack, int stacks, int dest, int src, int count) +{ + int i; + struct crate * first, * last; + + if (dest < 0 || dest >= stacks + || src < 0 || src >= stacks) + { + fprintf(stderr, "Invalid src/dest stack (%d/%d/%d)\n", + stacks, dest, src); + return -1; + } + + last = first = stack[src]; + for (i = 1; i < count; ++i) { + if (last) + last = last->next; + } + if (!last) { + fprintf(stderr, "Fewer than %d crates available in stack %d\n", + count, src); + return -1; + } + + stack[src] = last->next; + last->next = stack[dest]; + stack[dest] = first; + + return 0; +} + + +int +crates_dump(struct crate ** stack, int stacks) +{ + int i; + + for (i = 0; i < stacks; ++i) { + struct crate * c; + + fprintf(stderr, "%d:", i + 1); + for (c = stack[i]; c != NULL; c = c->next) { + fprintf(stderr, " %c", c->id); + } + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + + return 0; +} + + +int +main(int argc, char ** argv) +{ + int (*crates_move)(struct crate **, int, int, int, int) = crates_move_9000; + char buf[BUFSIZ]; + int stacks = 0, i; + struct crate ** stack = NULL; + regex_t movecmd; + + while ((i = getopt(argc, argv, "m:")) != -1) { + switch (i) { + case 'm': + if (strcmp(optarg, "9000") == 0) + crates_move = crates_move_9000; + else if (strcmp(optarg, "9001") == 0) + crates_move = crates_move_9001; + else { + fprintf(stderr, "Unknown CrateMover %s\n", optarg); + return -1; + } + break; + + default: + return -1; + } + } + + while (fgets(buf, sizeof(buf), stdin)) { + int len; + + len = strlen(buf); + + if (len == 1 && buf[0] == '\n') { + break; + } + if (stacks == 0 && stack == NULL) { + if (len % 4 != 0) { + fprintf(stderr, "Unexpected first line width: %d\n", len); + return -1; + } + stacks = len / 4; + stack = calloc(stacks, sizeof(struct crate *)); + } + if (len != stacks * 4) { + fprintf(stderr, "Unexpected input line width: %d/%d\n", len, stacks * 4); + return -1; + } + + for (i = 0; i < stacks; ++i) { + if (isupper(buf[i * 4 + 1])) { + struct crate ** pc = stack + i; + while (*pc != NULL) + pc = &(*pc)->next; + *pc = malloc(sizeof(struct crate)); + (*pc)->next = NULL; + (*pc)->id = buf[i * 4 + 1]; + } + } + +#ifdef CRATES_DUMP + crates_dump(stack, stacks); +#endif + } + + regcomp(&movecmd, "move ([[:digit:]]+) from ([[:digit:]]+) to ([[:digit:]]+)\n", REG_EXTENDED); + while (fgets(buf, sizeof(buf), stdin)) { + regmatch_t matches[4]; + if (regexec(&movecmd, buf, 4, matches, 0) != 0) { + fprintf(stderr, "Unexpected move command: %s\n", buf); + } + crates_move(stack, stacks, + atoi(buf + matches[3].rm_so) - 1, + atoi(buf + matches[2].rm_so) - 1, + atoi(buf + matches[1].rm_so)); + +#ifdef CRATES_DUMP + crates_dump(stack, stacks); +#endif + } + regfree(&movecmd); + + for (i = 0; i < stacks; ++i) { + fputc(stack[i] ? stack[i]->id : ' ', stdout); + } + fputc('\n', stdout); + + return 0; +} + diff --git a/5a.c b/5a.c deleted file mode 100644 index 1fc80d0..0000000 --- a/5a.c +++ /dev/null @@ -1,136 +0,0 @@ - -#include -#include -#include -#include -#include - - -struct crate { - struct crate * next; - char id; -}; - - -int -crates_move(struct crate ** stack, int stacks, int dest, int src, int count) -{ - int i; - - if (dest < 0 || dest >= stacks - || src < 0 || src >= stacks) - { - fprintf(stderr, "Invalid src/dest stack (%d/%d/%d)\n", - stacks, dest, src); - return -1; - } - - for (i = 0; i < count; ++i) { - struct crate * c; - - if (stack[src] == NULL) { - fprintf(stderr, "No crates available in stack %d\n", - src); - return -1; - } - - c = stack[src]; - stack[src] = c->next; - c->next = stack[dest]; - stack[dest] = c; - } - - return 0; -} - - -int -crates_dump(struct crate ** stack, int stacks) -{ - int i; - - for (i = 0; i < stacks; ++i) { - struct crate * c; - - fprintf(stderr, "%d:", i + 1); - for (c = stack[i]; c != NULL; c = c->next) { - fprintf(stderr, " %c", c->id); - } - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - - return 0; -} - - -int -main() -{ - char buf[BUFSIZ]; - int stacks = 0, i; - struct crate ** stack = NULL; - regex_t movecmd; - - while (fgets(buf, sizeof(buf), stdin)) { - int len; - - len = strlen(buf); - - if (len == 1 && buf[0] == '\n') { - break; - } - if (stacks == 0 && stack == NULL) { - if (len % 4 != 0) { - fprintf(stderr, "Unexpected first line width: %d\n", len); - return -1; - } - stacks = len / 4; - stack = calloc(stacks, sizeof(struct crate *)); - } - if (len != stacks * 4) { - fprintf(stderr, "Unexpected input line width: %d/%d\n", len, stacks * 4); - return -1; - } - - for (i = 0; i < stacks; ++i) { - if (isupper(buf[i * 4 + 1])) { - struct crate ** pc = stack + i; - while (*pc != NULL) - pc = &(*pc)->next; - *pc = malloc(sizeof(struct crate)); - (*pc)->next = NULL; - (*pc)->id = buf[i * 4 + 1]; - } - } - -#ifdef CRATES_DUMP - crates_dump(stack, stacks); -#endif - } - - regcomp(&movecmd, "move ([[:digit:]]+) from ([[:digit:]]+) to ([[:digit:]]+)\n", REG_EXTENDED); - while (fgets(buf, sizeof(buf), stdin)) { - regmatch_t matches[4]; - if (regexec(&movecmd, buf, 4, matches, 0) != 0) { - fprintf(stderr, "Unexpected move command: %s\n", buf); - } - crates_move(stack, stacks, - atoi(buf + matches[3].rm_so) - 1, - atoi(buf + matches[2].rm_so) - 1, - atoi(buf + matches[1].rm_so)); - -#ifdef CRATES_DUMP - crates_dump(stack, stacks); -#endif - } - regfree(&movecmd); - - for (i = 0; i < stacks; ++i) { - fputc(stack[i] ? stack[i]->id : ' ', stdout); - } - fputc('\n', stdout); - - return 0; -} - diff --git a/makefile b/makefile index cd67fac..a13a109 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ all: bin/1a bin/1b \ bin/2a bin/2b \ bin/3a bin/3b \ bin/4a bin/4b \ - bin/5a \ + bin/5 \ bin/%: %.c $(CC) $(CFLAGS) -o $@ $< -- cgit v1.2.1