diff --git a/day10/README b/day10/README index 7fde3ae..6f9f286 100644 --- a/day10/README +++ b/day10/README @@ -52,6 +52,12 @@ than that, because we don't need to keep the connections around, just the weight Finally, the weight of the max joltage adapter is the answer. +** Update ** + +I added day10part2-refactored.exs, which contains a commented and arguably easier to understand +version that uses Enum.reduce instead of so much recursion. However, in benchmarks it was +negligibly (~1 microsecond) slower, so I decided to leave the original version in place. + +------------------+ | Overall Thoughts | +------------------+ diff --git a/day10/day10part2-refactored.exs b/day10/day10part2-refactored.exs new file mode 100644 index 0000000..1f7e0f6 --- /dev/null +++ b/day10/day10part2-refactored.exs @@ -0,0 +1,38 @@ +defmodule Day10Part2 do + def run do + File.read!("input") + |> String.split("\n", trim: true) + |> Enum.map(&String.to_integer/1) + |> count_arrangements() + |> IO.puts() + end + + # Entry point. Start with one arrangement: the outlet. + def count_arrangements(list), do: count_arrangements(%{0 => 1}, [0 | Enum.sort(list)]) + + # Termination point. We've checked all the adapters. The number of arrangments + # to the last adapter is the answer. + def count_arrangements(arrangements, [last]), do: arrangements[last] + + # Check each adapter in turn by comparing it to the next three adapters. + def count_arrangements(arrangements, [current | rest]) do + count_for_adapter(current, Enum.take(rest, 3), arrangements) + |> count_arrangements(rest) + end + + # Compare the next three adapters to the current adapter. + # For each checked adapter, if the joltage difference is 3 or less, we can connect them, + # so add the number of arrangements up to the current adapter to that adapter. + def count_for_adapter(current, next_three, arrangements) do + Enum.reduce(next_three, arrangements, fn adapter, arrangements -> + if adapter - current <= 3 do + current_count = arrangements[current] + Map.update(arrangements, adapter, current_count, &(&1 + current_count)) + else + arrangements + end + end) + end +end + +Day10Part2.run()