#include #include #include #include static int first_half(FILE *fp) { size_t total = 0, size; ssize_t len; ssize_t first, last; char *line = NULL; while ((len = getline(&line, &size, fp)) != -1) { line[--len] = '\0'; first = last = -1; for (size_t i = 0; i <= len; i++) { if (first == -1 && isdigit(line[i])) { first = line[i] - '0'; } if (last == -1 && isdigit(line[len - i])) { last = line[len - i] - '0'; } if (first > -1 && last > -1) break; } if (first == -1 || last == -1) { fprintf(stderr, "failed to find digit in input string: %s\n", line); free(line); return EXIT_FAILURE; } total += (first * 10) + last; } free(line); printf("result: %ld\n", total); return EXIT_SUCCESS; } const struct { size_t num; char *text; } table[] = { { 1, "one" }, { 2, "two" }, { 3, "three" }, { 4, "four" }, { 5, "five" }, { 6, "six" }, { 7, "seven" }, { 8, "eight" }, { 9, "nine" }, }; inline static ssize_t lookup_num(char *line, size_t i) { if (isdigit(line[i])) return line[i] - '0'; for (size_t t = 0; t < sizeof(table) / sizeof(*table); t++) if (strncmp(&line[i], table[t].text, strlen(table[t].text)) == 0) return table[t].num; return -1; } static int second_half(FILE *fp) { size_t total = 0, size; ssize_t len; ssize_t first, last; char *line = NULL; while ((len = getline(&line, &size, fp)) != -1) { line[--len] = '\0'; first = last = -1; for (size_t i = 0; i <= len; i++) { if (first == -1) first = lookup_num(line, i); if (last == -1) last = lookup_num(line, len - i); if (first > -1 && last > -1) break; } if (first == -1 || last == -1) { fprintf(stderr, "failed to find digit in input string: %s\n", line); free(line); return EXIT_FAILURE; } total += (first * 10) + last; } free(line); printf("result: %ld\n", total); return EXIT_SUCCESS; } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); return EXIT_FAILURE; } FILE *fp = fopen(argv[1], "r"); if (!fp) { fprintf(stderr, "failed to open input file: %s\n", argv[1]); return EXIT_FAILURE; } const char *half; int ret; if ((half = getenv("AOC_TREBUCHET_HALF")) && strcmp(half, "first") == 0) ret = first_half(fp); else ret = second_half(fp); fclose(fp); return ret; }