Day23
This commit is contained in:
BIN
day23/c/day23
Executable file
BIN
day23/c/day23
Executable file
Binary file not shown.
199
day23/c/day23.c
Normal file
199
day23/c/day23.c
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define CHARS_MAX 6
|
||||||
|
#define MAX_LINKS 16*1024
|
||||||
|
#define MAX_NODES 8*1024
|
||||||
|
|
||||||
|
typedef struct link {
|
||||||
|
char left[2];
|
||||||
|
char right[2];
|
||||||
|
} link_t;
|
||||||
|
|
||||||
|
int cmp(const void* a, const void* b) {
|
||||||
|
const char (*pa)[2] = a;
|
||||||
|
const char (*pb)[2] = b;
|
||||||
|
|
||||||
|
if ((*pa)[0] != (*pb)[0]) {
|
||||||
|
return (*pa)[0] - (*pb)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*pa)[1] - (*pb)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char *p, *buf, c;
|
||||||
|
|
||||||
|
buf = calloc(CHARS_MAX, sizeof(char));
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
link_t *links = calloc(MAX_LINKS, sizeof(link_t));
|
||||||
|
int link_count = 0;
|
||||||
|
|
||||||
|
while ((c = getchar()) != EOF) {
|
||||||
|
*p++ = c;
|
||||||
|
if (c != '\n') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
links[link_count].left[0] = buf[0];
|
||||||
|
links[link_count].left[1] = buf[1];
|
||||||
|
links[link_count].right[0] = buf[3];
|
||||||
|
links[link_count].right[1] = buf[4];
|
||||||
|
link_count++;
|
||||||
|
|
||||||
|
memset(buf, 0, CHARS_MAX);
|
||||||
|
p = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
// Find unique nodes
|
||||||
|
char (*nodes)[2] = calloc(MAX_NODES, sizeof(nodes[0]));
|
||||||
|
int node_count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < link_count; i++) {
|
||||||
|
// Add left
|
||||||
|
int found = 0;
|
||||||
|
for (int j = 0; j < node_count; j++) {
|
||||||
|
if (!memcmp(nodes[j], links[i].left, sizeof(nodes[0]))) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
memcpy(nodes[node_count++], links[i].left, sizeof(nodes[0]));
|
||||||
|
}
|
||||||
|
// Right
|
||||||
|
found = 0;
|
||||||
|
for (int j = 0; j < node_count; j++) {
|
||||||
|
if (!memcmp(nodes[j], links[i].right, sizeof(nodes[0]))) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
memcpy(nodes[node_count++], links[i].right, sizeof(nodes[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create adjacency matrix
|
||||||
|
uint8_t **adjacency = calloc(node_count, sizeof(adjacency[0]));
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
adjacency[i] = calloc(node_count, sizeof(adjacency[0][0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
for (int j = 0; j < node_count; j++) {
|
||||||
|
if (i == j) {
|
||||||
|
adjacency[i][j] = 1;
|
||||||
|
}
|
||||||
|
// Check if there's a link from i to j
|
||||||
|
for (int k = 0; k < link_count; k++) {
|
||||||
|
if (!memcmp(links[k].left, nodes[i], sizeof(nodes[0])) && !memcmp(links[k].right, nodes[j], sizeof(nodes[0]))) {
|
||||||
|
adjacency[i][j] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!memcmp(links[k].right, nodes[i], sizeof(nodes[0])) && !memcmp(links[k].left, nodes[j], sizeof(nodes[0]))) {
|
||||||
|
adjacency[i][j] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(links);
|
||||||
|
|
||||||
|
uint64_t groups = 0;
|
||||||
|
// Check each node that starts with 't'
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
for (int j = i; j < node_count; j++) {
|
||||||
|
if (i == j || adjacency[i][j] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a link from i to j
|
||||||
|
// Check if there's a k in j's neighbors that has a link to i
|
||||||
|
for (int k = j; k < node_count; k++) {
|
||||||
|
if (k == j || k == i || adjacency[j][k] == 0 || adjacency[k][i] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least one 't'
|
||||||
|
if (nodes[i][0] != 't' && nodes[j][0] != 't' && nodes[k][0] != 't') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
groups++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%lu\n", groups);
|
||||||
|
|
||||||
|
uint64_t largest_conn_count = 0;
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
uint64_t connections = 0;
|
||||||
|
for (int j = 0; j < node_count; j++) {
|
||||||
|
if (adjacency[i][j] == 1) {
|
||||||
|
connections++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (connections > largest_conn_count) {
|
||||||
|
largest_conn_count = connections;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
// Get connected node idxs
|
||||||
|
int *connected = calloc(largest_conn_count, sizeof(connected[0]));
|
||||||
|
int count = 0;
|
||||||
|
for (int j = 0; j < node_count; j++) {
|
||||||
|
if (adjacency[i][j]) {
|
||||||
|
connected[count++] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether everyone is connected with everyone
|
||||||
|
int good = 1;
|
||||||
|
for (int l = 0; l < count; l++) {
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
for (int k = 0; k < count; k++) {
|
||||||
|
if (adjacency[connected[j]][connected[k]] == 0 && l != j && l != k) {
|
||||||
|
good = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!good) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (good) {
|
||||||
|
char (*formatted)[2] = calloc(count - 1, sizeof(formatted[0]));
|
||||||
|
int formatted_count = 0;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
if (j != l) {
|
||||||
|
memcpy(formatted[formatted_count++], nodes[connected[j]], sizeof(nodes[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qsort(formatted, count - 1, sizeof(char[2]), cmp);
|
||||||
|
for (int j = 0; j < count - 1; j++) {
|
||||||
|
printf("%c%c", formatted[j][0], formatted[j][1]);
|
||||||
|
if (j != count - 2) {
|
||||||
|
printf(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < node_count; i++) {
|
||||||
|
free(adjacency[i]);
|
||||||
|
}
|
||||||
|
free(adjacency);
|
||||||
|
free(nodes);
|
||||||
|
}
|
||||||
3380
day23/input.txt
Normal file
3380
day23/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
32
day23/sample.txt
Normal file
32
day23/sample.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
kh-tc
|
||||||
|
qp-kh
|
||||||
|
de-cg
|
||||||
|
ka-co
|
||||||
|
yn-aq
|
||||||
|
qp-ub
|
||||||
|
cg-tb
|
||||||
|
vc-aq
|
||||||
|
tb-ka
|
||||||
|
wh-tc
|
||||||
|
yn-cg
|
||||||
|
kh-ub
|
||||||
|
ta-co
|
||||||
|
de-co
|
||||||
|
tc-td
|
||||||
|
tb-wq
|
||||||
|
wh-td
|
||||||
|
ta-ka
|
||||||
|
td-qp
|
||||||
|
aq-cg
|
||||||
|
wq-ub
|
||||||
|
ub-vc
|
||||||
|
de-ta
|
||||||
|
wq-aq
|
||||||
|
wq-vc
|
||||||
|
wh-yn
|
||||||
|
ka-de
|
||||||
|
kh-ta
|
||||||
|
co-tc
|
||||||
|
wh-qp
|
||||||
|
tb-vc
|
||||||
|
td-yn
|
||||||
Reference in New Issue
Block a user