Skip to content

Instantly share code, notes, and snippets.

@arkgil
Created April 21, 2016 23:04
Show Gist options
  • Save arkgil/b097f5a8a9cdf8d253fe6b7066a77eb2 to your computer and use it in GitHub Desktop.
Save arkgil/b097f5a8a9cdf8d253fe6b7066a77eb2 to your computer and use it in GitHub Desktop.
defmodule STask do
@doc """
Constructs a stream of numbers which
are worth checking if they divide n.
By jumping by 2 and 4 we filter out
obvious candidates.
"""
def divisors_stream(n) do
Stream.unfold({4, 7}, fn
{_, number} when number >= n ->
nil
{4, number} ->
{number, {2, number + 4}}
{2, number} ->
{number, {4, number + 2}}
end)
end
@doc """
Checks wheter number is prime.
"""
def is_prime({_, n}), do: is_prime(n)
def is_prime(n) when n <= 1, do: false
def is_prime(n) when n in [2, 3, 5], do: true
def is_prime(n) when rem(n, 2) == 0, do: false
def is_prime(n) when rem(n, 3) == 0, do: false
def is_prime(n) when rem(n, 5) == 0, do: false
def is_prime(n) do
divisors_stream(n)
|> Enum.to_list
|> Enum.filter(&(rem(n, &1) == 0))
|> Enum.all?(&(&1 == 1 || &1 == n))
end
@doc """
Extracts elements of list which appear in it
prime number of times.
"""
def get_prime_occurences(list) do
list
|> Enum.reduce(%{}, &update_count/2)
|> Enum.filter(&is_prime/1)
|> Enum.into([], fn {k, _} -> k end)
end
def update_count(x, acc), do: Map.update(acc, x, 1, &(&1 + 1))
@doc """
Function filters out elements of a which
appear in b prime number of times.
"""
def fancy_filter(a, b) do
prime_occurences = get_prime_occurences(b)
Enum.filter(a, &(!&1 in prime_occurences))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment