#include #include #include #include #define DEFAULT_FILE "input.txt" #define STRBUF_LEN 300 #define ISDIGIT(X) (X >= '0' && X <= '9') #define NUM_AS 200 #define HASHMAP_SIZE 17576 // 26 * 26 * 26 typedef struct _node { char letters[3]; int left; int right; } node; int hashnode(char *str) { bool err = false; if (str[0] < 'A' || str[0] > 'Z') err = true; if (str[1] < 'A' || str[1] > 'Z') err = true; if (str[2] < 'A' || str[2] > 'Z') err = true; if (err) { printf("Error in hashnode!"); return -1; } int first = str[0] - 'A'; int second = str[1] - 'A'; int third = str[2] - 'A'; return (first * 26 * 26) + (second * 26) + third; } bool all_zs(node *nodes, int *as, int numas) { int i = 0; for (i = 0; i < numas; i++) { int current_hash = as[i]; node current_node = nodes[current_hash]; if (current_node.letters[2] != 'Z') return false; } return true; } int count_jumps_to_zzz(char *lrbuf, int start, node *nodes) { int instructionidx = 0; int currenthash = start; int numjumps = 0; while(currenthash != HASHMAP_SIZE - 1) { if (lrbuf[instructionidx] != 'L' && lrbuf[instructionidx] != 'R') instructionidx = 0; bool is_left = lrbuf[instructionidx] == 'L'; instructionidx++; currenthash = is_left ? nodes[currenthash].left : nodes[currenthash].right; numjumps++; } return numjumps; } int count_jumps_endsin_z(char *lrbuf, int start, node *nodes) { int instructionidx = 0; int currenthash = start; int numjumps = 0; while(nodes[currenthash].letters[2] != 'Z') { if (lrbuf[instructionidx] != 'L' && lrbuf[instructionidx] != 'R') instructionidx = 0; bool is_left = lrbuf[instructionidx] == 'L'; instructionidx++; currenthash = is_left ? nodes[currenthash].left : nodes[currenthash].right; numjumps++; } return numjumps; } int count_jumps_to_cycle(char *lrbuf, int start, node *nodes) { int instructionidx = 0; int currenthash = start; int numjumps = 0; do { if (lrbuf[instructionidx] != 'L' && lrbuf[instructionidx] != 'R') instructionidx = 0; bool is_left = lrbuf[instructionidx] == 'L'; instructionidx++; currenthash = is_left ? nodes[currenthash].left : nodes[currenthash].right; numjumps++; } while(currenthash != start); return numjumps; } int main(int argc, char **argv) { // Get filename as an argument, if there is one char *path = (argc > 1) ? argv[1] : DEFAULT_FILE; if (!path) { printf("Requires input file.\n"); return 1; } FILE *file = fopen(path, "r"); char strbuf[STRBUF_LEN] = {0}; char lrbuf[STRBUF_LEN] = {0}; if (!file) { printf("Could not find file."); return 1; } // Begin Challenge node nodes[HASHMAP_SIZE]; int start_hashes[NUM_AS]; fgets(lrbuf, STRBUF_LEN, file); fgets(strbuf, STRBUF_LEN, file); while(fgets(strbuf, STRBUF_LEN, file)) { node current; int hash = hashnode(strbuf); int left = hashnode(strbuf + 7); int right = hashnode(strbuf + 12); memcpy(nodes[hash].letters, strbuf, sizeof(char) * 3); nodes[hash].left = left; nodes[hash].right = right; } int i = 0; int numas = 0; for (i = 0; i < HASHMAP_SIZE; i += 26) { if (nodes[i].letters[2] != 'A') continue; start_hashes[numas] = i; numas++; printf("Start: %c%c%c\n", nodes[i].letters[0], nodes[i].letters[1], nodes[i].letters[2]); } int instructionidx = 0; uint64_t numjumps = 0; while (!all_zs(nodes, start_hashes, numas)) { if (lrbuf[instructionidx] != 'L' && lrbuf[instructionidx] != 'R') instructionidx = 0; bool is_left = lrbuf[instructionidx] == 'L'; instructionidx++; for (i = 0; i < numas; i++) { int current_hash = start_hashes[i]; start_hashes[i] = is_left ? nodes[current_hash].left : nodes[current_hash].right; } numjumps++; } printf("Numjumps: %lu\n", numjumps); return 0; }