Created
November 24, 2016 01:04
-
-
Save DavidAntaramian/317a2ff1bec962ed458b528abe7d40fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Johnann do | |
def john(day) when day >= 1 do | |
get(day, :john) | |
end | |
def ann(day) when day >= 1 do | |
get(day, :ann) | |
end | |
def sum_john(day) when day >= 1 do | |
john(day) | |
|> Enum.sum() | |
end | |
def sum_ann(day) when day >= 1 do | |
ann(day) | |
|> Enum.sum() | |
end | |
defp get(day, person) do | |
day | |
|> get_or_calculate() | |
|> Map.get(person) | |
|> Enum.sort() | |
|> Enum.map(fn {_, v} -> v end) | |
end | |
defp get_or_calculate(day) do | |
get_or_calculate(day, %{john: %{0 => 0}, ann: %{0 => 1}}) | |
end | |
# The number of calculations have an upper-bound on the number of days | |
# that have been calculated for John. When the number of entries in | |
# John's cache are equal to or greater than the day being requested, | |
# there is no need for further calculation | |
defp get_or_calculate(day, %{john: john, ann: ann}) when map_size(john) < day do | |
# The number of days calculated so far | |
new_index = map_size(john) | |
previous_index = new_index - 1 | |
johns_katas = calculate(john, ann, new_index, previous_index) | |
john = Map.put(john, new_index, johns_katas) | |
anns_katas = calculate(ann, john, new_index, previous_index) | |
ann = Map.put(ann, new_index, anns_katas) | |
get_or_calculate(day, %{ john: john, ann: ann }) | |
end | |
defp get_or_calculate(_, cache) do | |
cache | |
end | |
defp calculate(origin, other, new_index, previous_index) do | |
old_index = Map.get(origin, previous_index) | |
new_index - Map.get(other, old_index) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment