#include #include #include #include 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; }