#include #include #include #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); }