mirror of
https://git.plasmaofthedawn.com/adventofcode.git
synced 2025-12-24 02:27:34 -06:00
127 lines
2.7 KiB
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);
|
|
|
|
}
|