diff --git a/Elixir/digital_sum.ex b/Elixir/digital_sum.ex
@@ -11,69 +11,70 @@ defmodule Conjecture do
if max < 0 or n_processes <= 0 do
:invalid_input
else
- # Spawn a new process for each starting index from 0 to ``max`
- f = fn i -> spawn fn -> get_counterexpl i, max, n_processes end end
- pids = Enum.map 1..n_processes, f
+ parent_id = self()
- # Send the current PID to each process
- Enum.map pids, fn pid -> send pid, self() end
- listen n_processes
+ # Spawn a new process for each starting index from 0 to `max`
+ f = fn i -> spawn fn -> counterexpl i, max, n_processes, parent_id end end
+ Enum.map 1..n_processes, f
+
+ listen n_processes, %{}
end
end
# Listen for messages on all processes
- def listen 0 do :ok end
-
- def listen n do
- receive do
- :ok -> listen (n - 1)
- msg -> msg
- end
- end
+ def listen 0, _ do :ok end
- def get_counterexpl start, max, n_processes do
+ def listen n, sums_cache do
receive do
- parent_pid ->
- case counterexpl start, max, n_processes, %{} do
- :found -> send parent_pid, :fail
- _ -> send parent_pid, :ok
+ :ok -> listen (n - 1), sums_cache
+ :fail -> :fail
+ {child_id, m} ->
+ if Map.has_key? sums_cache, m do
+ send child_id, sums_cache[m]
+ listen n, sums_cache
+ else
+ sum_m = sum m
+ send child_id, sum_m
+ listen m, Map.put(sums_cache, m, sum_m)
end
end
end
- def counterexpl a, max, n_processes, sums_cache do
- case iter a, 0, sums_cache do
- :found -> :found
- sums_cache_updated ->
- if a + n_processes <= max do
- counterexpl (a + n_processes), max, n_processes, sums_cache_updated
- else
- sums_cache_updated
- end
+ def counterexpl a, max, step, parent_id do
+ cond do
+ iter a, 0, parent_id -> send parent_id, :found
+ a + step <= max ->
+ counterexpl (a + step), max, step, parent_id
+ true -> send parent_id, :ok
end
end
- def iter a, b, sums_cache do
- case test a, b, sums_cache do
- :found -> :found
- sums_cache_updated ->
- if b + 1 < a do
- iter a, b + 1, sums_cache_updated
- else
- sums_cache_updated
- end
+ def iter a, b, parent_id do
+ IO.puts (test a, b, parent_id)
+ cond do
+ test a, b, parent_id -> true
+ b + 1 < a -> iter a, b + 1, parent_id
+ true -> false
end
end
- def test a, b, sums_cache do
- {sums_cache_a, sum_a} = lookup sums_cache, a
- {sums_cache_b, sum_b} = lookup sums_cache_a, b
- {sums_cache_a_b, sum_a_b} = lookup sums_cache_b, a + b
+ def test a, b, parent_id do
+ self_id = self()
+ send parent_id, {self_id, a}
- if 0 != rem(sum_a_b - sum_a - sum_b, 9) do
- :found
- else
- sums_cache_a_b
+ receive do
+ sum_a ->
+ send parent_id, {self_id, b}
+
+ receive do
+ sum_b ->
+ send parent_id, {self_id, a + b}
+
+ receive do
+ sum_a_b ->
+ 0 != rem(sum_a_b - sum_a - sum_b, 9)
+ end
+ end
end
end