import Control.Monad (forM_) data Player = Player { name :: String , rank :: Int , matchLimit :: Int } deriving (Show, Eq) players :: [Player] players = [ Player "orbekk" (-1) 4 , Player "ltsang" (-4) 4 , Player "sebh" 2 4 , Player "fringd" (-1) 4 , Player "sheyrax" (-2) 2 ] remove :: Eq a => a -> [a] -> [a] remove p = filter (/=p) matchPlayers :: [Player] -> [Player] -> ([Player], [(Player, Player)]) matchPlayers [] qs = (qs, []) matchPlayers ps [] = (ps, []) matchPlayers (p:ps) (q:qs) | p == q = matchPlayers (p:ps) qs | otherwise = ([p', q'] ++ s', (p, q) : m') where p' = p { matchLimit = matchLimit p - 1 } q' = q { matchLimit = matchLimit q - 1 } (s', m') = matchPlayers (remove q ps) (remove p qs) main = do let (players', matches) = matchPlayers players players print players' forM_ matches $ \(p, q) -> putStrLn ((name p) ++ " vs. " ++ (name q))