summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--5a.c136
-rw-r--r--makefile1
2 files changed, 137 insertions, 0 deletions
diff --git a/5a.c b/5a.c
new file mode 100644
index 0000000..1fc80d0
--- /dev/null
+++ b/5a.c
@@ -0,0 +1,136 @@
+
+#include <ctype.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+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 6b7b00a..cd67fac 100644
--- a/makefile
+++ b/makefile
@@ -5,6 +5,7 @@ all: bin/1a bin/1b \
bin/2a bin/2b \
bin/3a bin/3b \
bin/4a bin/4b \
+ bin/5a \
bin/%: %.c
$(CC) $(CFLAGS) -o $@ $<