Problem description from the Advent of Code website:
Part 1:
The task involves analyzing a calibration document containing lines of text. Each line represents a calibration value that needs to be recovered by extracting the first and last digits and combining them into a two-digit number. The goal is to find the sum of all these calibration values.
For example:
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
In this example, the calibration values of these four lines are 12, 38, 15, and 77. Adding these together produces 142.
Part 2:
In problem two, the calibration document may include digits spelled out with letters (e.g., "one," "two," etc.). The task is to identify the actual first and last digits in each line, taking into account both numerical digits and spelled-out numbers. The overall objective remains the same: find the sum of the calibration values obtained from combining the first and last digits of each line.
For example:
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
In this example, the calibration values are 29, 83, 13, 24, 42, 14, and 76. Adding these together produces 281.
Here's the code I wrote in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getDigits(char* src, int* dest);
int main(int argc, char** argv) {
FILE* input = fopen(argv[1], "r");
if (input == NULL)
return -1;
char* line = NULL;
size_t line_size = 0;
int digits[2], line_len, sum = 0;
while ((line_len = getline(&line, &line_size, input)) != -1) {
getDigits(line, digits);
sum += 10*digits[0] + digits[1];
}
printf("Sum: %d\n", sum);
return 0;
}
void getDigits(char* src, int* dest) {
int len = strlen(src);
// Get first digit
for (int i = 0; i < len; i++) {
if (!strncmp("zero", src+i, 4)) {
dest[0] = 0;
break;
}
if (!strncmp("one", src+i, 3)) {
dest[0] = 1;
break;
}
if (!strncmp("two", src+i, 3)) {
dest[0] = 2;
break;
}
if (!strncmp("three", src+i, 5)) {
dest[0] = 3;
break;
}
if (!strncmp("four", src+i, 4)) {
dest[0] = 4;
break;
}
if (!strncmp("five", src+i, 4)) {
dest[0] = 5;
break;
}
if (!strncmp("six", src+i, 3)) {
dest[0] = 6;
break;
}
if (!strncmp("seven", src+i, 5)) {
dest[0] = 7;
break;
}
if (!strncmp("eight", src+i, 5)) {
dest[0] = 8;
break;
}
if (!strncmp("nine", src+i, 4)) {
dest[0] = 9;
break;
}
if (src[i] > 47 && src[i] < 58) { // 48 -> 57 ASCII => number
dest[0] = src[i] - 48;
break;
}
}
// Get second digit
for (int i = len-1; i >= 0; i--) {
if (!strncmp("zero", src+i-3, 4)) {
dest[1] = 0;
break;
}
if (!strncmp("one", src+i-2, 3)) {
dest[1] = 1;
break;
}
if (!strncmp("two", src+i-2, 3)) {
dest[1] = 2;
break;
}
if (!strncmp("three", src+i-4, 5)) {
dest[1] = 3;
break;
}
if (!strncmp("four", src+i-3, 4)) {
dest[1] = 4;
break;
}
if (!strncmp("five", src+i-3, 4)) {
dest[1] = 5;
break;
}
if (!strncmp("six", src+i-2, 3)) {
dest[1] = 6;
break;
}
if (!strncmp("seven", src+i-4, 5)) {
dest[1] = 7;
break;
}
if (!strncmp("eight", src+i-4, 5)) {
dest[1] = 8;
break;
}
if (!strncmp("nine", src+i-3, 4)) {
dest[1] = 9;
break;
}
if (src[i] > 47 && src[i] < 58) {
dest[1] = src[i] - 48;
break;
}
}
}
Is there any way to optimize the "spelled out numbers" checking?