{-
Round-robin Scheduling Algorithm [Simple]
<https://e...content-available-to-author-only...a.org/wiki/Round-robin_tournament#Scheduling_algorithm>
An algorithm for creates a fair schedule.
Usage:
- list is a collection (list) of the participants
Example, [1, 2, 3, 4]
printOut [1, 2, 3, 4]
=> Round 1
1 vs 4
2 vs 3
Round 2
1 vs 3
4 vs 2
Round 3
1 vs 2
3 vs 4
NOTE: This algorithm will be improved later using Berger tables.
-}
module Main where
-- Rotate participants on a List
rotater :: [ a] -> [ a]
rotater list =
left' = (head left) : (head right) : (init . tail) left
in left' ++ (reverse right' )
-- Create the schedule. Here is the main Round-robin Schedule Algorithm
schedulizer :: [ a] -> [ [ ( a, a) ] ]
schedulizer list
= makesSchedule list
( length list
) ( - 1 ) where
makesSchedule
:: [ a
] -> Int -> Int -> [ [ ( a
, a
) ] ] makesSchedule _ _ 0 = [ ]
makesSchedule list n games =
let games' = if games == (-1)
then do
if even n then (n - 1) else n
else games
middle = n `div` 2
divide = splitAt middle list
left = fst divide
right = if even n
then (reverse . snd) divide
else (reverse . init . snd) divide
zipped = zip left right
in [zipped] ++ makesSchedule (rotater list) n (games' - 1 )
-- Collect data in one round
collect [ ] = [ ]
collect ( x:xs) =
in [ ( show home
) ++ " vs " ++ ( show away
) ] ++ collect xs
-- Beautify the Output
beautifyOut list = beautifySchedule ( schedulizer list) 0 ( - 1 )
where
beautifySchedule _ _ 0 = [ ]
beautifySchedule list i rounds =
let rounds' = if rounds == (-1)
then do
let n = length list
if even n then (n - 1) else n
else rounds
play = (unlines . collect) (list !! i)
in ([ "Round " ++ (show $ i + 1) ++ "\n " ++ play]
++ beautifySchedule list (i + 1) (rounds' - 1 ) )
-- Print out the result
printOut
:: ( Show a
) => [ a
] -> IO ( ) printOut list =
let schedule = beautifyOut list
main = do
let list = [ 1 .. 14 ]
printOut list
ey0KICAgIFJvdW5kLXJvYmluIFNjaGVkdWxpbmcgQWxnb3JpdGhtIFtTaW1wbGVdCiAgICA8aHR0cHM6Ly9lLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5hLm9yZy93aWtpL1JvdW5kLXJvYmluX3RvdXJuYW1lbnQjU2NoZWR1bGluZ19hbGdvcml0aG0+CgogICAgQW4gYWxnb3JpdGhtIGZvciBjcmVhdGVzIGEgZmFpciBzY2hlZHVsZS4KCiAgICBVc2FnZToKICAgIC0gbGlzdCBpcyBhIGNvbGxlY3Rpb24gKGxpc3QpIG9mIHRoZSBwYXJ0aWNpcGFudHMKCiAgICBFeGFtcGxlLCBbMSwgMiwgMywgNF0KCiAgICBwcmludE91dCBbMSwgMiwgMywgNF0KICAgID0+ICBSb3VuZCAxCiAgICAgICAgMSB2cyA0CiAgICAgICAgMiB2cyAzCgogICAgICAgIFJvdW5kIDIKICAgICAgICAxIHZzIDMKICAgICAgICA0IHZzIDIKCiAgICAgICAgUm91bmQgMwogICAgICAgIDEgdnMgMgogICAgICAgIDMgdnMgNAoKICAgIE5PVEU6IFRoaXMgYWxnb3JpdGhtIHdpbGwgYmUgaW1wcm92ZWQgbGF0ZXIgdXNpbmcgQmVyZ2VyIHRhYmxlcy4KLX0KCm1vZHVsZSBNYWluIHdoZXJlCgogIC0tIFJvdGF0ZSBwYXJ0aWNpcGFudHMgb24gYSBMaXN0CiAgcm90YXRlciA6OiBbYV0gLT4gW2FdCiAgcm90YXRlciBsaXN0ID0KICAgIGxldCBuICAgICAgPSBsZW5ndGggbGlzdAogICAgICAgIG1pZGRsZSA9IG4gYGRpdmAgMgogICAgICAgIGRpdmlkZSA9IHNwbGl0QXQgbWlkZGxlIGxpc3QKICAgICAgICBsZWZ0ICAgPSBmc3QgZGl2aWRlCiAgICAgICAgcmlnaHQgID0gKHJldmVyc2UgLiBzbmQpIGRpdmlkZQogICAgICAgIGxlZnQnICA9IChoZWFkIGxlZnQpIDogKGhlYWQgcmlnaHQpIDogKGluaXQgLiB0YWlsKSBsZWZ0CiAgICAgICAgcmlnaHQnID0gKHRhaWwgcmlnaHQpICsrIFtsYXN0IGxlZnRdCiAgICBpbiBsZWZ0JyArKyAocmV2ZXJzZSByaWdodCcpCgogIC0tIENyZWF0ZSB0aGUgc2NoZWR1bGUuIEhlcmUgaXMgdGhlIG1haW4gUm91bmQtcm9iaW4gU2NoZWR1bGUgQWxnb3JpdGhtCiAgc2NoZWR1bGl6ZXIgOjogW2FdIC0+IFtbKGEsIGEpXV0KICBzY2hlZHVsaXplciBsaXN0ID0gbWFrZXNTY2hlZHVsZSBsaXN0IChsZW5ndGggbGlzdCkgKC0xKQogICAgd2hlcmUKICAgICAgbWFrZXNTY2hlZHVsZSA6OiBbYV0gLT4gSW50IC0+IEludCAtPiBbWyhhLCBhKV1dCiAgICAgIG1ha2VzU2NoZWR1bGUgXyBfIDAgICAgICAgID0gW10KICAgICAgbWFrZXNTY2hlZHVsZSBsaXN0IG4gZ2FtZXMgPQogICAgICAgIGxldCBnYW1lcycgID0gaWYgZ2FtZXMgPT0gKC0xKQogICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZXZlbiBuIHRoZW4gKG4gLSAxKSBlbHNlIG4KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBnYW1lcwoKICAgICAgICAgICAgbWlkZGxlICA9IG4gYGRpdmAgMgogICAgICAgICAgICBkaXZpZGUgID0gc3BsaXRBdCBtaWRkbGUgbGlzdAoKICAgICAgICAgICAgbGVmdCAgPSBmc3QgZGl2aWRlCiAgICAgICAgICAgIHJpZ2h0ID0gaWYgZXZlbiBuCiAgICAgICAgICAgICAgICAgICAgICAgdGhlbiAocmV2ZXJzZSAuIHNuZCkgZGl2aWRlCiAgICAgICAgICAgICAgICAgICAgICAgZWxzZSAocmV2ZXJzZSAuIGluaXQgLiBzbmQpIGRpdmlkZQoKICAgICAgICAgICAgemlwcGVkID0gemlwIGxlZnQgcmlnaHQKICAgICAgICBpbiBbemlwcGVkXSArKyBtYWtlc1NjaGVkdWxlIChyb3RhdGVyIGxpc3QpIG4gKGdhbWVzJyAtIDEpCgogIC0tIENvbGxlY3QgZGF0YSBpbiBvbmUgcm91bmQKICBjb2xsZWN0IDo6IChTaG93IGEpID0+IFsoYSwgYSldIC0+IFtTdHJpbmddCiAgY29sbGVjdCBbXSAgICAgPSBbXQogIGNvbGxlY3QgKHg6eHMpID0KICAgIGxldCBob21lID0gZnN0IHgKICAgICAgICBhd2F5ID0gc25kIHgKICAgIGluIFsoc2hvdyBob21lKSArKyAiIHZzICIgKysgKHNob3cgYXdheSldICsrIGNvbGxlY3QgeHMKCiAgLS0gQmVhdXRpZnkgdGhlIE91dHB1dAogIGJlYXV0aWZ5T3V0IDo6IChTaG93IGEpID0+IFthXSAtPiBbU3RyaW5nXQogIGJlYXV0aWZ5T3V0IGxpc3QgPSBiZWF1dGlmeVNjaGVkdWxlIChzY2hlZHVsaXplciBsaXN0KSAwICgtMSkKICAgIHdoZXJlCiAgICAgIGJlYXV0aWZ5U2NoZWR1bGUgOjogKFNob3cgYSkgPT4gW1soYSwgYSldXSAtPiBJbnQgLT4gSW50IC0+IFtTdHJpbmddCiAgICAgIGJlYXV0aWZ5U2NoZWR1bGUgXyBfIDAgICAgICAgICA9IFtdCiAgICAgIGJlYXV0aWZ5U2NoZWR1bGUgbGlzdCBpIHJvdW5kcyA9CiAgICAgICAgbGV0IHJvdW5kcycgPSBpZiByb3VuZHMgPT0gKC0xKQogICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG4gPSBsZW5ndGggbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGV2ZW4gbiB0aGVuIChuIC0gMSkgZWxzZSBuCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugcm91bmRzCiAgICAgICAgICAgIHBsYXkgICAgPSAodW5saW5lcyAuIGNvbGxlY3QpIChsaXN0ICEhIGkpCgogICAgICAgIGluIChbICJSb3VuZCAiICsrIChzaG93ICQgaSArIDEpICsrICJcbiIgKysgcGxheV0KICAgICAgICAgICArKyBiZWF1dGlmeVNjaGVkdWxlIGxpc3QgKGkgKyAxKSAocm91bmRzJyAtIDEpKQoKICAtLSBQcmludCBvdXQgdGhlIHJlc3VsdAogIHByaW50T3V0IDo6IChTaG93IGEpID0+IFthXSAtPiBJTyAoKQogIHByaW50T3V0IGxpc3QgPQogICAgbGV0IHNjaGVkdWxlID0gYmVhdXRpZnlPdXQgbGlzdAogICAgaW4gKHB1dFN0ciAuIHVubGluZXMpIHNjaGVkdWxlCgogIG1haW4gPSBkbwogICAgbGV0IGxpc3QgPSBbMS4uMTRdCiAgICBwcmludE91dCBsaXN0