summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05.c118
-rw-r--r--Makefile5
-rw-r--r--input.h8
3 files changed, 130 insertions, 1 deletions
diff --git a/05.c b/05.c
new file mode 100644
index 0000000..eeac8ce
--- /dev/null
+++ b/05.c
@@ -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;
+}
diff --git a/Makefile b/Makefile
index 3be3369..a58a9cf 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/input.h b/input.h
index 6507053..d386da0 100644
--- a/input.h
+++ b/input.h
@@ -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;