fork download
  1. defmodule Sequences do
  2. @doc ~S"""
  3. Natural Integers (Non-Negative Integers).
  4.  
  5. ## Examples
  6.  
  7. # take 1..10
  8. iex> Sequences.nats |> Enum.take(10)
  9. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  10. """
  11. def nats do
  12. &nats(1, &1, &2)
  13. end
  14.  
  15. defp nats(_, {:halt, acc}, _fun), do: {:halted, acc}
  16. defp nats(n, {:suspend, acc}, fun), do: {:suspended, acc, &nats(n, &1, fun)}
  17. defp nats(n, {:cont, acc}, fun), do: nats(n + 1, fun.(n, acc), fun)
  18.  
  19. @doc ~S"""
  20. Fibonacci Sequence ([1, 1, 2, 3, ...]).
  21.  
  22. ## Examples
  23.  
  24. # take first 10 Fibonacci Numbers.
  25. iex> Sequences.fibs |> Enum.take(10)
  26. [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
  27.  
  28. # The 100th Fibonacci Number
  29. iex> Sequences.fibs |> Enum.at(99)
  30. 354224848179261915075
  31. """
  32. def fibs do
  33. &fibs({1, 1}, &1, &2)
  34. end
  35.  
  36. defp fibs(_, {:halt, acc}, _fun), do: {:halted, acc}
  37. defp fibs(v, {:suspend, acc}, fun), do: {:suspended, acc, &fibs(v, &1, fun)}
  38. defp fibs({a, b}, {:cont, acc}, fun), do: fibs({b, a + b}, fun.(a, acc), fun)
  39.  
  40. @doc ~S"""
  41. Primes.
  42.  
  43. ## Examples
  44.  
  45. # First 20 primes
  46. iex> Sequences.primes |> Enum.take(20)
  47. [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
  48.  
  49. # The 10000th prime
  50. iex> Sequences.primes |> Enum.at(9999)
  51. 104729
  52. """
  53. def primes do
  54. &primes(2, &1, &2)
  55. end
  56.  
  57. defp primes(_, {:halt, acc}, _fun), do: {:halted, acc}
  58. defp primes(v, {:suspend, acc}, fun) do
  59. {:suspended, acc, &primes(v, &1, fun)}
  60. end
  61. defp primes(2, {:cont, acc}, fun) do
  62. primes(3, fun.(2, acc), fun)
  63. end
  64. defp primes(3, {:cont, acc}, fun) do
  65. primes({%{}, 5, 2, nil}, fun.(3, acc), fun)
  66. end
  67. defp primes({h, p, d, nil}, {:cont, acc}, fun) do
  68. m = next_m(h, p, p, 4, true)
  69. n = p + d
  70. next_h = h |> Map.put(m, p)
  71. primes({next_h, n, 6 - d, Map.get(next_h, n)}, fun.(p, acc), fun)
  72. end
  73. defp primes({h, q, d, b}, {:cont, _} = acc, fun) do
  74. k = if rem(q + b, 3) == 0, do: 2, else: 4
  75. m = next_m(h, b, q, k, true)
  76. n = q + d
  77. next_h = h |> Map.put(m, b) |> Map.delete(q)
  78. primes({next_h, n, 6 - d, Map.get(next_h, n)}, acc, fun)
  79. end
  80.  
  81. defp next_m(_, _, m, _, false), do: m
  82. defp next_m(h, n, pre_m, k, true) do
  83. m = pre_m + n * k
  84. next_m(h, n, m, 6 - k, Map.has_key?(h, m))
  85. end
  86.  
  87. def run do
  88. IO.puts "Sequences.nats |> Enum.take(10)"
  89. Sequences.nats |> Enum.take(10) |> IO.inspect
  90. IO.puts "Sequences.fibs |> Enum.take(10)"
  91. Sequences.fibs |> Enum.take(10) |> IO.inspect
  92. IO.puts "Sequences.fibs |> Enum.at(99)"
  93. Sequences.fibs |> Enum.at(99) |> IO.inspect
  94. IO.puts "Sequences.primes |> Enum.take(20)"
  95. Sequences.primes |> Enum.take(20) |> IO.inspect
  96. IO.puts "Sequences.primes |> Enum.at(9999)"
  97. Sequences.primes |> Enum.at(9999) |> IO.inspect
  98. end
  99. end
  100.  
  101. Sequences.run
Success #stdin #stdout 1.09s 107200KB
stdin
Standard input is empty
stdout
Sequences.nats |> Enum.take(10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Sequences.fibs |> Enum.take(10)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Sequences.fibs |> Enum.at(99)
354224848179261915075
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]
Sequences.primes |> Enum.at(9999)
104729