AoC2023/day1/day1b.c
2023-12-03 17:03:15 +01:00

81 lines
1.9 KiB
C

#include <stdio.h>
#include <string.h>
#include <limits.h>
char *firstMatch (char *string, int offset, int *digit);
char *lastMatch (char *string, int *digit);
// array of strings with all digits and human-numbers
const char *numbers[] = {"one", "two", "three", "four", "five", "six",
"seven", "eight", "nine",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int main()
{
FILE *input;
input = fopen("./input", "r");
int digit = 0;
int value = 0;
int sum = 0;
char row[100];
// use fgets
while ((fgets(row, 100, input)) != 0) {
firstMatch(row, 0, &digit);
value = digit * 10;
lastMatch(row, &digit);
value += digit;
printf("value: %d\n", value);
sum += value;
}
fclose(input);
printf("%u\n", sum);
}
// function with input offset and string, returns offset (and val?)
// looks for every string / char, return lowest offset
// to find rightmost, repeatedly call this function with offset + 1
char *firstMatch (char *string, int offset, int *digit)
{
// this ptr is 1 step outside of the array, because the
// relational operators in C are only defined if both pointers
// point within the same array or one step beyond the last member
char *first = &string[99] + 1;
// looks for each number string from numbers[]
// and remembers the lowest pointer
char *match;
for (int i = 0; i < sizeof(numbers) / 8; i++) {
match = strstr(string + offset, numbers[i]);
if (match == 0) continue;
if (match < first) {
first = match;
if (i <= 8) {
*digit = i + 1;
} else {
*digit = i - 9;
}
}
}
// Pointer unchanged? No match, return NULL
if (first == &string[99] + 1) first = NULL;
return first;
}
char *lastMatch (char *string, int *digit)
{
char *last = &string[0];
int offset = 0;
while (firstMatch(string, offset, digit) >= last) {
if (firstMatch(string, offset, digit) == NULL) break;
last = firstMatch(string, offset, digit);
offset++;
}
return last;
}