2017-02-11 8 views
2

これはかなり一般的なことだと確信していますが、私はそれについて何も見つけることができません(私のinternet-search-fuは強くない)。公平にリストを分割する

:リストの長さが均等にいくつかの例はNで割り切れない場合

IはNよりも小さい最終的なサブリストを持つグループN個の要素それぞれのリストのリストにリストをすることができる機能を有します

groupEvery 2 [1,2,3,4]    = [[1,2],[3,4]] 
groupEvery 4 [1,2,3,4,5,6,7,8,9,10] = [[1,2,3,4], [5,6,7,8], [9,10]] 

私がしたいことリストと正の整数Nを取ることである(上記の例でNは2と3であると言うことができる)とnはリストの新しいリストにそれを分割します。どのようなタイプのリストでも動作し、可能な限り小さなサイズのサブリストを生成する必要があります。

だから私は持っているしたいと思います:

fairPartition 3 [1,2,3,4,5,6,7,8,9,10] = [[1,2,3,4], [5,6,7], [8,9,10]] 

それとも限りgroupEveryを使用して長さ3の2及び長さ4

素朴な試みの一つがあるとして、サブリストの任意の組み合わせ:

fairPartition :: Int -> [a] -> [[a]] 
fairPartition n xs = groupEvery ((length xs `div` n) + 1) xs 

fairPartition 4 [1..10] = [[1,2,3],[4,5,6],[7,8,9],[10]] 

(3,3,3,1)は長さの公平な分布ではありません。また、小さな長さのリストでは、適切な数のサブリストを返しません。

# Haskell, at GHCi 
*Main> let size = 4 in map (\l -> length . fairPartition 4 $ [1..l]) [size..25] 
[2,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4] 

ハスケルに簡単に翻訳可能な{擬似、実際の}コード機能や説明が欲しいです(アイデンティティ翻訳は最高です)!

ありがとうございました。

+2

「転置」についてはどうですか。 groupEvery n'?注文事項またはリスト要素はセットとして扱うことができますか? – chi

+0

いいえ、注文は私にとっては問題ではないので、実際にはそう思っています。ありがとう!私は好奇心と一般性のための注文問題のソリューションを見たいと思いますが。 – Jxek

答えて

3

splitパッケージのsplitPlaces関数を使用することができます。

import Data.List.Split 

fairPartition n xs = case length xs `quotRem` n of 
    (q, r) -> splitPlaces (replicate r (q+1) ++ replicate (n-r) q) xs 
+0

ニース。私はこれを探していた(splitPlaces)。私はそれを逃したと信じられない。 – Alec

関連する問題