128 lines
2.8 KiB
C
128 lines
2.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#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);
|
|
}
|