From 0d10e42415d7f3f9bdc219cc0bab59508d64e64f Mon Sep 17 00:00:00 2001 From: Akuli Date: Mon, 11 Dec 2023 18:22:38 +0200 Subject: [PATCH] day 11 --- examples/aoc2023/day11/part1.jou | 86 ++++++++++++++++++++++++ examples/aoc2023/day11/part2.jou | 92 ++++++++++++++++++++++++++ examples/aoc2023/day11/sampleinput.txt | 10 +++ 3 files changed, 188 insertions(+) create mode 100644 examples/aoc2023/day11/part1.jou create mode 100644 examples/aoc2023/day11/part2.jou create mode 100644 examples/aoc2023/day11/sampleinput.txt diff --git a/examples/aoc2023/day11/part1.jou b/examples/aoc2023/day11/part1.jou new file mode 100644 index 00000000..ea39cd6f --- /dev/null +++ b/examples/aoc2023/day11/part1.jou @@ -0,0 +1,86 @@ +import "stdlib/io.jou" +import "stdlib/mem.jou" +import "stdlib/str.jou" +import "stdlib/math.jou" + + +class Input: + width: int + height: int + data: byte* + + def duplicate_blank_lines(self) -> None: + self->data = realloc(self->data, 2*strlen(self->data) + 1) + assert self->data != NULL + + y = 0 + while y < self->height: + if strspn(&self->data[(self->width + 1)*y], ".") == self->width: + # duplicate row + blank_start = &self->data[(self->width + 1)*y] + next_start = &self->data[(self->width + 1)*(y+1)] + memmove(next_start, blank_start, strlen(blank_start) + 1) + y += 2 + self->height++ + else: + y++ + + def transpose(self) -> None: + old_content = strdup(self->data) + old_width = self->width + old_height = self->height + self->width = old_height + self->height = old_width + + memset(self->data, '\n', strlen(self->data)) + for x = 0; x < self->width; x++: + for y = 0; y < self->height; y++: + self->data[(self->width + 1)*y + x] = old_content[(old_width + 1)*x + y] + + free(old_content) + + # array is terminated by [-1, -1] + def get_hashtag_coords(self) -> int[2]*: + result: int[2]* = malloc(sizeof(result[0]) * (self->width * self->height + 1)) + result_len = 0 + for y = 0; y < self->height; y++: + for x = 0; x < self->width; x++: + if self->data[(self->width + 1)*y + x] == '#': + result[result_len++] = [x, y] + + result[result_len] = [-1, -1] + return result + + +def manhattan_distance(a: int[2], b: int[2]) -> int: + return abs(a[0]-b[0]) + abs(a[1]-b[1]) + + +def main() -> int: + max_len = 100000 + input = Input{data = calloc(1, max_len+1)} + + f = fopen("sampleinput.txt", "r") + assert f != NULL + fread(input.data, 1, max_len, f) + fclose(f) + + input.width = strcspn(input.data, "\n") as int + input.height = (strlen(input.data) as int) / (input.width + 1) + + input.duplicate_blank_lines() + input.transpose() + input.duplicate_blank_lines() + input.transpose() + + coords = input.get_hashtag_coords() + + sum = 0 + for i = 0; coords[i][0] != -1; i++: + for k = 0; k < i; k++: + sum += manhattan_distance(coords[i], coords[k]) + printf("%d\n", sum) # Output: 374 + + free(input.data) + free(coords) + return 0 diff --git a/examples/aoc2023/day11/part2.jou b/examples/aoc2023/day11/part2.jou new file mode 100644 index 00000000..b05ace4b --- /dev/null +++ b/examples/aoc2023/day11/part2.jou @@ -0,0 +1,92 @@ +import "stdlib/io.jou" +import "stdlib/mem.jou" +import "stdlib/str.jou" + + +class Input: + width: int + height: int + data: byte* + + # returned array is terminated by -1 + def find_blank_lines(self) -> int*: + result: int* = malloc(sizeof(result[0]) * (self->height + 1)) + result_len = 0 + + for y = 0; y < self->height; y++: + if strspn(&self->data[(self->width + 1)*y], ".") == self->width: + result[result_len++] = y + result[result_len] = -1 + return result + + def transpose(self) -> None: + old_content = strdup(self->data) + old_width = self->width + old_height = self->height + self->width = old_height + self->height = old_width + + memset(self->data, '\n', strlen(self->data)) + for x = 0; x < self->width; x++: + for y = 0; y < self->height; y++: + self->data[(self->width + 1)*y + x] = old_content[(old_width + 1)*x + y] + + free(old_content) + + # returned array is terminated by -1 + def get_hashtag_y_coords(self) -> int*: + result: int* = malloc(sizeof(result[0]) * (self->width * self->height + 1)) + result_len = 0 + for y = 0; y < self->height; y++: + for x = 0; x < self->width; x++: + if self->data[(self->width + 1)*y + x] == '#': + result[result_len++] = y + + result[result_len] = -1 + return result + + +def sum_vertical_distances(input: Input*) -> long: + hashtag_y_coords = input->get_hashtag_y_coords() + blank_lines = input->find_blank_lines() + + result = 0L + for end = hashtag_y_coords; *end != -1; end++: + for start = hashtag_y_coords; start < end; start++: + for y = *start; y < *end; y++: + y_is_blank = False + for p = blank_lines; *p != -1; p++: + if *p == y: + y_is_blank = True + break + if y_is_blank: + # Change to 1000000 for actual input + result += 100 + #result += 1000000 + else: + result += 1 + + free(hashtag_y_coords) + free(blank_lines) + return result + + +def main() -> int: + max_len = 100000 + input = Input{data = calloc(1, max_len+1)} + + f = fopen("sampleinput.txt", "r") + assert f != NULL + fread(input.data, 1, max_len, f) + fclose(f) + + input.width = strcspn(input.data, "\n") as int + input.height = (strlen(input.data) as int) / (input.width + 1) + + result = sum_vertical_distances(&input) + input.transpose() + result += sum_vertical_distances(&input) + printf("%lld\n", result) # Output: 8410 + + free(input.data) + return 0 diff --git a/examples/aoc2023/day11/sampleinput.txt b/examples/aoc2023/day11/sampleinput.txt new file mode 100644 index 00000000..986aad4a --- /dev/null +++ b/examples/aoc2023/day11/sampleinput.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#.....