diff options
author | Adam Spragg <adam@spra.gg> | 2023-01-15 10:34:50 +0000 |
---|---|---|
committer | Adam Spragg <adam@spra.gg> | 2023-01-15 10:34:50 +0000 |
commit | 3dd30be057332cd764ee79a26673a775336322eb (patch) | |
tree | cabb7c293fa2d587a217916b6e519f98e3cd7cb6 /3.c | |
parent | 2b922997fb893a5bc14f157ad5db27ae77cec6a6 (diff) |
Puzzle 3: Consolidate 3a/3b programs into `3` with `-p` option
Like the later puzzles
Diffstat (limited to '3.c')
-rw-r--r-- | 3.c | 163 |
1 files changed, 163 insertions, 0 deletions
@@ -0,0 +1,163 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +int +chrcmp(void const * a, void const * b) +{ + return (*(char const *) a) - *((char const *) b); +} + + +int +priority(int c) +{ + if (c >= 'A' && c <= 'Z') + return 27 + c - 'A'; + if (c >= 'a' && c <= 'z') + return 1 + c - 'a'; + fprintf(stderr, "Unexpected priority request: %c\n", c); + return -1; +} + + +int +min(int a, int b) +{ + return a < b ? a : b; +} + + +int +min3(int a, int b, int c) +{ + return min(min(a, b), c); +} + + +int +rucksack_common_sum() +{ + char buf[BUFSIZ]; + int score = 0; + + while (fgets(buf, sizeof(buf), stdin)) { + int len, i, j; + + len = strlen(buf); + if (len && buf[len - 1] == '\n') + --len; + if (len % 2 == 1) { + fprintf(stderr, "Unexpected length: %d\n", len); + return -1; + } + + qsort(buf, len / 2, 1, chrcmp); + qsort(buf + len / 2, len / 2, 1, chrcmp); + + i = 0; + j = len / 2; + while (i < len / 2 && j < len) { + if (buf[i] < buf[j]) + ++i; + else if (buf[j] < buf[i]) + ++j; + else + break; + } + if (i >= len / 2 || j >= len) { + fprintf(stderr, "No match found in %s\n", buf); + return -1; + } + score += priority(buf[i]); + } + + return score; +} + + +int +group_badge_sum() +{ + char buf[3][BUFSIZ]; + int score = 0; + + while (fgets(buf[0], sizeof(buf[0]), stdin) + && fgets(buf[1], sizeof(buf[1]), stdin) + && fgets(buf[2], sizeof(buf[2]), stdin)) + { + int n, i, j, k; + + for (n = 0; n < 3; ++n) { + int len = strlen(buf[n]); + if (len && buf[n][len - 1] == '\n') { + --len; + buf[n][len] = '\0'; + } + if (len % 2 == 1) { + fprintf(stderr, "Unexpected length: %d\n", len); + return -1; + } + + qsort(buf[n], len, 1, chrcmp); + } + + i = 0; j = 0; k = 0; + while (buf[0][i] != '\0' && buf[1][j] != '\0' && buf[2][k] != '\0') { + int n = min3(buf[0][i], buf[1][j], buf[2][k]); + if (buf[0][i] == n && buf[1][j] == n && buf[2][k] == n) + break; + if (buf[0][i] == n) + ++i; + if (buf[1][j] == n) + ++j; + if (buf[2][k] == n) + ++k; + } + if (buf[0][i] == '\0' || buf[1][j] == '\0' || buf[2][k] == '\0') { + fprintf(stderr, "No match found in %s/%s/%s\n", buf[0], buf[1], buf[2]); + return -1; + } + score += priority(buf[0][i]); + } + + return score; +} + + +int +main(int argc, char ** argv) +{ + int part = 1, i; + + while ((i = getopt(argc, argv, "p:")) != -1) { + switch (i) { + case 'p': + part = atoi(optarg); + break; + + default: + return -1; + } + } + + switch (part) { + case 1: + printf("Score: %d\n", rucksack_common_sum()); + break; + + case 2: + printf("Score: %d\n", group_badge_sum()); + break; + + default: + fprintf(stderr, "Unexpected puzzle part %d\n", part); + return -1; + } + + return 0; +} + |