Created
November 1, 2014 00:03
-
-
Save BennyHallett/d75807b90cbf045f86db to your computer and use it in GitHub Desktop.
Tournament Scheduling in Elixir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Scheduler do | |
require Integer | |
@doc """ | |
Generate a number of teams (3 or more) | |
""" | |
def generate_teams(number) when number < 3, do: IO.puts "Need to specify at least 3 teams" | |
def generate_teams(number) do | |
team_names | |
|> Enum.shuffle | |
|> Enum.take(number) | |
end | |
@doc """ | |
Given a list of team names, schedule matches in a round-robin style. | |
Returns an array of rounds, which includes several tuples, one per match. | |
""" | |
def schedule(teams) do | |
teams | |
|> round_out | |
|> build_schedule | |
end | |
defp build_schedule(teams), do: _build_schedule(teams, length(teams)) | |
defp _build_schedule(team, l), do: __build_schedule(Enum.chunk(team, (l/2 |> float_to_int)), [], number_of_rounds(l)) | |
defp __build_schedule(_, output, 0), do: output | |
defp __build_schedule([t1, t2], output, l) do | |
output = [t1, t2] | |
|> generate_matches | |
|> combine_with(output) | |
rotate(t1, t2) | |
|> __build_schedule(output, l - 1) | |
end | |
defp rotate([h1|htail], [a1|atail]) do | |
[x|xt] = Enum.reverse(htail) | |
[ | |
[h1, a1|Enum.reverse(xt)], | |
atail ++ [x] | |
] | |
end | |
defp combine_with(round, output), do: output ++ [round] | |
defp generate_matches([t1, t2]), do: Enum.zip(t1, t2) | |
defp number_of_rounds(number_of_teams), do: (number_of_teams - 1) * 2 | |
defp round_out(teams), do: _round_out(teams, teams |> length |> Integer.is_even) | |
defp _round_out(teams, true), do: teams | |
defp _round_out(teams, false), do: teams ++ [:bye] | |
defp team_names do | |
[ "Aardvarks", "Buffalos", "Carrion", "Ducks", "Elephants", | |
"Fireants", "Geese", "Hunters", "Impala", "Jokers", "Kings", | |
"Lions", "Mice", "Newts", "Orangutans", "Parrots", ] | |
end | |
defp float_to_int(f) do | |
{n, _} = f | |
|> to_string | |
|> Integer.parse | |
n | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment