HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Calculating tournament tables

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
calculatingtournamenttables

Problem

This my first program in Haskell. I'm organizing a ping-pong tournament and I want to calculate a tournament table automatically. The table should contain scores in all games and some statistics (points, wins, losses, balls, ...). The input is hardcoded directly in the Haskell file.

```
import Data.Tuple

players = ["John", "Bob", "David", "Alice"]

type Score = (Int, Int)
type Game = ((String, String), [Score])

games :: [Game]
games = [(("John", "Bob"), [(11, 7), (11, 8), (3, 11)]),
(("John", "David"), [(11, 0), (11, 3)]),
(("David", "Alice"), [(9, 11), (9, 11), (8, 11)]),
(("Alice", "John"), [(11, 0), (11, 0)])]

validScore :: Score -> Bool
validScore (left, right) = (left == 11 && right 11 && right == left - 2) ||
(right == 11 && left 11 && left == right - 2)

winner :: Score -> Bool
winner (left, right) | validScore (left, right) = left > right

wins :: [Score] -> Int
wins xs = length (filter winner xs)

losses :: [Score] -> Int
losses xs = length xs - length (filter winner xs)

gamePoints :: [Score] -> Int
gamePoints xs | wins xs > losses xs = 1
| wins xs Game
swapGame game = (swap (fst game), map swap (snd game))

findGame :: String -> String -> [Game]
findGame player opponent = [game | game [[Game]]
playerGames player = map (findGame player) players

calculate :: ([Score] -> Int) -> String -> Int
calculate f player = sum [f (snd game) | game 1 - gamePoints scores)
playerGoals = calculate (\scores -> sum (map fst scores))
playerMisses = calculate (\scores -> sum (map snd scores))
playerDiff = calculate (\scores -> sum (map fst scores) - sum (map snd scores))

showScore :: Score -> String
showScore (left, right) = show left ++ ":" ++ show right

showScores :: [Score] -> String
showScores [x] = showScore x
showScores (x : xs) = showScore x ++ "," ++ showScores xs

showGames :: [[Game]] -> String
showGames [[]] = " "
showGames [[(_, scores)]] = showScores scores
showGames ([] : games) = "

Solution

I will try to do some review.

wins xs = length (filter winner xs)
=>
wins = length . filter winner


And the same with losses and others:

losses xs = length xs - length (filter winner xs)
=>
losses = length . filter (not . winner)


Manual string concatenation may be simplified:

showScores [x] = showScore x
showScores (x : xs) = showScore x ++ "," ++ showScores xs
=>
showScores = intercalate "," $ map showScore


In some cases forM_ is more readable:

main = mapM_ (\row -> putStrLn (show row)) table
=>
main = forM_ table (\row -> putStrLn (show row))


Or even:

=>
main = mapM_ (putStrLn . show) table

Code Snippets

wins xs = length (filter winner xs)
=>
wins = length . filter winner
losses xs = length xs - length (filter winner xs)
=>
losses = length . filter (not . winner)
showScores [x] = showScore x
showScores (x : xs) = showScore x ++ "," ++ showScores xs
=>
showScores = intercalate "," $ map showScore
main = mapM_ (\row -> putStrLn (show row)) table
=>
main = forM_ table (\row -> putStrLn (show row))
=>
main = mapM_ (putStrLn . show) table

Context

StackExchange Code Review Q#73456, answer score: 5

Revisions (0)

No revisions yet.