Infinite Sequences (w/o using Stream)

Run Settings
LanguageElixir
Language Version
Run Command
require Sequences defmodule SequencesTest do def run do IO.puts "Sequences.nats |> Enum.take(10)" Sequences.nats |> Enum.take(10) |> IO.inspect IO.puts "Sequences.fibs |> Enum.take(10)" Sequences.fibs |> Enum.take(10) |> IO.inspect IO.puts "Sequences.fibs |> Enum.at(99)" Sequences.fibs |> Enum.at(99) |> IO.inspect IO.puts "Sequences.primes |> Enum.take(20)" Sequences.primes |> Enum.take(20) |> IO.inspect IO.puts "Sequences.primes |> Enum.at(9999)" Sequences.primes |> Enum.at(9999) |> IO.inspect end end SequencesTest.run
defmodule Sequences do @doc ~S""" Natural Integers (Non-Negative Integers). ## Examples # take 1..10 iex> Sequences.nats |> Enum.take(10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] """ def nats do &nats(1, &1, &2) end defp nats(_, {:halt, acc}, _fun), do: {:halted, acc} defp nats(n, {:suspend, acc}, fun), do: {:suspended, acc, &nats(n, &1, fun)} defp nats(n, {:cont, acc}, fun), do: nats(n + 1, fun.(n, acc), fun) @doc ~S""" Fibonacci Sequence ([1, 1, 2, 3, ...]). ## Examples # take first 10 Fibonacci Numbers. iex> Sequences.fibs |> Enum.take(10) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] # The 100th Fibonacci Number iex> Sequences.fibs |> Enum.at(99) 354224848179261915075 """ def fibs do &fibs({1, 1}, &1, &2) end defp fibs(_, {:halt, acc}, _fun), do: {:halted, acc} defp fibs(v, {:suspend, acc}, fun), do: {:suspended, acc, &fibs(v, &1, fun)} defp fibs({a, b}, {:cont, acc}, fun), do: fibs({b, a + b}, fun.(a, acc), fun) @doc ~S""" Primes. ## Examples # First 20 primes iex> Sequences.primes |> Enum.take(20) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] # The 10000th prime iex> Sequences.primes |> Enum.at(9999) 104729 """ def primes do &primes(2, &1, &2) end defp primes(_, {:halt, acc}, _fun), do: {:halted, acc} defp primes(v, {:suspend, acc}, fun) do {:suspended, acc, &primes(v, &1, fun)} end defp primes(2, {:cont, acc}, fun) do primes(3, fun.(2, acc), fun) end defp primes(3, {:cont, acc}, fun) do primes({%{}, 5, 2, nil}, fun.(3, acc), fun) end defp primes({h, p, d, nil}, {:cont, acc}, fun) do m = next_m(h, p, p, 4, true) n = p + d next_h = h |> Map.put(m, p) primes({next_h, n, 6 - d, Map.get(next_h, n)}, fun.(p, acc), fun) end defp primes({h, q, d, b}, {:cont, _} = acc, fun) do k = if rem(q + b, 3) == 0, do: 2, else: 4 m = next_m(h, b, q, k, true) n = q + d next_h = h |> Map.put(m, b) |> Map.delete(q) primes({next_h, n, 6 - d, Map.get(next_h, n)}, acc, fun) end defp next_m(_, _, m, _, false), do: m defp next_m(h, n, pre_m, k, true) do m = pre_m + n * k next_m(h, n, m, 6 - k, Map.has_key?(h, m)) end end
Editor Settings
Theme
Key bindings
Full width
Lines