Define Server.semiprime
- Clear the boilerplate that `mix` generated - Consume `Math.factor` to test which inputs are semiprimes - Cache all inputs that are semiprimes as soon as we discover that they are - semiprimes I considered a couple things related to the Cache: - Could save space by storing all semiprime factors in a tree. This would make the lookups more expensive. Also because the tree's depth would never exceed two (because all semiprimes only have two factors), the tree would be quite broad, and we may not be saving enough space for the trade to be worthwhile. I might be wrong about that though. - We could consider pre-computing all semiprimes when we start the app, but without running some tests firsts, I'm not sure whether or not it's worth the trouble.
This commit is contained in:
parent
ab73220280
commit
ee96a818e1
2 changed files with 51 additions and 11 deletions
|
@ -4,15 +4,30 @@ defmodule Server do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Hello world.
|
If `n` contains exactly two prime factors, return those prime factors;
|
||||||
|
otherwise, return nothing.
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> Server.hello()
|
|
||||||
:world
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def hello do
|
def semiprime(n) do
|
||||||
:world
|
case Cache.get(n) do
|
||||||
|
nil ->
|
||||||
|
case do_semiprime(n) do
|
||||||
|
nil ->
|
||||||
|
nil
|
||||||
|
|
||||||
|
res ->
|
||||||
|
Cache.put(n, res)
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
hit ->
|
||||||
|
hit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_semiprime(n) do
|
||||||
|
case Math.factor(n) do
|
||||||
|
[_, _] = res -> res
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,32 @@ defmodule ServerTest do
|
||||||
use ExUnit.Case
|
use ExUnit.Case
|
||||||
doctest Server
|
doctest Server
|
||||||
|
|
||||||
test "greets the world" do
|
describe "semiprime" do
|
||||||
assert Server.hello() == :world
|
test "returns the factors when the number is semiprime" do
|
||||||
|
# Semiprimes below 30
|
||||||
|
[
|
||||||
|
{4, [2, 2]},
|
||||||
|
{6, [2, 3]},
|
||||||
|
{9, [3, 3]},
|
||||||
|
{10, [2, 5]},
|
||||||
|
{14, [2, 7]},
|
||||||
|
{15, [3, 5]},
|
||||||
|
{21, [3, 7]},
|
||||||
|
{22, [2, 11]},
|
||||||
|
{25, [5, 5]},
|
||||||
|
{26, [2, 13]}
|
||||||
|
]
|
||||||
|
|> Enum.each(fn {input, expected} ->
|
||||||
|
assert Server.semiprime(input) == expected
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns nothing when the number is a composite number" do
|
||||||
|
# Composite numbers below 30
|
||||||
|
[1, 2, 3, 5, 7, 8, 11, 12, 13, 16, 17, 18, 19, 20, 23, 24, 27, 28, 29]
|
||||||
|
|> Enum.each(fn x ->
|
||||||
|
assert Server.semiprime(x) == nil
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue