Current section

Files

Jump to
inplace lib examples josephus.ex
Raw

lib/examples/josephus.ex

defmodule InPlace.Examples.Josephus do
@moduledoc """
https://en.wikipedia.org/wiki/Josephus_problem
"""
alias InPlace.LinkedList
@doc """
Form the circle from N soldiers.
Going clockwise, eliminate every k-th soldier
until only one soldier is left.
"""
def solve(num_soldiers, every_k) do
circle = LinkedList.new(num_soldiers)
Enum.each(1..num_soldiers, fn n -> LinkedList.append(circle, n) end)
{_move_count, kill_sequence} =
LinkedList.iterate(
circle,
fn p, {count_acc, sequence_acc} ->
sequence_acc = if rem(count_acc, every_k) == 0 do
LinkedList.delete_pointer(circle, p)
[p | sequence_acc]
else
sequence_acc
end
{count_acc + 1, sequence_acc}
end,
initial_value: {1, []},
stop_on: fn _ -> LinkedList.size(circle) == 1 end
)
## the survivor and kill sequence
%{
kill_sequence: Enum.reverse(kill_sequence),
survivor: LinkedList.data(circle, LinkedList.head(circle))
}
end
end