Skip to content

Commit

Permalink
hardcoded prng history keeps track of the history it uses
Browse files Browse the repository at this point in the history
  • Loading branch information
CoderDennis committed Jan 2, 2024
1 parent 4cd1858 commit 4ae5d37
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 9 deletions.
14 changes: 7 additions & 7 deletions lib/decorum/prng.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,29 @@ defmodule Decorum.Prng do
defmodule Hardcoded do
@moduledoc false
@type t :: %__MODULE__{
wholeHistory: Decorum.History.t(),
history: Decorum.History.t(),
unusedHistory: Decorum.History.t()
}

@enforce_keys [:wholeHistory, :unusedHistory]
defstruct [:wholeHistory, :unusedHistory]
@enforce_keys [:history, :unusedHistory]
defstruct [:history, :unusedHistory]

@spec new(history :: Decorum.History.t()) :: t
def new(history) when is_list(history) do
%__MODULE__{wholeHistory: history, unusedHistory: history}
%__MODULE__{history: [], unusedHistory: history}
end

@spec next!(prng :: t()) :: {non_neg_integer(), t()}
def next!(%__MODULE__{unusedHistory: []} = _prng) do
raise EmptyHistoryError, "PRNG history is empty"
end

def next!(%__MODULE__{unusedHistory: [value | rest]} = prng) do
{value, %__MODULE__{prng | unusedHistory: rest}}
def next!(%__MODULE__{history: history, unusedHistory: [value | rest]} = prng) do
{value, %__MODULE__{prng | history: [value | history], unusedHistory: rest}}
end

@spec get_history(prng :: t()) :: Decorum.History.t()
def get_history(%__MODULE__{wholeHistory: history}), do: history
def get_history(%__MODULE__{history: history}), do: Enum.reverse(history)
end

@spec random() :: t()
Expand Down
12 changes: 10 additions & 2 deletions test/prng_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule PrngTest do
end

test "hardcoded Prng replays the given history" do
history = Enum.to_list(100..150)
history = Enum.to_list(101..150)

{values, _prng} = get_values(Prng.hardcoded(history), 50)

Expand All @@ -36,9 +36,17 @@ defmodule PrngTest do
assert_raise Decorum.Prng.EmptyHistoryError, fn -> Prng.next!(prng) end
end

test "hardcoded Prng keeps track of the history it uses" do
history = Enum.to_list(50..70)

{values, prng} = get_values(Prng.hardcoded(history), 10)

assert Prng.get_history(prng) == values
end

@spec get_values(prng :: Prng.t(), count :: non_neg_integer()) :: {non_neg_integer(), Prng.t()}
def get_values(prng, count) do
0..count
1..count
|> Enum.reduce({[], prng}, fn _, {list, prng} ->
{value, new_prng} = Prng.next!(prng)
{list ++ [value], new_prng}
Expand Down

0 comments on commit 4ae5d37

Please sign in to comment.