#include #include #include #include #include "../../lib/aoc.h" #include "../../lib/hashmap.h" typedef char Towel[10]; typedef struct Towels { Towel towels[2000]; int towels_count; AocHashmap *map; } Towels; bool towels_valid_design(Towels *t, char *design) { if (strlen(design) == 0) return true; for (int i = 0; i < t->towels_count; i++) { if (strstr(design, t->towels[i]) == design) { if (towels_valid_design(t, design + strlen(t->towels[i]))) return true; } } return false; } long towels_valid_designs(Towels *t, char *design) { AocHashmapNode *memo = aoc_hashmap_get(t->map, design); if (memo != NULL) return *(long *)memo->value; if (strlen(design) == 0) return 1; long *valid_designs = malloc(sizeof(long)); for (int i = 0; i < t->towels_count; i++) { if (strstr(design, t->towels[i]) == design) { *valid_designs += towels_valid_designs(t, design + strlen(t->towels[i])); } } aoc_hashmap_put(t->map, design, valid_designs); return *valid_designs; } int main() { char *line; Towels towels; towels.towels_count = 0; towels.map = malloc(sizeof(AocHashmap)); for (int i = 0; i < AOC_HASHMAP_RADIX; i++) { towels.map->buckets[i] = NULL; } line = aoc_read_line(); char *token = strtok(line, ", "); while (token != NULL) { strcpy(towels.towels[towels.towels_count++], token); token = strtok(NULL, ", "); } aoc_read_line(); // blank line int valid_single_designs = 0; long valid_multi_designs = 0; while ((line = aoc_read_line()) != NULL) { if (towels_valid_design(&towels, line)) valid_single_designs++; valid_multi_designs += towels_valid_designs(&towels, line); } printf("Part 1: %d\n", valid_single_designs); printf("Part 2: %ld\n", valid_multi_designs); aoc_hashmap_free(towels.map); aoc_free(); exit(0); }