advent-of-code

advent of code attempts
git clone git://bvnf.space/advent-of-code.git
Log | Files | Refs

commit 3a2917331f01b49f9c3950b1458b1c6f0f53838f
parent 6998e1ac8e3a02cbcbd1ab5b2995c02cb3877c7f
Author: aabacchus <ben@bvnf.space>
Date:   Mon, 12 Dec 2022 20:48:26 +0000

22.12 in C

Diffstat:
A2022/12/a.c | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2022/12/example | 5+++++
A2022/12/input | 41+++++++++++++++++++++++++++++++++++++++++
3 files changed, 251 insertions(+), 0 deletions(-)

diff --git a/2022/12/a.c b/2022/12/a.c @@ -0,0 +1,205 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#define HEIGHT 41//5 +#define WIDTH 171//8 + +struct point { + int x, y; +}; + +struct nodel { + int dist; + struct point p; + struct nodel *next; +}; + +struct nodel *nodetop = NULL; +int grid[HEIGHT][WIDTH] = {0}; + +/* insert a node for dist and p so that nodetop is sorted */ +void +node_push(int dist, struct point p) { + struct nodel *n = malloc(sizeof(struct nodel)); + if (n == NULL) { + perror("malloc"); + exit(1); + } + n->dist = dist; + n->p.x = p.x; + n->p.y = p.y; + + struct nodel *t = nodetop; + if (t == NULL || t->dist < dist) { + n->next = t; + nodetop = n; + return; + } + for (; t != NULL; t = t->next) { + /* If anyone ever reads this, can you explain why part 2 requires `>=` and not `>`? Please tell me! */ + if (t->next == NULL || t->next->dist >= dist) { + n->next = t->next; + t->next = n; + break; + } + } +} + +struct nodel * +node_pop(void) { + struct nodel *n = nodetop; + if (n != NULL) + nodetop = n->next; + return n; +} + +void +push_if_valid(int dist, int x, int y, int curheight, char partB) { + if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) + return; + struct point p = {x, y}; + if (partB == 0) { + if (grid[y][x] <= curheight + 1) + node_push(dist, p); + } else { + if (curheight <= grid[y][x] + 1) + node_push(dist, p); + } +} + +int +main(int argc, char **argv) { + char *buf = NULL; + size_t buflen = 0; + ssize_t n; + FILE *f; + struct point start, end; + + int visited[HEIGHT][WIDTH] = {0}; + + nodetop = NULL; + + if (argc != 2) { + fprintf(stderr, "usage: %s input\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "r"); + if (f == NULL) { + perror(argv[1]); + return 1; + } + + size_t row = 0; + while ((n = getline(&buf, &buflen, f)) != -1) { + if (buf[n - 1] == '\n') { + buf[n - 1] = '\0'; + n--; + } + assert(n == WIDTH); + for (ssize_t i = 0; i < n; i++) { + switch (buf[i]) { + case 'S': + start.x = i; + start.y = row; + buf[i] = 'a'; + break; + case 'E': + end.x = i; + end.y = row; + buf[i] = 'z'; + break; + } + grid[row][i] = buf[i] - 'a'; + } + row++; + } + + free(buf); + fclose(f); + + printf("start at (%d,%d)\nend at (%d,%d)\n", start.x, start.y, end.x, end.y); + + for (int i = 0; i < HEIGHT; i++) { + for (int j = 0; j < WIDTH; j++) + printf("%c", grid[i][j] + 'a'); + printf("\n"); + } + + node_push(0, start); + struct nodel *endpath; + + while (1) { + struct nodel *n = node_pop(); + if (n == NULL) { + fprintf(stderr, "reached end of node list.\n"); + exit(1); + } + if (visited[n->p.y][n->p.x]) { + goto cont; + } + visited[n->p.y][n->p.x] = 1; + //fprintf(stderr, "%d,%d = %d\n", n->p.x, n->p.y, n->dist); + + if (n->p.x == end.x && n->p.y == end.y) { + endpath = n; + break; + } + + int curheight = grid[n->p.y][n->p.x]; + push_if_valid(n->dist + 1, n->p.x - 1, n->p.y, curheight, 0); + push_if_valid(n->dist + 1, n->p.x + 1, n->p.y, curheight, 0); + push_if_valid(n->dist + 1, n->p.x, n->p.y - 1, curheight, 0); + push_if_valid(n->dist + 1, n->p.x, n->p.y + 1, curheight, 0); + +cont: + free(n); + } + + printf("Part A: %d\n", endpath->dist); + free(endpath); + + /* reset for part B */ + while (node_pop() != NULL) ; + for (int y = 0; y < HEIGHT; y++) + for (int x = 0; x < WIDTH; x++) + visited[y][x] = 0; + nodetop = NULL; + + /* This time start from the end and find the closest point of elevation a */ + /* Have to reverse the neighbour selection rule so that going from lowest + * to end will still be possible. */ + node_push(0, end); + while (1) { + struct nodel *n = node_pop(); + if (n == NULL) { + fprintf(stderr, "reached end of node list.\n"); + exit(1); + } + if (visited[n->p.y][n->p.x]) { + goto contB; + } + visited[n->p.y][n->p.x] = 1; + //fprintf(stderr, "%d,%d = %d\n", n->p.x, n->p.y, n->dist); + + int curheight = grid[n->p.y][n->p.x]; + if (curheight == 0) { + endpath = n; + break; + } + + push_if_valid(n->dist + 1, n->p.x - 1, n->p.y, curheight, 1); + push_if_valid(n->dist + 1, n->p.x + 1, n->p.y, curheight, 1); + push_if_valid(n->dist + 1, n->p.x, n->p.y - 1, curheight, 1); + push_if_valid(n->dist + 1, n->p.x, n->p.y + 1, curheight, 1); + +contB: + free(n); + } + + printf("Part B: %d (%d,%d)\n", endpath->dist, endpath->p.x, endpath->p.y); + free(endpath); + + return 0; +} diff --git a/2022/12/example b/2022/12/example @@ -0,0 +1,5 @@ +Sabqponm +abcryxxl +accszExk +acctuvwj +abdefghi diff --git a/2022/12/input b/2022/12/input @@ -0,0 +1,41 @@ +abcccccaaaaaacccaaaccaaaaaaaacccaaaaaaccccccccccccccccccccccccccccaaaaaaaaaaaaaacacccccccccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccaaaaa +abcccccaaaaaaaacaaaaccaaaaaaccccaaaaaaccccccccccaaacccccccccccccccaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccaaaaaaaaaccccccaaaccccccccccccccccccccccccccccccccccaaaaaa +abccccaaaaaaaaacaaaaccaaaaaaccccaaaaaaaaccccccccaaaccccccccccccccccaaaaaaaaaaaaaaccccaaaccccccccccccccccccccccccccaaaaaaaaccccacaaaccccccccccccccccaaccccccccccccccccaaaaaa +abcccaaaaaaaaaacaaaccaaaaaaaacccccaaccaaacaaccccaaaaaaaccccccccccccaacaaaaaaaaaccccccaaaaccccccccccccccccccccaaacaaaaaaccccccaaaaaaaacccccccccccccaaaacccccccccccccccaaacaa +abcccaaacaaaccccccccaaaaaaaaaaccccccccaaaaaacaaaaaaaaaaccccccccccccccaaaaaaaaaaccccccaaaaccccccccccccccccaaccaaacaaaaaaacccccaaaaaaaacccccccccccccaaaaccaaaccccccccccccccaa +abcccccccaaaccccccccaaaaaaaaaaccccccaaaaaaaccaaaaaaaaacccccccccccccccaaaacaaaaaaaacccaaaaccccccccccccccccaaaaaaacaaccaaacccccccaaaaacccccccccccccccaaaaaaaaacccccccccccccaa +abcccccccaacccccccccacaaaaaccaccccccaaaaaaacccaaaaaaaccccccaaacccccccaacacaaaaaaaacccccccccccccccccccccccaaaaaaccccccaaaccccccaaaaaccccccccccccjjkkaaaaaaaacccccccccccccccc +abaccccccccccccccccccccaaaacccccccccccaaaaaaccccaaaaaaccccaaaacccccccccccccaaaaaaccccccccccaccaaccccccccccaaaaaaaaccccccccccccaaaaaaccccccccccjjjkkkkkaaaaccccccccaaccccccc +abaccccccccaaaccccccccccaaccccccccccccaacaaacccaaaaaaaccccaaaacccccccccccccaaaaaaccccccccccaaaaacccccccccaaaaaaaaaccccccccccccaccaaacccccccccjjjjkkkkkkkaacccccccccaccccccc +abaacccccccaaaaccccccccccaaaccccccccccaacccccccaaaacaaccccaaaacccccccccccccaaaaaacccccccccccaaaaaccccccccaaaaaaaacccccccaaccccccccccccccccccjjjjoooookkkkkllllllccccaaacccc +abaacccccccaaaaccccccccccaaaaccccccccccccccccccaacaaacaaaccccccccccaaccccccaaacaaccccccccccaaaaaacccccccaaaaaaaccccccccaaaacccccccccccccccccjjjoooooopkkkklllllllccccaacccc +abaccccccccaaacccccccccccaaaacccccccccccccccccccccaaaaaaacccccccccaaaccccccccccccccccccccccaaaaccccccaaaccccaaaccccccccaaaacccccccccccccccccjjooooooopppklppplllllcccaccccc +abacccaaaaaccccccccccccccaaaccccccccccccccccccccccaaaaaaccccccaaaaaaaccccccccccccccccccccccccaaacccccaaacacccaaccccccccaaaaccccccccccccccccjjjooouuuupppppppppplllcccaccccc +abccccaaaaacccccccccccccccccccccccccccccccccccccaaaaaaaaccccccaaaaaaaaaaccaacccccccccccccccccccccccaacaaaaaccccccccccccccccaaacccccaccaccccjjjoouuuuuupppppppppllllccaccccc +abcccaaaaaacccccccccccccaaccccccaaacccccccccccccaaaaaaaaaccccccaaaaaaaaacaaaaccccccccccccccccccccccaaaaaaaaccccccccccccacccaaccccccaaaacccjjjjoouuuuuuupuuuvvpqqlllccaccccc +abcccaaaaaaccccccccccccaaacaacccaaaaacccccccccccaaaaaaaaaaccccccaaaaaaaccaaaacccccccccccccccccccccccaaaaaccccccccccccccaaaaaaacccccaaaaaccijjooouuuxxxuuuuvvvqqqlmccccccccc +abcccaaaaaaccccaacccccccaaaaaccaaaaaccccccccccccaaaaaacaaacccccaaaaaaccccaaaacccccccccccccccccccaaaccaaaaaccccaaaccccccaaaaaaaacccaaaaaaciiiinootuxxxxuuyyyvvqqqmmccccccccc +abcccacaacccccaaacaaccaaaaaacccaaaaaccccccccccccaaaaaacccccccccaaaaaaaccccccccccccaaccacccccccccaaacaaacaaccaaaaaccccccaaaaaaaaaccaaaaaaiiinnnnnttxxxxxyyyyvvqqqmmdddcccccc +abcccaaacaaacccaaaaaccaaaaaaaaccaaaaacccccccccccaaacaaaccccccccaaccaaaccccccccccccaaaaaccccccaaaaaaaaaacccccaaaaaacccccaaaaaaaaaccccaaciiinnnnttttxxxxxyyyyvvqqmmmdddcccccc +abcccaaaaaaacaaaaaacccaacaaaaaccaacccccccccccaaaaaaaaaaaccccccccccccaacccccccccccaaaaacccccccaaaaaaaacccccccaaaaaacccccaaaaaaaaccccccciiinnnnttttxxxxxyyyyvvqqqmmmdddcccccc +SbcccaaaaaaccaaaaaaaaccccaacccccccccccaacccccaaaaaaaaaaccccccccccccccccccccccccccaaaaaaccccccccaaaaaccccccccaaaaacccccaaaaaaaccccccccciiinnntttxxxEzzzzyyvvvqqqmmmdddcccccc +abccaaaaaaaacaacaaaaacccaaccccccccccccaaacccccaaaaaaaaaaaccccccccccccccccccccccccccaaaacccccccaaaaaaccccccccaaaaaccccccacaaaaccccccccciiinnntttxxxxxyyyyyyvvvqqmmmdddcccccc +abcaaaaaaaaaacccaacccccaacccccccccacacaaaccccccaaaaaaaaaacccccccccccccccccccccacccaaccccccccccaaaaaaccccccccccccccccccccaaaaaccccccccciiinnntttxxxxyyyyyyyyvvvqqmmmdddccccc +abcaaaaaaaaaaccaaccaaaaaacccccccccaaaaaaaaaacccaaaaaaaaaacaaccccccccccccaaaaaaaaccccccccccccccaccaaaccccccccccccccccaaacaaacccccccccaaiiinnnttttxxwwyyyyyyyvvvqqmmmdddccccc +abaaccaaacaaaccccccaaaaaaaccccccccaaaaaaaaaacccaaaaaaaacccaaaccccccccccccaaaaaacccccccccccccccccccccccccccccccccccccaaaaaaaaaacccaaaachhhnnnntttsswwyywwwwwvvvrrqkmdddccccc +abaaacaaacccccccccccaaaaaaacccccccccaaaaaacccccaacccaaacccaaaaaaaccccccccaaaaaaccccccccccccccaaccccccccccccccccccccccaaaaaaaaacccaaaaaahhhmmmmmsssswwywwwwwwvrrrrkkdddccccc +abaaaaaaacccccccccccaaaaaaacccccccccaaaaaaccccccaaccccccaaaaaaaaccccccccaaaaaaaaccccccccaaccaaaccccccccccccccccaacccccaaaaaaacccccaaaaahhhhhmmmmssswwwwwrrrrrrrrkkkeeeccccc +abcaaaaaaccccccccccaaaaaacccccccccccaaaaaacccccaaaaccccaaaaaaaaacccccccaaaaaaaaaacccccccaaacaaacccccccccccccacaaaccccaaaaaaccccccaaaaacchhhhhmmmmsswwwwrrrrrrrrrkkkeeeccccc +abaaaaaacccccccccccaaaaaaccccccccccaaaaaaaaccccaaaaccccaaaaaaaaccccccccaaaaaaaaaacaaacccaaaaaaccccccaacccccaaaaaccaccaaaaaaacccccaccaacccchhhhmmmssswwsrrrrrrrkkkkkeeeccccc +abaaaaaaaccccccccaaccccaaccccccccccaaaaaaacccccaaaacccccccaaaaaacccaaccacaaaaaccccaaaccccaaaaaaaaaacaaaccccaaaaaaaaccaaacaaaccccccccccccccchhhhmmssssssrlllkkkkkkkeeecccccc +abaaaaaaaaccccccaaacaacccccccccccccaaaaaaaaccccccccccccccaaaaaaacccaacccccaaaaccccaaaaaaaaaaaaaaaaaaaacccccccaaaaaccccccccaaaacccccccccccccchhgmmmsssssllllkkkkkeeeeeaacccc +abcaaacaaacccccccaaaaaccccccccccccaaaaaaaaaccccccccccccccaaaccaaaaaaaaaacccaaccaaaaaaaaaaaaaaaaacaaaaaaaccccaaaaacccccccaaaaaacccccccccccccccggmmmlssslllllffeeeeeeeaaacccc +abcaaacccccccccaaaaaacccccccaaacaaacaaaaaaacccccccccccccaaaaccccaaaaaaaacccccccaaaaaaaaaaaaaaaccaaaaaaaaccccaacaacccccccaaaaaacccccccccccccccgggmmlllllllfffffeeeeaaaaacccc +abcaaccccccccccaaaaaaaacccccaaaaaaaaaaaaaccccccccccccccccaaaacccccaaaacccccaacccaaaaaaaccccaaaccaaaaaaaacccccccaaccccccccaaaaaaaccccccccccccccggglllllllffffffecacaaacccccc +abcccccccccaaccaacaaaaaccccccaaaaaaaaaaaaccccccaaccaaccaaaaaaccccaaaaaccccaaccccccaaaaaacccaaaccaacaaaccaaaacccccccccccccaaaaaaaccccccccccccccggggllllfffffcccccccaaacccccc +abcccccccaaaaaaccaaacccccccccaaaaaaaaccaaacccccaaaaaaccaaaaacccccaaaaaacccaaaccaaaaaaaaacccccccccccaaaccaaaaacccccccccccaaaaaaaaaccaaccccccccccggggggfffffccccccccccccccccc +abcaaccccaaaaaaccaaccccccccaaaaaaaaaacccaacccccaaaaaccccaaaaaccccacccaaccaaaaccaaaaaccaacccccccccccccccaaaaaacccccccaaacaaaaaaaaaaaaacccccccccccgggggfffaacccccccccccccaccc +abaaaccccaaaaaaccccccccaaacaaaaaaaaaaaaaaaaaaccaaaaaacccaaccacccccccaaaaaaaaaaaaaaaccccccccccccccaaaaccaaaaaacccccccaaaaaaaaaacaaaaaaccccccccccccagggfcaaaccccccccccccaaaaa +abaaaacccaaaaaccccccccaaaacaaacaaacccaaaaaaaacaaaaaaaaccccccccccccccaaaaaaaaaaaaaaacccccccccccccaaaaacccaaaaaccccccccaaaaaacaaaaaaaaccccccccccccccaccccaaacccccccccccccaaaa +abaaaaccccaaaaccccccccaaaacccccaaacccccaaaacccaaaaaaaacccccccccccccccaaaaaaaaaaaaaacccccccccccccaaaaaaccaaaccccccccccaaaaaaaaaaaaaaaaccccccccccccccccccccacccccccccccccaaaa +abaacccccccccccccccccccaaacccccaacccccaaaaaacccccaacccccccccccccccccccccaaaaaaaaacccccccccccccccaaaaaacccccccccccccaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccaaaaaa