Skip to content

Instantly share code, notes, and snippets.

@certainty
Last active July 23, 2016 14:10
Show Gist options
  • Save certainty/5b2c9c080d8c8185d93727a700934148 to your computer and use it in GitHub Desktop.
Save certainty/5b2c9c080d8c8185d93727a700934148 to your computer and use it in GitHub Desktop.
sign_distribution
defmodule Challenge do
def sign_distribution(numbers) do
numbers
|> Enum.reduce({%{neg: 0, pos: 0, zero: 0}, 0}, &update_frequencies/2)
|> calculate_percentage
end
defp update_frequencies(number, {frequencies, total}) do
{Map.update!(frequencies, sign(number), &(&1 + 1)), total + 1}
end
defp sign(n) when n > 0, do: :pos
defp sign(n) when n < 0, do: :neg
defp sign(_), do: :zero
defp calculate_percentage({%{neg: neg, pos: pos, zero: zero}, total}) do
%{neg: pcnt(neg, total),
pos: pcnt(pos, total),
zero: pcnt(zero, total)}
end
defp pcnt(n, total), do: 1.0 * (total / n)
end
[1,2,3,0,0,0,-1,-10]
|> Challenge.sign_distribution
|> IO.inspect
defmodule Challenge2 do
@spec sign_distribution([Integer.t]) :: Map.t
def sign_distribution(numbers), do: do_sign_distribution(numbers, 0, 0, 0, 0)
defp do_sign_distribution([], total, pos, neg, zero) do
%{pos: pcnt(pos, total),
neg: pcnt(neg, total),
zero: pcnt(zero, total)}
end
defp do_sign_distribution([n | ns], total, pos, neg, zero) do
new_total = total + 1
cond do
n > 0 -> do_sign_distribution(ns, new_total, pos + 1, neg, zero)
n < 0 -> do_sign_distribution(ns, new_total, pos, neg + 1, zero)
true -> do_sign_distribution(ns, new_total, pos, neg, zero + 1)
end
end
defp pcnt(n, total), do: 1.0 * (total / n)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment