Files
adventofcode/src/c/2024/day19/part2.c

127 lines
2.7 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CACHE_SIZE 100000
char towels[1000][100];
int towel_length[1000];
char wanted[1000][100];
char cache_key[CACHE_SIZE][100];
long cache_value[CACHE_SIZE];
int cache_len = 0;
int num_towels = 0;
// returns index of first mismatch
int first_mismatch(char* a, char* b) {
int i = 0;
while (a[i] == b[i] && a[i] && b[i]) {
i++;
}
return i;
}
// returns 1 if found, 0 if not
long find_arrangement(char* wanted, int depth) {
if (wanted[0] == 0) {
return 1;
}
for (int i = 0; i < cache_len; i++) {
if (strcmp(cache_key[i], wanted) == 0) {
//printf("cache hit\n");
return cache_value[i];
}
}
long total = 0;
for (int i = 0; i < num_towels; i++) {
//if (depth == 0) {
//}
if (first_mismatch(wanted, towels[i]) == towel_length[i]) {
//if (depth <= 10) {
//printf("%d: %s v %s: %d.. %d\n", depth, wanted, towels[i], first_mismatch(wanted, towels[i]), total);
//}
total += find_arrangement(&wanted[towel_length[i]], depth + 1);
}
}
strcpy(cache_key[cache_len], wanted);
cache_value[cache_len] = total;
cache_len++;
return total;
}
int main() {
char *line_buf = NULL;
size_t buffer_size = 1000;
int amount = getline(&line_buf, &buffer_size, stdin);
int last_comma = 0;
for (int i = 0; i < amount; i++) {
if (line_buf[i] == ',') {
strncpy(towels[num_towels], &line_buf[last_comma], i - last_comma);
towels[num_towels][i - last_comma] = 0;
towel_length[num_towels] = i - last_comma;
//printf("%s, %d\n", towels[num_towels], towel_length[num_towels]);
num_towels++;
last_comma = i + 2;
}
}
strncpy(towels[num_towels], &line_buf[last_comma], amount - last_comma - 1);
towels[num_towels][amount - last_comma - 1] = 0;
towel_length[num_towels] = amount - last_comma - 1;
//printf("%s\n", towels[num_towels]);
num_towels++;
//exit(0);
// parse empty line
getline(&line_buf, &buffer_size, stdin);
int num_wanted = 0;
int n;
while ((n = getline(&line_buf, &buffer_size, stdin)) > 0) {
strncpy(wanted[num_wanted], line_buf, n - 1);
num_wanted++;
//printf("!%s\n", wanted[num_wanted - 1]);
}
long total = 0;
for (int i = 0; i < num_wanted; i++) {
total += find_arrangement(wanted[i], 0);
printf("%s, %ld\n", wanted[i], find_arrangement(wanted[i], 0));
//printf("%s, %d\n", wanted[i], find_arrangement(wanted[i]));
}
printf("res: %ld", total);
}