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:
William Carroll 2020-12-12 01:32:31 +00:00
parent ab73220280
commit ee96a818e1
2 changed files with 51 additions and 11 deletions

View file

@ -4,15 +4,30 @@ defmodule Server do
"""
@doc """
Hello world.
## Examples
iex> Server.hello()
:world
If `n` contains exactly two prime factors, return those prime factors;
otherwise, return nothing.
"""
def hello do
:world
def semiprime(n) do
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

View file

@ -2,7 +2,32 @@ defmodule ServerTest do
use ExUnit.Case
doctest Server
test "greets the world" do
assert Server.hello() == :world
describe "semiprime" do
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