動くには動くというだけ。
import List type PartyNumber = Int numberOfSeat = 100 numberOfVotes = [123, 4, 56, 78] main = do print $ result $ numberOfWinners $ (winners numberOfSeat) $ concat $ markedDhondtTable $ dhondtTable numberOfVotes numberOfSeat result :: [(PartyNumber, Int)] -> [Int] result xs = map (numberOfWinnersAtPartyNumber xs) [1..length numberOfVotes] -- 政党番号に対応した当選数 numberOfWinnersAtPartyNumber :: [(PartyNumber, Int)] -> PartyNumber -> Int numberOfWinnersAtPartyNumber xs n = let numberOfWinner = filter ((\a (b, c) -> a == b)(n)) xs in if numberOfWinner /= [] then (snd.head) numberOfWinner else 0 -- 政党番号別当選者数 numberOfWinners :: [(Double, PartyNumber)] -> [(PartyNumber, Int)] numberOfWinners [] = [] numberOfWinners xs = let top = snd $ head xs exceptTop = filter ((\t (d,n) -> n /= t)(top)) xs nOfw = length xs - length exceptTop in (top, nOfw) : (numberOfWinners exceptTop) -- 当選者 :: 当選者数 -> 得票リスト -> 当選者得票リスト winners :: (Ord a) => Int -> [a] -> [a] winners n xs = take n $ reverse $ List.sort xs -- ドント表に政党番号を付ける markedDhondtTable :: [[Double]] -> [[(Double, PartyNumber)]] markedDhondtTable xs = map markedPartyNumber (zip xs [1..]) -- 政党番号を付ける markedPartyNumber :: ([Double], PartyNumber) -> [(Double, PartyNumber)] markedPartyNumber (xs, n) = map ((\n m->(m,n))(n)) xs -- 得票数と定数からドント表を作成する dhondtTable :: [Int] -> Int -> [[Double]] dhondtTable ns n = map (dhondtList n) ns -- 定数と得票数を元に割った得票数のリストを返す dhondtList :: Int -> Int -> [Double] dhondtList seat vote = map (\n -> fromIntegral(vote) / fromIntegral(n)) [1..seat]