Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Created September 25, 2013 13:27
Show Gist options
  • Save sasa1977/6699577 to your computer and use it in GitHub Desktop.
Save sasa1977/6699577 to your computer and use it in GitHub Desktop.
defmodule Fibonacci do
defrecordp :fib_state, Fibonacci, current: 0, previous1: nil, previous2: nil
def new do
fib_state()
end
def value(fib_state(current: current)) do
current
end
def next(state) do
state
|> shift
|> compute_current
end
defp shift(fib_state(current: current, previous1: previous1) = state) do
fib_state(state, previous1: current, previous2: previous1)
end
defp compute_current(fib_state(previous2: nil) = state) do
fib_state(state, current: 1)
end
defp compute_current(fib_state(previous1: previous1, previous2: previous2) = state) do
fib_state(state, current: (previous1 || 0) + (previous2 || 0))
end
def lazy(initial_state // fib_state()) do
Stream.iterate(initial_state, next(&1))
end
end
# Basic usage
fib0 = Fibonacci.new
fib1 = Fibonacci.next(fib0)
fib2 = Fibonacci.next(fib1)
fib3 = Fibonacci.next(fib2)
IO.inspect fib3
IO.puts ""
# Lazy sequence
Fibonacci.lazy
|> Enum.take(5)
|> IO.inspect
IO.puts ""
# Advanced usage:
Fibonacci.lazy
|> Stream.drop(3) # drop first three
|> Enum.first # take the first
|> Fibonacci.lazy # start lazy from it
|> Stream.filter(&(rem(Fibonacci.value(&1), 2) == 1)) # take only odd values
|> Stream.map(&(Fibonacci.value(&1))) # extract values from it
|> Enum.take(10) # take first 10
|> IO.inspect # print it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment