feat: add day 3

This commit is contained in:
2023-12-06 17:34:27 +01:00
parent b88ad0abf9
commit 52784ef81a
7 changed files with 316 additions and 14 deletions

146
day_3.c Normal file
View File

@@ -0,0 +1,146 @@
//
// Created by lennart on 12/6/23.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include "input_handler.h"
typedef struct {
char **data;
int height;
int width;
} PartsMap;
// Functions
PartsMap* load_map(const char *file_name);
void free_map(PartsMap *map);
bool is_adjacent_to_symbol(PartsMap *map, int row, int col, int len);
bool is_gear(PartsMap *map, int g_row, int g_col, int *num1, int *num2);
int main() {
PartsMap *map = load_map("day_3.txt");
// Part 1 - Iterate over each row and find numbers with adjacent symbols
int sum = 0;
for(int row = 0; row < map->height; row++) {
const char *begin = &map->data[row][0];
char *pos = (char*) begin;
while(*pos != 0) {
const char *before = pos;
if(isdigit(*pos)) {
unsigned long num = strtoul(before, &pos, 10);
if(is_adjacent_to_symbol(map, row, (int) (before - begin), (int) (pos - before))) {
sum += (int) num;
}
} else {
pos++;
}
}
}
printf("Result #1: %i\n", sum);
// Part 2 - Iterate over each row and find gear symbols (*) with 2 adjacent numbers
sum = 0;
for(int row = 0; row < map->height; row++) {
for(int col = 0; col < map->width; col++) {
if(map->data[row][col] == '*') {
int num1, num2;
if(is_gear(map, row, col, &num1, &num2)) {
sum += num1 * num2;
}
}
}
}
printf("Result #2: %i", sum);
free_map(map);
}
bool is_gear(PartsMap *map, int g_row, int g_col, int *num1, int *num2) {
int count = 0;
int rowMin = max(g_row - 1, 0);
int rowMax = min(g_row + 1, map->height - 1);
int colMin = max(g_col - 1, 0);
int colMax = min(g_col + 1, map->width - 1);
for(int row = rowMin; row <= rowMax; row++) {
const char *begin = &map->data[row][0];
char *pos = &map->data[row][colMin];
while(isdigit(*pos) && pos > begin) {
pos--;
}
while(pos - begin <= colMax) {
if(isdigit(*pos)) {
const char *before = pos;
unsigned long num = strtoul(before, &pos, 10);
if(++count == 1) {
*num1 = (int) num;
} else if(count == 2) {
*num2 = (int) num;
} else {
return false; // More than 2 adjacent numbers
}
} else {
pos++;
}
}
}
return count == 2;
}
bool is_adjacent_to_symbol(PartsMap *map, int row, int col, int len) {
int rowMin = max(row - 1, 0);
int rowMax = min(row + 2, map->height);
int colMin = max(col - 1, 0);
int colMax = min(col + len + 1, map->width);
for(int cr = rowMin; cr < rowMax; cr++) {
for(int cc = colMin; cc < colMax; cc++) {
char c = map->data[cr][cc];
if(c != '.' && !isdigit(c)) {
return true;
}
}
}
return false;
}
PartsMap* load_map(const char *file_name) {
FILE *f = fopen(file_name, "r");
if(f == NULL) {
printf("ERROR: Input file not found!");
exit(1);
}
char *buffer = NULL;
int bufferLen = 0;
size_t length = 16;
PartsMap *map = malloc(sizeof (PartsMap));
map->height = 0;
map->data = malloc(sizeof (map->data) * length);
while(!feof(f)) {
if(map->height >= length) {
map->data = realloc(map->data, sizeof (map->data) * (length *= 2));
}
read_line(f, &buffer, &bufferLen);
map->data[map->height++] = strdup(buffer);
}
map->width = strlen(map->data[0]);
fclose(f);
free(buffer);
return map;
}
void free_map(PartsMap *map) {
for(size_t row = 0; row < map->height; row++) {
free(map->data[row]);
}
free(map->data);
free(map);
}