Committing days 1-4
This commit is contained in:
130
03/03.c
Normal file
130
03/03.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user