diff options
author | Vincent Douillet <vincent@vdouillet.fr> | 2021-12-05 21:28:14 +0100 |
---|---|---|
committer | Vincent Douillet <vincent@vdouillet.fr> | 2021-12-05 22:40:02 +0100 |
commit | 4c42453d856053bb49affef7c165397e5c16d9eb (patch) | |
tree | 75c9cbd2aea8a39841de37ae636408b7dd428326 /05.c | |
parent | 8dafc5f3d72d9670dea971174d66a5ae006900b7 (diff) |
day 5
Diffstat (limited to '05.c')
-rw-r--r-- | 05.c | 118 |
1 files changed, 118 insertions, 0 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; +} |