#include #include #include #include #include "../../lib/aoc.h" typedef struct WireValue { char name[4]; char l[4]; char op[4]; char r[4]; bool value; bool resolved; } WireValue; typedef struct Grove { WireValue wires[400]; int wires_count; } Grove; WireValue *grove_wire_by_name(Grove *g, const char *name) { for (int i = 0; i < g->wires_count; i++) { if (strcmp(name, g->wires[i].name) == 0) return &(g->wires[i]); } return NULL; } bool grove_more_to_resolve(Grove *g) { for (int i = 0; i < g->wires_count; i++) { if (g->wires[i].resolved == false) return true; } return false; } void grove_resolve(Grove *g) { for (int i = 0; i < g->wires_count; i++) { if (g->wires[i].resolved) continue; WireValue *l, *r; l = grove_wire_by_name(g, g->wires[i].l); r = grove_wire_by_name(g, g->wires[i].r); if (l == NULL || r == NULL) printf("ERROR: BAD WIRE I GUESS\n"); if (l->resolved && r->resolved) { switch (g->wires[i].op[0]) { case 'A': g->wires[i].value = l->value && r->value; break; case 'O': g->wires[i].value = l->value || r->value; break; case 'X': g->wires[i].value = (l->value + r->value) % 2; break; } g->wires[i].resolved = true; } } } int main() { Grove g; char *line, *token; char name[4]; int value; bool done_with_init = false; while ((line = aoc_read_line()) != NULL) { if (strcmp(line, "") == 0) { done_with_init = true; continue; } if (done_with_init) { token = strtok(line, " "); strcpy(g.wires[g.wires_count].l, token); token = strtok(NULL, " "); strcpy(g.wires[g.wires_count].op, token); token = strtok(NULL, " -> "); strcpy(g.wires[g.wires_count].r, token); token = strtok(NULL, " -> "); strcpy(g.wires[g.wires_count].name, token); g.wires[g.wires_count].resolved = false; g.wires_count++; } else { sscanf(line, "%c%c%c: %d", &(name[0]), &(name[1]), &(name[2]), &value); name[3] = '\0'; strcpy(g.wires[g.wires_count].name, name); g.wires[g.wires_count].value = value; g.wires[g.wires_count].resolved = true; g.wires_count++; } } while (grove_more_to_resolve(&g)) { grove_resolve(&g); } char z[100], guy[3]; guy[2] = '\0'; int z_index; int max_z_index = 0; for (int i = 0; i < g.wires_count; i++) { if (g.wires[i].name[0] != 'z') continue; guy[0] = g.wires[i].name[1]; guy[1] = g.wires[i].name[2]; z_index = atoi(guy); z[z_index] = g.wires[i].value; if (max_z_index < z_index) max_z_index = z_index; } long answer = 0; for (int i = max_z_index; i >= 0; i--) { answer += z[i]; answer *= 2; } answer /= 2; printf("Part 1: %ld", answer); aoc_free(); exit(0); }