I’m just learning Elixir but find it really fun, nevertheless it’s easy to produce crappy code when there is no one to do some review. Thus i ask you nicely to tell me how can I improve it to be more readable, or maybe faster, better?
defmodule Two do
def fibonacci_even_sum do
Stream.unfold({1, 2}, fn({n, m}) -> if n > 4_000_000, do: nil, else: {n, {m, n + m}} end)
|> Enum.reduce(0, fn(n, acc) -> if rem(n, 2) == 0, do: n + acc, else: 0 + acc end)
end
end
IO.inspect Two.fibonacci_even_sum
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
I’m also just getting my feet wet with Elixir and I’ve been trying to approach problems like this as if I were going to be applying them to larger systems/had other team members looking at my code later.
Nice use of unfold! Lets pull it out into its own function.
defmodule Two do
def fibonacci_even_sum do
fibonacci_sequence
|> Stream.take_while(&(&1 < 4_000_000))
|> Enum.reduce(0, &sum_even/2)
end
def fibonacci_sequence do
Stream.unfold({1,1}, fn {a,b} -> {a, {b, a + b}} end)
end
def sum_even(num, acc) do
if rem(num, 2) == 0, do: acc + num, else: acc
end
end
I’ve doubled the amount of lines your solution would take but it makes your intentions more obvious.
Piping into Stream.take_while allows us to turn your unfold into a more generally useful endless stream while only taking as many as we need.
I’m conflicted on pulling the reduce function out into its own function, I’m not really sure what the general best practice is there? I’d like to hear more from people on that.
Yeah, they are much more readable So much more learning before me, but when i read how can my ugly code be transformed into something beautiful i think i’ll switch to Elixir in my Engineering thesis