Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Last active October 1, 2015 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sasa1977/fcf245c23e2498e4e985 to your computer and use it in GitHub Desktop.
Save sasa1977/fcf245c23e2498e4e985 to your computer and use it in GitHub Desktop.
defmodule Primes do
# Basic implementation of an infinite prime generator, as explained at
# http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
def new do
%{composites: HashDict.new, current: 2}
end
def next(%{composites: composites, current: current} = sieve) do
case HashDict.get(composites, current) do
nil ->
sieve
|> add_composite(current * current, current)
|> advance
factors ->
Enum.reduce(factors, sieve, &add_composite(&2, current + &1, &1))
|> remove_current
|> advance
|> next
end
end
defp advance(%{current: current} = sieve) do
%{sieve | current: current + 1}
end
defp remove_current(%{composites: composites, current: current} = sieve) do
%{sieve | composites: HashDict.delete(composites, current)}
end
defp add_composite(%{composites: composites} = sieve, which, factor) do
%{sieve | composites: HashDict.update(composites, which, [factor], &[factor | &1])}
end
def stream do
Stream.unfold(new, fn(acc) -> {acc.current, next(acc)} end)
end
def nth(n) do
stream
|> Stream.drop(n - 1)
|> Enum.take(1)
|> hd
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment