1 defmodule SieveFilter do
2 def less_than?({a, _}, {b, _}) when a < b do true end
3 def less_than?({a, b}, {a, c}) when b < c do true end
4 def less_than?(_, _) do false end
6 def get_next({counter, prime}) do {counter + prime, prime} end
10 def run_item_through_sieve([{item, prime}|remaining_sieve], item) do
11 {matched, unmatched} = run_item_through_sieve(remaining_sieve, item)
12 {[{item, prime}|matched], unmatched}
14 def run_item_through_sieve(sieve, _) do {[], sieve} end
16 def merge(xs, []) do xs end
17 def merge([], ys) do ys end
22 if SieveFilter.less_than?(x, y) do
23 [x|merge(remaining_xs, ys)]
25 [y|merge(xs, remaining_ys)]
29 def get_next(sieve) do
30 Enum.map(sieve, &(SieveFilter.get_next(&1)))
35 def transform(sieve, previous_item) do
36 item = previous_item + 1
37 {matched, unmatched} = Sieve.run_item_through_sieve(sieve, item)
40 [] -> {Sieve.merge([{item * 2, item}], sieve), item}
41 _ -> transform(Sieve.merge(Sieve.get_next(matched), unmatched), item)
45 def generate(initial_state, initial_item, get_next) do
48 {initial_state, initial_item},
49 fn({previous_state, previous_item}) -> get_next.(previous_state, previous_item) end
51 fn({_, item}) -> item end
56 Stream.drop(generate([], 1, &(transform(&1, &2))), 1)