summaryrefslogtreecommitdiff
path: root/05.c
blob: eeac8ced78dae8f3409e408a38c596f8f98b1a06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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;
}