diff options
author | Adam Spragg <adam@spra.gg> | 2022-12-20 19:02:04 +0000 |
---|---|---|
committer | Adam Spragg <adam@spra.gg> | 2022-12-20 19:02:04 +0000 |
commit | e17a454221a6539640e3ea9b5f4cdfbd5471fa3a (patch) | |
tree | 1fc5e3b1e070d0253e88f010d4a7dbcd3427fbd5 | |
parent | e5829c438669e8b12236aaccd5b0c7c0c51e800d (diff) |
Solve puzzle 20 part 2
Phew. Nice easy one for today! Caught up now.
-rw-r--r-- | 20.c | 91 |
1 files changed, 69 insertions, 22 deletions
@@ -2,11 +2,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> struct num { - int val; - int ord; + long val; + long ord; }; @@ -17,11 +18,54 @@ struct num { int -main() +main(int argc, char ** argv) { + long key = 1, rounds = 1; char buf[BUFSIZ]; struct num * nums = NULL; - int nnums = 0, numsize = 0, i, pos; + int nnums = 0, numsize = 0, r, i, pos; + + // Parse options + while ((i = getopt(argc, argv, "p:k:r:")) != -1) { + switch (i) { + case 'p': + switch (atoi(optarg)) { + case 1: + key = 1; + rounds = 1; + break; + + case 2: + key = 811589153; + rounds = 10; + break; + + default: + fprintf(stderr, "Invalid part %s\n", optarg); + return -1; + } + break; + + case 'k': + key = atoi(optarg); + if (!key) { + fprintf(stderr, "Invalid key %s\n", optarg); + return -1; + } + break; + + case 'r': + rounds = atoi(optarg); + if (rounds < 0) { + fprintf(stderr, "Invalid rounds %s\n", optarg); + return -1; + } + break; + + default: + return -1; + } + } // Read file. while (fgets(buf, sizeof(buf), stdin)) { @@ -46,33 +90,36 @@ main() free(nums); return -1; } + nums[nnums].val *= key; nums[nnums].ord = nnums; ++nnums; } // Mix file. - for (i = 0, pos = 0; i < nnums; ++i) { - int newpos; - struct num tmp; + for (r = 0; r < rounds; ++r) { + 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); + // 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; + if (nums[pos].val == 0) + continue; - // Move this. - tmp = nums[pos]; + // 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)); + 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; + nums[newpos] = tmp; + } } // Find zero. @@ -85,7 +132,7 @@ main() return -1; } - printf("Coords: %d,%d,%d; sum %d\n", + printf("Coords: %ld,%ld,%ld; sum %ld\n", nums[modulo(i + 1000, nnums)].val, nums[modulo(i + 2000, nnums)].val, nums[modulo(i + 3000, nnums)].val, |