2017-02-11 4 views
2

나는 이것이 합리적으로 일반적인 것이라고 확신하지만 그것에 대해서는 아무 것도 찾을 수 없다. (내 인터넷 검색 부는 강하지 않다).목록을 공정하게 나누기

:리스트의 길이가 균일 예로 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 목록의 새로운리스트에 파티션 (위의 예에서을 N 2 일, 3라고 할 수있다). 어떤 유형의 목록에서도 작동해야하며 가능한 한 작은 크기의 하위 목록을 생성해야합니다.

그래서 내가하고 싶은 :

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

또는 한 groupEvery를 사용하여 길이 3의 두 길이 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] 

나는 Haskell로 쉽게 번역 할 수있는 {pseudo, actual} 코드 함수 또는 설명을 원합니다 (ID 변환이 가장 좋습니다!).

감사합니다.

+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