Files
AdventOfCode2023/03/03.c
2023-12-04 19:40:03 -05:00

130 lines
3.1 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define STRBUF_SIZE 200
#define DEFAULT_FILE "input.txt"
#define ISDIGIT(X) (X >= '0' && X <= '9')
// Parses a found number.
// The provided location can be any digit of the
// number; this function will automatically
// seek the first digit before processing.
// Erases numbers as they are processed.
uint16_t parse_num_at(char *str, uint8_t idx)
{
// Check input
if (str[idx] < '0' || str[idx] > '9') return 0;
// Find first digit of number
while (ISDIGIT(str[idx]) && idx) idx--;
if (!ISDIGIT(str[idx])) idx++;
uint16_t num = 0;
// Add up all digits
while (ISDIGIT(str[idx]))
{
num = (num * 10) + (str[idx] - '0');
// Erase the number to make sure we don't count it twice
str[idx] = '.';
idx++;
}
return num;
}
// Returns the sum of all numbers around a symbol,
// including diagonals.
uint16_t search_numbers_around( uint8_t idx,
char *above,
char *current,
char *below)
{
uint16_t sum = 0;
if (idx) sum += parse_num_at(above, idx - 1);
sum += parse_num_at(above, idx);
sum += parse_num_at(above, idx + 1);
sum += parse_num_at(current, idx + 1);
sum += parse_num_at(current, idx - 1);
if (idx) sum += parse_num_at(below, idx - 1);
sum += parse_num_at(below, idx);
sum += parse_num_at(below, idx + 1);
return sum;
}
// Search through a line of *current for symbols.
// returns the sum for that line (erases numbers as
// they are processed.)
uint16_t parse_line(char *above, char *current, char *below)
{
uint16_t sum = 0;
uint8_t idx;
char c;
for (idx = 0; current[idx] != 0; idx++)
{
c = current[idx];
if (!ISDIGIT(c) && c != '.' && c != '\n')
{
// We've found a symbol,
// add up all numbers around it
sum += search_numbers_around(idx, above, current, below);
}
}
return sum;
}
int main(int argc, char **argv)
{
// Get filename as an argument, defaults to "input.txt"
char *path = (argc > 1) ? argv[1] : DEFAULT_FILE;
if (!path)
{
printf("Requires input file.\n");
return 1;
}
FILE *file = fopen(path, "r");
if (!file)
{
printf("Could not find file.");
return 1;
}
char *above = malloc(sizeof(char) * STRBUF_SIZE);
char *current = malloc(sizeof(char) * STRBUF_SIZE);
char *below = malloc(sizeof(char) * STRBUF_SIZE);
memset(above, '.', STRBUF_SIZE);
fgets(current, STRBUF_SIZE, file);
uint32_t sum = 0;
while (fgets(below, 200, file))
{
sum += parse_line(above, current, below);
free(above);
above = current;
current = below;
below = malloc(sizeof(char) * STRBUF_SIZE);
memset(below, '.', STRBUF_SIZE);
}
// Process the last line of the file
sum += parse_line(above, current, below);
printf("Sum: %d\n", sum);
return 0;
}