Skip to content

Instantly share code, notes, and snippets.

@KamilLelonek
Created May 26, 2018 11:43
Show Gist options
  • Save KamilLelonek/6593161e7c210f443afc31a0b950dd85 to your computer and use it in GitHub Desktop.
Save KamilLelonek/6593161e7c210f443afc31a0b950dd85 to your computer and use it in GitHub Desktop.
defmodule Task1 do
@doc """
A function that receives two sequences: A and B of integers and returns one sequence C.
Sequence C should contain all elements from sequence A (maintaining the order) except those,
that are present in sequence B p times, where p is a prime number.
Example:
A=[2,3,9,2,5,1,3,7,10]
B=[2,1,3,4,3,10,6,6,1,7,10,10,10]
C=[2,9,2,5,7,10]
"""
@spec call(seq1 :: [integer()], seq2 :: [integer()], p :: integer()) :: [integer()]
def call(seq1, seq2, prime) do
prime
|> prime?()
|> maybe_filter(seq1, seq2, prime)
end
defp prime?(number)
when number <= 2,
do: true
defp prime?(number), do: Enum.all?(range(number), &dividable?(number, &1))
defp range(number), do: 2..(number |> :math.sqrt() |> round())
defp dividable?(dividend, divisor), do: rem(dividend, divisor) != 0
defp maybe_filter(false, _seq1, _seq2, prime), do: {:error, "#{prime} must be a prime number"}
defp maybe_filter(true, seq1, seq2, prime) do
seq2
|> histogram()
|> drop_occurences(prime)
|> take_values()
|> reject(seq1)
end
defp histogram(list) when is_list(list),
do: Enum.reduce(list, %{}, &count/2)
defp count(element, occurences),
do: Map.update(occurences, element, 1, &(&1 + 1))
defp drop_occurences(histogram, prime), do: Enum.filter(histogram, fn {_k, v} -> v == prime end)
defp take_values(seq), do: Enum.map(seq, &elem(&1, 0))
defp reject(to_remove, seq), do: Enum.reject(seq, &Enum.member?(to_remove, &1))
end
@KamilLelonek
Copy link
Author

iex(1)> Task1.call([2,3,9,2,5,1,3,7,10], [2,1,3,4,3,10,6,6,1,7,10,10,10], 2)
[2, 9, 2, 5, 7, 10]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment