aoc-2023/c/01/part_2.c

109 lines
2.1 KiB
C

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// The amount of input lines
const int lines = 1000;
// The amount of numbers that can be found
const int number_size = 10;
const char numbers[10][6] =
{ "zero"
, "one"
, "two"
, "three"
, "four"
, "five"
, "six"
, "seven"
, "eight"
, "nine"
};
int extract_number(int *numbers, int size);
int *find_numbers(char *text);
int numbers_size(int *numbers);
int starts_with_number(char *text);
int main(void) {
int sum = 0;
for (int i = 0; i < lines; i++) {
// Instead of directly looping through the array,
// we extract a list of integers first
int *ns = find_numbers(get_string(""));
// Then use that list to increase the sum
sum += extract_number(ns, numbers_size(ns));
// Free all allocated information
free(ns);
}
printf("%i\n", sum);
return 0;
}
/* Given a list of integers, combines the first and the last digit to create a
single number between 0 and 100.
*/
int extract_number(int *numbers, int size) {
return (numbers[0] * 10) + numbers[size - 1];
}
// Convert a string to an array of integers
int *find_numbers(char *text) {
int length = strlen(text);
int *items = malloc(sizeof(int) * length);
int cursor = 0;
for (int i = 0; i < length; i++) {
char c = text[i];
if (c >= '0' && c <= '9') {
items[cursor] = c - '0';
cursor++;
}
else {
int n = starts_with_number(text + i);
if (n >= 0) {
items[cursor] = n;
cursor++;
}
}
}
items[cursor] = -1;
return items;
}
int numbers_size(int *numbers) {
int i = 0;
while (numbers[i] >= 0) {
i++;
}
return i;
}
/* Determine whether a (sub)string starts with a given number.
*/
int starts_with_number(char *text) {
for (int i = 0; i < number_size; i ++) {
if (strstr(text, numbers[i]) == text) {
return i;
}
}
// If not, return -1
return -1;
}