RosettaCodeData/Task/Average-loop-length/Elixir/average-loop-length.elixir

27 lines
809 B
Text
Raw Permalink Normal View History

2015-11-18 06:14:39 +00:00
defmodule RC do
def factorial(0), do: 1
def factorial(n), do: Enum.reduce(1..n, 1, &(&1 * &2))
2016-12-05 22:15:40 +01:00
def loop_length(n), do: loop_length(n, MapSet.new)
2015-11-18 06:14:39 +00:00
defp loop_length(n, set) do
2016-12-05 22:15:40 +01:00
r = :rand.uniform(n)
if r in set, do: MapSet.size(set), else: loop_length(n, MapSet.put(set, r))
2015-11-18 06:14:39 +00:00
end
def task(runs) do
IO.puts " N average analytical (error) "
IO.puts "=== ========= ========== ========="
Enum.each(1..20, fn n ->
2016-12-05 22:15:40 +01:00
avg = Enum.reduce(1..runs, 0, fn _,sum -> sum + loop_length(n) end) / runs
2015-11-18 06:14:39 +00:00
analytical = Enum.reduce(1..n, 0, fn i,sum ->
sum + (factorial(n) / :math.pow(n, i) / factorial(n-i))
end)
:io.format "~3w ~9.4f ~9.4f (~6.2f%)~n", [n, avg, analytical, abs(avg/analytical - 1)*100]
end)
end
end
2016-12-05 22:15:40 +01:00
runs = 1_000_000
2015-11-18 06:14:39 +00:00
RC.task(runs)