From 20a1adf5115bd988ac54052519bf024c398741d0 Mon Sep 17 00:00:00 2001 From: dobiadi Date: Sun, 22 Dec 2024 17:41:25 +0100 Subject: [PATCH] Day21 --- day21/c/day21 | Bin 0 -> 27728 bytes day21/c/day21.c | 421 +++++++++++++++++++++++++++++++++++++++++++++++ day21/input.txt | 5 + day21/sample.txt | 5 + 4 files changed, 431 insertions(+) create mode 100755 day21/c/day21 create mode 100644 day21/c/day21.c create mode 100644 day21/input.txt create mode 100644 day21/sample.txt diff --git a/day21/c/day21 b/day21/c/day21 new file mode 100755 index 0000000000000000000000000000000000000000..860112d59ea4056051c9b48b35ea25c41ca22b0b GIT binary patch literal 27728 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 kdb;ljL3KIlmYJ$J<=U?1r56E4lmBOr +#include +#include +#include + +#define CODE_LEN 4 +#define CODES 5 +#define CODE_MAX_LEN 16*1024 +#define sgn(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : 0)) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define abs(a) ((a) < 0 ? -(a) : (a)) + +typedef enum { + NUMERIC, + DIRECTIONAL +} panel_type; + +typedef struct node { + struct node *children[11]; + uint64_t value; + uint64_t value2; + char key; + uint8_t is_leaf; +} node_t; + + +typedef struct layer { + panel_type type; + struct layer *next_layer; + int current_position[2]; + int id; + node_t *trie; +} layer_t; + +const int numeric_panel[][2] = { + {3, 1}, // 0 + {2, 0}, // 1 + {2, 1}, // 2 + {2, 2}, // 3 + {1, 0}, // 4 + {1, 1}, // 5 + {1, 2}, // 6 + {0, 0}, // 7 + {0, 1}, // 8 + {0, 2}, // 9 + {3, 2}, // A +}; + +const int directional_panel[][2] = { + {0, 1}, // UP + {1, 0}, // LEFT + {1, 1}, // DOWN + {1, 2}, // RIGHT + {0, 2}, // A +}; + +#define UP 0 +#define LEFT 1 +#define DOWN 2 +#define RIGHT 3 + +#define d2c(a) ((a) == UP ? '^' : ((a) == LEFT ? '<' : ((a) == DOWN ? 'v' : ((a) == RIGHT ? '>' : 'A')))) + +layer_t* create_numeric_layer() { + layer_t *layer = calloc(1, sizeof(layer[0])); + layer->type = NUMERIC; + layer->next_layer = NULL; + layer->current_position[0] = numeric_panel[10][0]; + layer->current_position[1] = numeric_panel[10][1]; + layer->trie = calloc(1, sizeof(node_t)); + return layer; +} + +layer_t* create_directional_layer() { + layer_t *layer = calloc(1, sizeof(layer[0])); + layer->type = DIRECTIONAL; + layer->next_layer = NULL; + layer->current_position[0] = directional_panel[4][0]; + layer->current_position[1] = directional_panel[4][1]; + layer->trie = calloc(1, sizeof(node_t)); + return layer; +} + +int c2n(char code) { + if (code == 'A') { + return 10; + } + + return code - 48; +} + +node_t* create_node() { + node_t *node = calloc(1, sizeof(node[0])); + return node; +} + +node_t* search(node_t* root, int* word, int len) { + node_t* node = root; + for (int i = 0; i < len; i++) { + if (node->children[word[i]] == NULL) { + return NULL; + } + node = node->children[word[i]]; + } + return node; +} + +void insert(node_t* root, int* word, int len, uint64_t value, int value2) { + node_t* node = root; + for (int i = 0; i < len; i++) { + if (node->children[word[i]] == NULL) { + node->children[word[i]] = create_node(); + } + node = node->children[word[i]]; + } + node->value = value; + node->value2 = value2; + node->is_leaf = 1; +} + +void free_node(node_t* node) { + for (int i = 0; i < 11; i++) { + if (node->children[i] != NULL) { + free_node(node->children[i]); + } + } + + free(node); +} + +uint64_t process_layer(layer_t *layer, int *code, uint64_t code_len, int *new_code, uint64_t new_code_len); +uint64_t process_layer2(layer_t *layer, int* code, uint64_t code_len); +int coords_to_idx(layer_t *layer, int coords[2]); +uint64_t cost_of_activation(layer_t *layer, int button); + +int main() { + char c; + + char codes[CODES][CODE_LEN]; + int code_count = 0, character_count = 0; + + while ((c = getchar()) != EOF) { + codes[code_count][character_count++] = c; + if (c != '\n') { + continue; + } + character_count = 0; + code_count++; + } + + // Create Layers + layer_t **layers = calloc(26, sizeof(layer_t*)); + // First is the numeric panel + layers[0] = create_numeric_layer(); + layers[0]->id = 0; + // Create directional layers + for (int i = 1; i < 26; i++) { + layers[i] = create_directional_layer(); + layers[i]->id = i; + } + // Link layers + for (int i = 0; i < 25; i++) { + layers[i]->next_layer = layers[i+1]; + } + + uint64_t sum = 0; + for (int i = 0; i < code_count; i++) { + // Convert code chars to int + int code_encoded[4]; + for (int j = 0; j < 4; j++) { + code_encoded[j] = c2n(codes[i][j]); + } + + int *ccode = calloc(CODE_MAX_LEN, sizeof(ccode[0])); + //uint64_t a = process_layer(layers[0], code_encoded, 4, ccode, 0); + int code_encoded2[5]; + for (int j = 0; j < 4; j++) { + code_encoded2[j+1] = c2n(codes[i][j]); + } + code_encoded2[0] = 10; + uint64_t a = process_layer2(layers[0], code_encoded2, 5); + free(ccode); + int b; + sscanf(codes[i], "%d", &b); + sum += a * (uint64_t)b; + } + printf("%lu\n", sum); + + for (int i = 0; i < 26; i++) { + free_node(layers[i]->trie); + free(layers[i]); + } + free(layers); +} + +uint64_t process_layer(layer_t *layer, int *code, uint64_t code_len, int *new_code, uint64_t new_code_len) { + if (code_len == 0) { + if (layer->next_layer == NULL) { + return new_code_len; + } + int *ccode = calloc(CODE_MAX_LEN, sizeof(ccode[0])); + uint64_t result = process_layer(layer->next_layer, new_code, new_code_len, ccode, 0); + free(ccode); + return result; + } + + int current_position[2]; + current_position[0] = layer->current_position[0]; + current_position[1] = layer->current_position[1]; + + int (*panel)[2] = layer->type == NUMERIC ? numeric_panel : directional_panel; + // Check if we are on the right button + if (current_position[0] == panel[code[0]][0] && current_position[1] == panel[code[0]][1]) { + // Click button + new_code[new_code_len] = 4; + return process_layer(layer, code + 1, code_len - 1, new_code, new_code_len+1); + } + + uint64_t ncl = new_code_len; + uint64_t value1 = UINT64_MAX, value2 = UINT64_MAX; + // Try going in each direction towards the next button + if (current_position[0] != panel[code[0]][0]) { + // Up or down + if (current_position[0] - panel[code[0]][0] > 0) { + for (int i = 0; i < current_position[0] - panel[code[0]][0]; i++) { + new_code[new_code_len++] = UP; + } + } else { + for (int i = 0; i < panel[code[0]][0] - current_position[0]; i++) { + new_code[new_code_len++] = DOWN; + } + } + layer->current_position[0] = panel[code[0]][0]; + // Cannot go to empty space + if ((layer->type == NUMERIC && layer->current_position[0] == 3 && layer->current_position[1] == 0) || (layer->type == DIRECTIONAL && layer->current_position[0] == 0 && layer->current_position[1] == 0)) { + } else { + value1 = process_layer(layer, code, code_len, new_code, new_code_len); + } + } + layer->current_position[0] = current_position[0]; + layer->current_position[1] = current_position[1]; + new_code_len = ncl; + + if (current_position[1] != panel[code[0]][1]) { + // Up or down + if (current_position[1] - panel[code[0]][1] > 0) { + for (int i = 0; i < current_position[1] - panel[code[0]][1]; i++) { + new_code[new_code_len++] = LEFT; + } + } else { + for (int i = 0; i < panel[code[0]][1] - current_position[1]; i++) { + new_code[new_code_len++] = RIGHT; + } + } + layer->current_position[1] = panel[code[0]][1]; + // Cannot go to empty space + if ((layer->type == NUMERIC && layer->current_position[0] == 3 && layer->current_position[1] == 0) || (layer->type == DIRECTIONAL && layer->current_position[0] == 0 && layer->current_position[1] == 0)) { + } else { + value2 = process_layer(layer, code, code_len, new_code, new_code_len); + } + } + layer->current_position[0] = current_position[0]; + layer->current_position[1] = current_position[1]; + + + uint64_t value = min(value1, value2); + + return value; +} + +uint64_t process_layer2(layer_t *layer, int* code, uint64_t code_len) { + uint64_t sum = 0; + if (layer == NULL) { + return 1; + } + int (*panel)[2] = layer->type == NUMERIC ? numeric_panel : directional_panel; + int current_position[2]; + int button_count = layer->type == NUMERIC ? 11 : 5; + + // Build cache for each combination + if (layer->trie->children[0] == NULL) { + for (int i = 0; i < button_count; i++) { + for (int j = 0; j < button_count; j++) { + int combination[2] = {i, j}; + int start1[2] = {panel[i][0], panel[i][1]}; + int start2[2] = {panel[i][0], panel[i][1]}; + int end[2] = {panel[j][0], panel[j][1]}; + + int last_action1 = 4; + // X first, Y second + uint64_t distance1 = 0; + while (start1[0] != end[0]) { + int dir = sgn(end[0] - start1[0]); + start1[0] += dir; + if ((layer->type == NUMERIC && start1[0] == 3 && start1[1] == 0) || (layer->type == DIRECTIONAL && start1[0] == 0 && start1[1] == 0)) { + distance1 = UINT64_MAX; + break; + } + int subcombination[2]; + subcombination[0] = last_action1; + if (dir == -1) { + subcombination[1] = UP; + last_action1 = UP; + } else { + subcombination[1] = DOWN; + last_action1 = DOWN; + } + distance1 += process_layer2(layer->next_layer, subcombination, 2); + } + if (distance1 != UINT64_MAX) { + while (start1[1] != end[1]) { + int dir = sgn(end[1] - start1[1]); + start1[1] += dir; + int subcombination[2]; + subcombination[0] = last_action1; + if (dir == -1) { + subcombination[1] = LEFT; + last_action1 = LEFT; + } else { + subcombination[1] = RIGHT; + last_action1 = RIGHT; + } + distance1 += process_layer2(layer->next_layer, subcombination, 2); + } + } + if (distance1 != UINT64_MAX) { + int activatecombination[2] = {last_action1, 4}; + distance1 += process_layer2(layer->next_layer, activatecombination, 2); + } + + int last_action2 = 4; + // Y first, X second + uint64_t distance2 = 0; + while (start2[1] != end[1]) { + int dir = sgn(end[1] - start2[1]); + start2[1] += dir; + if ((layer->type == NUMERIC && start2[0] == 3 && start2[1] == 0) || (layer->type == DIRECTIONAL && start2[0] == 0 && start2[1] == 0)) { + distance2 = UINT64_MAX; + break; + } + int subcombination[2]; + subcombination[0] = last_action2; + if (dir == -1) { + subcombination[1] = LEFT; + last_action2 = LEFT; + } else { + subcombination[1] = RIGHT; + last_action2 = RIGHT; + } + distance2 += process_layer2(layer->next_layer, subcombination, 2); + } + if (distance2 != UINT64_MAX) { + while (start2[0] != end[0]) { + int dir = sgn(end[0] - start2[0]); + start2[0] += dir; + int subcombination[2]; + subcombination[0] = last_action2; + if (dir == -1) { + subcombination[1] = UP; + last_action2 = UP; + } else { + subcombination[1] = DOWN; + last_action2 = DOWN; + } + distance2 += process_layer2(layer->next_layer, subcombination, 2); + } + } + if (distance2 != UINT64_MAX) { + int activatecombination[2] = {last_action2, 4}; + distance2 += process_layer2(layer->next_layer, activatecombination, 2); + } + + uint64_t distance = distance1; + int last_action = last_action1; + if (distance1 > distance2) { + distance = distance2; + last_action = last_action2; + } + + //printf("Layer %i: cost from %i to %i is %lu\n", layer->id, i, j, distance); + insert(layer->trie, combination, 2, distance, last_action); + } + } + } + + for (uint64_t i = 1; i < code_len; i++) { + int combination[2] = {code[i-1], code[i]}; + node_t *node = search(layer->trie, combination, 2); + sum += node->value; + } + + return sum; +} + +int coords_to_idx(layer_t *layer, int coords[2]) { + int idx; + int (*panel)[2] = layer->type == NUMERIC ? numeric_panel : directional_panel; + for (idx = 0; idx < (layer->type == NUMERIC ? 11 : 5); idx++) { + if (coords[0] == panel[idx][0] && coords[1] == panel[idx][1]) { + break; + } + } + + return idx; +} + +uint64_t cost_of_activation(layer_t *layer, int button) { + if (layer == NULL) { + return 1; + } + + // Build cache if not present + if (layer->trie->children[0] == NULL) { + process_layer2(layer, NULL, 0); + } + + int combination[2] = {button, 4}; + node_t *node = search(layer->trie, combination, 2); + + return node->value + cost_of_activation(layer->next_layer, node->value2); +} diff --git a/day21/input.txt b/day21/input.txt new file mode 100644 index 0000000..89a734f --- /dev/null +++ b/day21/input.txt @@ -0,0 +1,5 @@ +279A +286A +508A +463A +246A diff --git a/day21/sample.txt b/day21/sample.txt new file mode 100644 index 0000000..4cf0c29 --- /dev/null +++ b/day21/sample.txt @@ -0,0 +1,5 @@ +029A +980A +179A +456A +379A