feat: add day 3
This commit is contained in:
146
day_3.c
Normal file
146
day_3.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user