I want to find the prime factors of a number. I wrote:
defmodule Prime do
def factors(n) when is_integer(n) and n > 1 do
Stream.unfold(n, fn 1 -> nil; n -> &({&1, div(n, &1)}).(lf n) end) |> Enum.to_list
end
def lf(n) when is_integer(n) and n > 1 do
if rem(n, 2) == 0 do 2
else Stream.iterate(3, &(&1 + 2)) |> Stream.filter(&(rem(n, &1) == 0))
|> Stream.take(1) |> Enum.to_list |> hd
end
end
end
The problem lies at line 3: in the anonymous function I have to return the tuple {f, n / f}, where f is the lowest factor of n and is calculated in the lf function. However, I don't want to compute it twice (I could do {lf n, div(n, lf n)}). I also tried to define a closure, but apparently it's not allowed.
The trick that I used doesn't even work.
How is it done?
Did you try assigning a local variable in your anonymous function? I added line breaks to make it more readable.
def factors(n) when is_integer(n) and n > 1 do
Stream.unfold(n,
fn 1 -> nil
n -> local = lf n
{local, div(n, local)}
end) |> Enum.to_list
end
By the way, you could shorten your lf function by using Enum.find. (I'd also make lf a private function.)
defp lf(n) when is_integer(n) and n > 1 do
if rem(n, 2) == 0 do 2
else Stream.iterate(3, &(&1 + 2)) |> Enum.find(&(rem(n, &1) == 0))
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With