import Data.List ( sortOn, unfoldr )
import Data.Bifunctor ( Bifunctor(first, bimap) )
import Data.Ord ( Down(Down) )
type Gold = Int
-- ランク1がボス2が次のボス ...
type Rank = Int
type Pirate = (Gold, Rank)
-- 配分を考える
shareStep :: Gold -> [Pirate] -> [Pirate]
shareStep g [] = [(g, 1)]
shareStep g pirates =
(g - golds, 1):(proponents ++ opponents)
where
-- 安い順に並び替え、過半数をとれるように分割
(cheapers, highers) = splitAt (majorityNum (length pirates)) $ sortOn fst pirates
proponents = map (bimap (\x -> if x >= g then x else succ x) succ) cheapers -- +1金貨で買収して位を下げる
opponents = map (\(_, r) -> (0, succ r)) highers -- 金貨没収して位を下げる
golds = sum $ map fst proponents
-- 過半数+1で可決にする
majorityNum :: Int -> Int
majorityNum len = len `div` 2 + len `mod` 2
-- majorityNum len = len `div` 2 こうすれば過半数可決の方になる
-- 末尾再帰で考える
share :: Gold -> Int -> [Pirate] -> [Pirate]
share g n pirates
-- マイナスになったら終わる
| any (\x -> fst x < 0) pirates = share g (n-1) []
-- 基底
| length pirates == n = pirates
| otherwise = share g n (shareStep g pirates)
-- 回答
solve :: Gold -> Int -> [Pirate]
solve g n = sortOn snd $ share g n []
print $ solve 100 5