import Data.List
{-
車と人を重要の軽い順に順位をつけます。元のリストの順序は変更したくありません。
※ 人は未実装
-}
{-
質問
1. makeCarRankingをHumanにも使えるように汎用的にするにはどうしたらいいか?
2. makeCarRankingのように全体を見てから全部の要素に値を設定する操作はどうしたらスマートか?
-}
-- 車
data Car
= Car
{ carWeight
:: Int, carRanking
:: Int } deriving Show -- 人間
data Human
= Human
{ humanWeight
:: Int, humanRanking
:: Int } deriving Show
-- 車たち
cars :: [Car]
cars = [Car { carWeight = 10, carRanking = 0 }, Car { carWeight = 5, carRanking = 0 }, Car { carWeight = 20, carRanking = 0 }]
-- 人たち
humans :: [Human]
humans = [Human { humanWeight = 10, humanRanking = 0 }, Human { humanWeight = 5, humanRanking = 0 }, Human { humanWeight = 20, humanRanking = 0 }]
-- 車たちに順位をつける
makeCarRanking :: [Car] -> [Car]
makeCarRanking xs
= map (\c
-> (snd c
)) sortRanked
where -- 順序を元に戻すためにインデックスを付加 [Car] -> [(index, Car)]
zipped
= zip [(1 :: Int)..] xs
-- 重さでソートする
sorted
= sortBy
(\
(_, l
) (_, r
) -> compare (carWeight l
) (carWeight r
)) zipped
-- ランキングを付加 [(index, Car)] -> [(ranking, (index, Car))]
zipRanked
= zip [(1 :: Int)..] sorted
-- Carにランキングを設定 [(ranking, (index, Car))] -> [(index, Car)]
ranked
= map (\
(r
, (i
, c
)) -> (i
, Car
{ carWeight
= (carWeight c
), carRanking
= r
})) zipRanked
-- 元の順序に戻す
sortRanked
= sortBy
(\
(li
, _) (ri
, _) -> compare li ri
) ranked
main = do
aW1wb3J0IERhdGEuTGlzdAoKey0K6LuK44Go5Lq644KS6YeN6KaB44Gu6Lu944GE6aCG44Gr6aCG5L2N44KS44Gk44GR44G+44GZ44CC5YWD44Gu44Oq44K544OI44Gu6aCG5bqP44Gv5aSJ5pu044GX44Gf44GP44GC44KK44G+44Gb44KT44CCCuKAuyDkurrjga/mnKrlrp/oo4UKLX0KCnstCuizquWVjwoxLiBtYWtlQ2FyUmFua2luZ+OCkkh1bWFu44Gr44KC5L2/44GI44KL44KI44GG44Gr5rGO55So55qE44Gr44GZ44KL44Gr44Gv44Gp44GG44GX44Gf44KJ44GE44GE44GL77yfCjIuIG1ha2VDYXJSYW5raW5n44Gu44KI44GG44Gr5YWo5L2T44KS6KaL44Gm44GL44KJ5YWo6YOo44Gu6KaB57Sg44Gr5YCk44KS6Kit5a6a44GZ44KL5pON5L2c44Gv44Gp44GG44GX44Gf44KJ44K544Oe44O844OI44GL77yfCi19CgotLSDou4oKZGF0YSBDYXIgPSBDYXIgeyBjYXJXZWlnaHQgOjogSW50LCBjYXJSYW5raW5nIDo6IEludCB9IGRlcml2aW5nIFNob3cKLS0g5Lq66ZaTCmRhdGEgSHVtYW4gPSBIdW1hbiB7IGh1bWFuV2VpZ2h0IDo6IEludCwgaHVtYW5SYW5raW5nIDo6IEludCB9IGRlcml2aW5nIFNob3cKCi0tIOi7iuOBn+OBoQpjYXJzIDo6IFtDYXJdCmNhcnMgPSBbQ2FyIHsgY2FyV2VpZ2h0ID0gMTAsIGNhclJhbmtpbmcgPSAwIH0sIENhciB7IGNhcldlaWdodCA9IDUsIGNhclJhbmtpbmcgPSAwIH0sIENhciB7IGNhcldlaWdodCA9IDIwLCBjYXJSYW5raW5nID0gMCB9XQotLSDkurrjgZ/jgaEKaHVtYW5zIDo6IFtIdW1hbl0KaHVtYW5zID0gW0h1bWFuIHsgaHVtYW5XZWlnaHQgPSAxMCwgaHVtYW5SYW5raW5nID0gMCB9LCBIdW1hbiB7IGh1bWFuV2VpZ2h0ID0gNSwgaHVtYW5SYW5raW5nID0gMCB9LCBIdW1hbiB7IGh1bWFuV2VpZ2h0ID0gMjAsIGh1bWFuUmFua2luZyA9IDAgfV0KCi0tIOi7iuOBn+OBoeOBq+mghuS9jeOCkuOBpOOBkeOCiwptYWtlQ2FyUmFua2luZyA6OiBbQ2FyXSAtPiBbQ2FyXQptYWtlQ2FyUmFua2luZyB4cyA9IG1hcCAoXGMgLT4gKHNuZCBjKSkgc29ydFJhbmtlZAogIHdoZXJlIC0tIOmghuW6j+OCkuWFg+OBq+aIu+OBmeOBn+OCgeOBq+OCpOODs+ODh+ODg+OCr+OCueOCkuS7mOWKoCBbQ2FyXSAtPiBbKGluZGV4LCBDYXIpXQogICAgICAgIHppcHBlZCA9IHppcCBbKDEgOjogSW50KS4uXSB4cwogICAgICAgIC0tIOmHjeOBleOBp+OCveODvOODiOOBmeOCiwogICAgICAgIHNvcnRlZCA9IHNvcnRCeSAoXChfLCBsKSAoXywgcikgLT4gY29tcGFyZSAoY2FyV2VpZ2h0IGwpIChjYXJXZWlnaHQgcikpIHppcHBlZAogICAgICAgIC0tIOODqeODs+OCreODs+OCsOOCkuS7mOWKoCBbKGluZGV4LCBDYXIpXSAtPiBbKHJhbmtpbmcsIChpbmRleCwgQ2FyKSldCiAgICAgICAgemlwUmFua2VkID0gemlwIFsoMSA6OiBJbnQpLi5dIHNvcnRlZAogICAgICAgIC0tIENhcuOBq+ODqeODs+OCreODs+OCsOOCkuioreWumiBbKHJhbmtpbmcsIChpbmRleCwgQ2FyKSldIC0+IFsoaW5kZXgsIENhcildCiAgICAgICAgcmFua2VkID0gbWFwIChcKHIsIChpLCBjKSkgLT4gKGksIENhciB7IGNhcldlaWdodCA9IChjYXJXZWlnaHQgYyksIGNhclJhbmtpbmcgPSByIH0pKSB6aXBSYW5rZWQKICAgICAgICAtLSDlhYPjga7poIbluo/jgavmiLvjgZkKICAgICAgICBzb3J0UmFua2VkID0gc29ydEJ5IChcKGxpLCBfKSAocmksIF8pIC0+IGNvbXBhcmUgbGkgcmkpIHJhbmtlZAoKbWFpbiA9IGRvCiAgICBwdXRTdHJMbiAkIHNob3cgJCBtYWtlQ2FyUmFua2luZyBjYXJz