From e5829c438669e8b12236aaccd5b0c7c0c51e800d Mon Sep 17 00:00:00 2001 From: Adam Spragg Date: Tue, 20 Dec 2022 18:53:53 +0000 Subject: Solve puzzle 20 part 1 --- 20.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 20.c (limited to '20.c') diff --git a/20.c b/20.c new file mode 100644 index 0000000..e738d9c --- /dev/null +++ b/20.c @@ -0,0 +1,100 @@ + +#include +#include +#include + + +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; +} + -- cgit v1.2.1