advent-of-code-2023/day1/part2.c

137 lines
3.0 KiB
C

#include <ctype.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
* Each line of the input file contains a string with a mix of letters and digits
* Each line's "calibration value" is a single two digit number, made up of the first and last
* digit found in the string
* Print out the sum of all the calibration values.
*/
char buffer[2048];
void read_line(char* linebuf, FILE* file)
{
char* str = fgets(linebuf, 2048, file);
if (feof(file))
{
return;
}
if (str == NULL)
{
fprintf(stderr, "Fgets error");
linebuf[0] = '\0';
}
}
bool parse_digit(const char* str, char* result, int* n)
{
char* nums[] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
int numslen[] = {3, 3, 5, 4, 4, 3, 5, 5, 4};
char numschar[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
for (int i = 0; i < 9; i++)
{
if(strncmp(str, nums[i], numslen[i]) == 0)
{
*result = numschar[i];
*n = numslen[i];
return true;
}
}
return false;
}
void extract_digits(char* str, char *first, char *last)
{
char *p,*q;
p = str;
int n;
bool found = false;
while (*p != '\0' && !found)
{
switch(*p)
{
case 'o':
case 't':
case 'f':
case 's':
case 'e':
case 'n':
if(parse_digit(p, first, &n))
{
found = true;
break;
}
default:
if (isdigit(*p))
{
*first = *p;
found = true;
}
else
p++;
}
}
q = p;
*last = *first;
while (*q != '\0') // find next digit
{
switch(*q)
{
case 'o':
case 't':
case 'f':
case 's':
case 'e':
case 'n':
if(parse_digit(q, last, &n))
{
q++;
break;
}
default:
if (isdigit(*q))
{
*last = *q;
}
q++;
}
}
}
long convert_chars(char first, char last)
{
char num[3] = { first, last, '\0' };
return strtoul(num, NULL, 10);
}
int main(int argc, char *argv[])
{
FILE* input = fopen("input", "r");
if (input == NULL)
{
fprintf(stderr, "error opening file");
return EXIT_FAILURE;
}
long sum = 0;
char first, last;
while(true)
{
read_line(buffer, input);
if (feof(input))
break;
extract_digits(buffer, &first, &last);
long value = convert_chars(first, last);
printf("%ld\t%c\t%c\t%s", value, first, last, buffer);
sum += value;
}
printf("%ld", sum);
return EXIT_SUCCESS;
}