Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active October 21, 2015 23:37
Show Gist options
  • Save havenwood/2a983703bd154b7e239a to your computer and use it in GitHub Desktop.
Save havenwood/2a983703bd154b7e239a to your computer and use it in GitHub Desktop.
Elixir FizzBuzz
defmodule FizzBuzz do
use GenServer
require Logger
def init(state) do
Logger.debug "Starting FizzBuzz Server ..."
{:ok, state}
end
def handle_call({:to_string, n}, _from, state) do
if Dict.has_key?(state, n) do
{:reply, state[n], state}
else
value = __MODULE__.to_string(n)
state = Dict.put(state, n, value)
{:reply, value, state}
end
end
def start_link do
GenServer.start_link __MODULE__, %{}, name: __MODULE__
end
def print(pid, range) do
_print range, &(__MODULE__.to_string(pid, &1))
end
def print(range) do
_print range, &__MODULE__.to_string/1
end
defp _print(range, fizz_buzz) do
range
|> Stream.map(fizz_buzz)
|> Stream.into(IO.stream(:stdio, :line))
|> Stream.run
end
def to_string(pid, n) do
GenServer.call pid, {:to_string, n}
end
def to_string(n) when is_integer(n) do
:timer.sleep 1000 # Hard work this is ...
_to_string(n, rem(n, 3), rem(n, 5)) <> "\n"
end
defp _to_string(_n, 0, 0), do: "FizzBuzz"
defp _to_string(_n, 0, _), do: "Fizz"
defp _to_string(_n, _, 0), do: "Buzz"
defp _to_string( n, _, _), do: Integer.to_string n
end
# Examples:
require Logger
Logger.debug "Plain Vanilla ..."
FizzBuzz.print 1..15
{:ok, pid} = FizzBuzz.start_link
Logger.debug "FizzBuzz Server, First Run ..."
FizzBuzz.print pid, 1..15
Logger.debug "FizzBuzz Server, Memoized ..."
FizzBuzz.print pid, 1..15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment