Skip to content

Instantly share code, notes, and snippets.

@BennyHallett
Created November 1, 2014 00:03
Show Gist options
  • Save BennyHallett/d75807b90cbf045f86db to your computer and use it in GitHub Desktop.
Save BennyHallett/d75807b90cbf045f86db to your computer and use it in GitHub Desktop.
Tournament Scheduling in Elixir
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