diff options
-rw-r--r-- | 20.c | 100 | ||||
-rw-r--r-- | makefile | 1 |
2 files changed, 101 insertions, 0 deletions
@@ -0,0 +1,100 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +struct num { + int val; + int ord; +}; + + +// Proper mathematical modulo, which returns a value in the range 0 <= n < m +// Even if n is negative. +// Warning, evaluates `m` multiple times (but `n` only once) +#define modulo(n, m) ((((n) % (m)) + (m)) % (m)) + + +int +main() +{ + char buf[BUFSIZ]; + struct num * nums = NULL; + int nnums = 0, numsize = 0, i, pos; + + // Read file. + while (fgets(buf, sizeof(buf), stdin)) { + char * end; + + if (nnums == numsize) { + void * p; + + numsize += BUFSIZ; + if ((p = realloc(nums, numsize * sizeof(struct num))) == NULL) { + fprintf(stderr, "Bad realloc(%zu)\n", numsize * sizeof(struct num)); + free(nums); + return -1; + } + nums = p; + } + + if ((nums[nnums].val = strtol(buf, &end, 10)) == 0 + && end == buf) + { + fprintf(stderr, "Invalid entry: %s\n", buf); + free(nums); + return -1; + } + nums[nnums].ord = nnums; + ++nnums; + } + + // Mix file. + for (i = 0, pos = 0; i < nnums; ++i) { + int newpos; + struct num tmp; + + // Look for the num whose ordinal is i, starting from the + // position of the last num we looked at. + while (nums[pos].ord != i) + pos = modulo(pos + 1, nnums); + + if (nums[pos].val == 0) + continue; + + // Move this. + tmp = nums[pos]; + + newpos = modulo(pos + nums[pos].val, nnums - 1); // Buffer of nums does not include moving num + if (newpos > pos) + memmove(nums + pos, nums + pos + 1, (newpos - pos) * sizeof(struct num)); + else + memmove(nums + newpos + 1, nums + newpos, (pos - newpos) * sizeof(struct num)); + + nums[newpos] = tmp; + } + + // Find zero. + for (i = 0; i < nnums; ++i) + if (nums[i].val == 0) + break; + if (i == nnums) { + fprintf(stderr, "No zero found!\n"); + free(nums); + return -1; + } + + printf("Coords: %d,%d,%d; sum %d\n", + nums[modulo(i + 1000, nnums)].val, + nums[modulo(i + 2000, nnums)].val, + nums[modulo(i + 3000, nnums)].val, + nums[modulo(i + 1000, nnums)].val + + nums[modulo(i + 2000, nnums)].val + + nums[modulo(i + 3000, nnums)].val); + + free(nums); + + return 0; +} + @@ -21,6 +21,7 @@ all: bin \ bin/17 \ bin/18 \ bin/19 \ + bin/20 \ bin: mkdir -p $@ |