diff --git a/05/solution.c b/05/solution.c index 61808db..5b589d8 100644 --- a/05/solution.c +++ b/05/solution.c @@ -3,70 +3,79 @@ #include #include -typedef struct crate { - char c; - struct crate *nA; - struct crate *nB; -} crate; +typedef struct crates { + char *c; + size_t len, alloc; +} crates; -#define alloc_stacks(C, N) \ - if (C) C = realloc(C, sizeof(crate) * N); \ - else C = malloc(sizeof(crate) * N); +#define alloc_stacks(C) \ + if (C) C = realloc(C, sizeof(crates) * A); \ + else C = malloc(sizeof(crates) * A); \ + for (i = N; i < A; i++) C[i].c = 0; + +#define alloc_crates(C, N) \ + if (C.c) { \ + C.len += N; \ + if (C.len > C.alloc) \ + C.c = realloc(C.c, C.alloc = C.len); \ + } else \ + C.c = malloc(C.len = C.alloc = N); + +#define crate_pos(C, N) (C.c + C.len + N) int main(void) { - char l[BUFSIZ], *e, *m = 0; - crate **A = 0, **B = 0, *c, *p; - int i, n, N = 0, f, t; + char l[BUFSIZ], *e, *m = 0, ic, *tc, *tf; + crates *stacksA = 0, *stacksB = 0; + int i, n, N = 0, A, f, t; while (fgets(l, BUFSIZ, stdin)) { if ((e = strrchr(l, ']'))) { if (e > m) { m = e; - N = (m - l) / 4 + 1; - alloc_stacks(A, N); - alloc_stacks(B, N); + A = (m - l) / 4 + 1; + alloc_stacks(stacksA) + alloc_stacks(stacksB) + N = A; } for (i = 0; i < N; i++) { - c = calloc(1, sizeof(crate)); - c->c = l[i*4+1]; - - if (!A[i] || A[i]->c == ' ') { - A[i] = c; - B[i] = c; - } else { - for (p = A[i]; p->nA; p = p->nA); - p->nA = c; - for (p = B[i]; p->nB; p = p->nB); - p->nB = c; + if ((ic = l[i*4+1]) != ' ') { + alloc_crates(stacksA[i], 1) + alloc_crates(stacksB[i], 1) + memmove(stacksA[i].c + 1, stacksA[i].c, stacksA[i].len - 1); + memmove(stacksB[i].c + 1, stacksB[i].c, stacksB[i].len - 1); + stacksA[i].c[0] = ic; + stacksB[i].c[0] = ic; } } } - if (sscanf(l, "move %u from %u to %u", &n, &f, &t) == 3) { - f--; - t--; - for (i = 0; i < n; i++) { - c = A[f]; - A[f] = c->nA; - c->nA = A[t]; - A[t] = c; - } + if (l[0] == 'm') { + n = strtol(l + 5, &e, 10); + f = strtol(e + 6, &e, 10) - 1; + t = atoi(e + 4) - 1; - c = B[f]; - for (i = 1; i < n; i++) c = c->nB; - p = c->nB; - c->nB = B[t]; - B[t] = B[f]; - B[f] = p; + alloc_crates(stacksA[t], n) + tf = crate_pos(stacksA[f], -1); + tc = crate_pos(stacksA[t], -n); + for (i = 0; i < n; i++) + tc[i] = tf[-i]; + stacksA[f].len -= n; + + alloc_crates(stacksB[t], n) + tf = crate_pos(stacksB[f], -n); + tc = crate_pos(stacksB[t], -n); + for (i = 0; i < n; i++) + tc[i] = tf[i]; + stacksB[f].len -= n; } } printf("Silver: "); for (i = 0; i < N; i++) - if (A[i]) printf("%c", A[i]->c); + printf("%c", *crate_pos(stacksA[i], -1)); printf("\nGold: "); for (i = 0; i < N; i++) - if (B[i]) printf("%c", B[i]->c); + printf("%c", *crate_pos(stacksB[i], -1)); printf("\n"); }