summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Spragg <adam@spra.gg>2022-12-20 18:53:53 +0000
committerAdam Spragg <adam@spra.gg>2022-12-20 18:53:53 +0000
commite5829c438669e8b12236aaccd5b0c7c0c51e800d (patch)
treefff46211126935ba44db13f85228bbeb4882f5ff
parentb3c1ef2465b2a6486ddbc487f888091d47c58c85 (diff)
Solve puzzle 20 part 1
-rw-r--r--20.c100
-rw-r--r--makefile1
2 files changed, 101 insertions, 0 deletions
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 <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;
+}
+
diff --git a/makefile b/makefile
index 5b108f6..819be29 100644
--- a/makefile
+++ b/makefile
@@ -21,6 +21,7 @@ all: bin \
bin/17 \
bin/18 \
bin/19 \
+ bin/20 \
bin:
mkdir -p $@