diff --git a/day19/main.exs b/day19/main.exs new file mode 100644 index 0000000..c981099 --- /dev/null +++ b/day19/main.exs @@ -0,0 +1,57 @@ +defmodule Day19 do + def run do + {patterns, designs} = parse_file("data.txt") + + {possibles, _c} = + Enum.reduce(designs, {[], %{}}, fn d, {list, cache} -> + {total, c} = possible_designs(d, patterns, cache) + {[total | list], c} + end) + + part1 = Enum.filter(possibles, fn el -> el != 0 end) |> length + dbg(part1) + + part2 = Enum.sum(possibles) + dbg(part2) + end + + # if the design is empty list, we got to the end successfully + defp possible_designs([], _, cache), do: {1, cache} + + defp possible_designs(design, patterns, cache) do + # look in the cache for this design + if Map.has_key?(cache, design) do + # if it's there, just return it + {Map.get(cache, design), cache} + else + # find all the patterns that match the beginning of the design + matching_patterns = Enum.filter(patterns, &List.starts_with?(design, &1)) + + {new_total, new_cache} = + if length(matching_patterns) == 0 do + # if there are none, we've failed + {0, cache} + else + # recurse on rest of the list + Enum.reduce(matching_patterns, {0, cache}, fn pattern, {total, new_cache} -> + rest = Enum.drop(design, length(pattern)) + {t, c} = possible_designs(rest, patterns, new_cache) + {t + total, c} + end) + end + + # add this new total to the cache & return it + new_cache2 = Map.put(new_cache, design, new_total) + {new_total, new_cache2} + end + end + + defp parse_file(file) do + [top, bottom] = File.read!(file) |> String.trim() |> String.split("\n\n") + patterns = String.split(top, ", ") |> Enum.map(&String.graphemes/1) + designs = String.split(bottom, "\n") |> Enum.map(&String.graphemes/1) + {patterns, designs} + end +end + +Day19.run()