diff options
-rw-r--r-- | 05.c | 118 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | input.h | 8 |
3 files changed, 130 insertions, 1 deletions
@@ -0,0 +1,118 @@ +#include <stdlib.h> +#include <stdio.h> +#include <err.h> +#include <stdbool.h> +#include "input.h" + +#define INPUT "input/05.txt" +#define EXPECTED1 6113 +#define EXPECTED2 20373 + +#define RESOLUTION 1000 + +#define CMP(a, b) ((a > b) - (a < b)) + +typedef struct { + long p1[2]; + long p2[2]; +} t_line; + +/* sooooo thats about 80KB of memory on my end */ +int space1[RESOLUTION][RESOLUTION]; +int space2[RESOLUTION][RESOLUTION]; + +void line_list_read(t_line* line_list, struct input_str* input) { + for(size_t i = 0; i < input->line_count; i++) { + char* start = input->lines[i]; + char* end = start; + line_list[i].p1[0] = strtol(start, &end, 0); + start = end + 1; //skip comma + line_list[i].p1[1] = strtol(start, &end, 0); + start = end + 4; // skip arrow + line_list[i].p2[0] = strtol(start, &end, 0); + start = end + 1; // skip comma + line_list[i].p2[1] = strtol(start, &end, 0); + } +} + +void line_print(t_line* line) { + printf("%ld,%ld -> %ld,%ld\n", line->p1[0], line->p1[1], line->p2[0], line->p2[1]); +} + +void part1(struct input_str* input) { + t_line* line_list = malloc(input->line_count * sizeof(t_line)); + line_list_read(line_list, input); + for(size_t l = 0; l < input->line_count; l++) { + t_line line = line_list[l]; + long x1 = line.p1[0]; + long y1 = line.p1[1]; + long x2 = line.p2[0]; + long y2 = line.p2[1]; + if(x1 != x2 && y1 != y2) // ignore those for part1 + continue; + + long dx = -1 * CMP(x1, x2); + long dy = -1 * CMP(y1, y2); + long x, y; + // beware the monster loop + for(x = x1, y = y1; (x != x2 + dx || x1 == x2) && (y != y2 + dy || y1 == y2); x += dx, y += dy) { + space1[x][y]++; + } + } + + // count space points with at least a value of 2 + int result = 0; + for(int x = 0; x < RESOLUTION; x++) { + for(int y = 0; y < RESOLUTION; y++) { + if(space1[x][y] >= 2) + result++; + } + } + CHECK(result, EXPECTED1); + + free(line_list); +} + +void part2(struct input_str* input) { + t_line* line_list = malloc(input->line_count * sizeof(t_line)); + line_list_read(line_list, input); + for(size_t l = 0; l < input->line_count; l++) { + t_line line = line_list[l]; + long x1 = line.p1[0]; + long y1 = line.p1[1]; + long x2 = line.p2[0]; + long y2 = line.p2[1]; + long dx = -1 * CMP(x1, x2); + long dy = -1 * CMP(y1, y2); + long x, y; + for(x = x1, y = y1; (x != x2 + dx || x1 == x2) && (y != y2 + dy || y1 == y2); x += dx, y += dy) { + space2[x][y]++; + } + } + + // count space points with at least a value of 2 + int result = 0; + for(int x = 0; x < RESOLUTION; x++) { + for(int y = 0; y < RESOLUTION; y++) { + if(space2[x][y] >= 2) + result++; + } + } + CHECK(result, EXPECTED2); + + free(line_list); +} + +int main() { + // read input + struct input_str input; + input_str_read(&input, INPUT); + + // do stuff + part1(&input); + part2(&input); + + // cleanup & exit + input_str_free(&input); + return 0; +} @@ -1,7 +1,7 @@ CC=cc CFLAGS=-std=c1x -W -Wall -g LDFLAGS= -EXEC=01 02 03 04 +EXEC=01 02 03 04 05 all: $(EXEC) @@ -17,6 +17,9 @@ all: $(EXEC) 04: input.o 04.o $(CC) -o $@ $> $(LDFLAGS) +05: input.o 05.o + $(CC) -o $@ $> $(LDFLAGS) + .c.o: $(CC) -o $@ -c $< $(CFLAGS) @@ -1,6 +1,14 @@ #ifndef DEF_INPUTH #define DEF_INPUTH +/* simple macro to check a result against an expected value */ +#define CHECK(actual, expected) {\ + if(actual == expected)\ + printf("%d ok\n", actual);\ + else\ + printf("%d ko, expected %d\n", actual, expected);\ +} + struct input_int { size_t line_count; int* lines; |