Ranking methods: Difference between revisions

Added Haskell
(Added Haskell)
Line 348:
</pre>
 
=={{header|Haskell}}==
<lang Haskell>
import Data.List (groupBy, sort, intercalate)
 
type Item = (Int, String)
type ItemList = [Item]
type ItemGroups = [ItemList]
type RankItem a = (a, Int, String)
type RankItemList a = [RankItem a]
 
-- make sure the input is ordered and grouped by score
prepare :: ItemList -> ItemGroups
prepare = groupBy gf . reverse . sort
where gf (a, _) (b, _) = a == b
 
-- give an item a rank
rank :: Num a => a -> Item -> RankItem a
rank n (a, b) = (n, a, b)
 
-- ranking methods
standard, modified, dense, ordinal :: ItemGroups -> RankItemList Int
 
standard = ms 1 where
ms _ [] = []
ms n (x:xs) = map (rank n) x ++ ms (n + length x) xs
 
modified = md 1 where
md _ [] = []
md n (x:xs) = let l = length x
nl = n + l
nl1 = nl - 1
in map (rank nl1) x ++ md (n + l) xs
 
dense = md 1 where
md _ [] = []
md n (x:xs) = map (rank n) x ++ md (n + 1) xs
 
ordinal = zipWith rank [1..] . concat
 
fractional :: ItemGroups -> RankItemList Double
fractional = mf 1.0 where
mf _ [] = []
mf n (x:xs) = let l = length x
o = take l [n ..]
ld = fromIntegral l
a = sum o / ld
in map (rank a) x ++ mf (n + ld) xs
 
-- sample data
test :: ItemGroups
test = prepare
[ (44, "Solomon")
, (42, "Jason")
, (42, "Errol")
, (41, "Garry")
, (41, "Bernard")
, (41, "Barry")
, (39, "Stephen") ]
 
-- print rank items nicely
nicePrint :: Show a => String -> RankItemList a -> IO ()
nicePrint xs items = do
putStrLn xs
mapM_ np items
putStr "\n"
where np (a, b, c) = putStrLn $ intercalate "\t" [show a, show b, c]
 
main :: IO ()
main = do
nicePrint "Standard:" $ standard test
nicePrint "Modified:" $ modified test
nicePrint "Dense:" $ dense test
nicePrint "Ordinal:" $ ordinal test
nicePrint "Fractional:" $ fractional test
</lang>
Output:
<pre>
Standard:
1 44 Solomon
2 42 Jason
2 42 Errol
4 41 Garry
4 41 Bernard
4 41 Barry
7 39 Stephen
 
Modified:
1 44 Solomon
3 42 Jason
3 42 Errol
6 41 Garry
6 41 Bernard
6 41 Barry
7 39 Stephen
 
Dense:
1 44 Solomon
2 42 Jason
2 42 Errol
3 41 Garry
3 41 Bernard
3 41 Barry
4 39 Stephen
 
Ordinal:
1 44 Solomon
2 42 Jason
3 42 Errol
4 41 Garry
5 41 Bernard
6 41 Barry
7 39 Stephen
 
Fractional:
1.0 44 Solomon
2.5 42 Jason
2.5 42 Errol
5.0 41 Garry
5.0 41 Bernard
5.0 41 Barry
7.0 39 Stephen
</pre>
=={{header|J}}==
Implementation:
Anonymous user