Ranking methods: Difference between revisions
Content added Content deleted
m (→{{header|Scala}}: Comments) |
(Added Haskell) |
||
Line 348: | Line 348: | ||
</pre> |
</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}}== |
=={{header|J}}== |
||
Implementation: |
Implementation: |