2014-04-29 1 views
0

, K-1하나10으로 나열, ..., 0 하나K제로리스트와 하스켈 그들은 될 수 있도록 느슨하게 회수 되었습니까?게으른 목록은 하나 <strong>K</strong><em>하나</em> 및 <strong>0</strong><em>제로</em>와리스트의리스트를 구현하는 것이 어떻게

예를 들어 만약 K = 3에 대한 조언

generate_list 3 = [[1,1,1],[0,1,1],[1,0,1],[1,1,0],[0,0,1],[0,1,0],[1,0,0],[0,0,0]] 

감사 bheklilr. 여기 내 솔루션입니다 :

generate k = take (2^k) $ foldl (\x y -> zipWith (:) y x) (map (\x->[x]) (head rows)) (tail rows) 
     where 
      rows = map cycle $ map pattern [0..k-1] 
      pattern i = replicate (2^i) 1 ++ replicate (2^i) 0 

그러나 문제가있다 :

generate_list 3 = [[1,1,1], [0,1,1], [1,0,1], [1,1,0], [0,0,1], [0,1,0], [1,0,0], [0,0,0]] 
generate 3 = [[1,1,1], [1,1,0], [1,0,1], [1,0,0], [0,1,1], [0,1,0], [0,0,1], [0,0,0]] 

generate 3 !! 3 = [1,0,0] - it contains 1 one 
generate_list 3 !! 3 = [1,1,0] - it contain 2 one 

그래서 generate_list 출력 순서에서 내 작업 순서가 중요하고 [1,1,0][1,0,0] 앞에 와야합니다.

+0

지금까지 시도한 내용은 무엇입니까? 시도한 코드를 보여줄 수 있습니까, 아니면 'Data.List'와 같이 사용하려고 시도한 라이브러리를 말할 수 있습니까? – bheklilr

+0

[진리 테이블] (http://en.wikipedia.org/wiki/Truth_table)을 만드는 것과 이것이 갖는 관계에 대해 생각해 보셨습니까? 손으로 채우는 아주 간단한 알고리즘이 있습니다. 어떻게 코드로 변환 할 수 있습니까? – bheklilr

+0

나는 반전 된 목록을 생성하고 싶습니다. 진리를 만들고 그것을 뒤집어 놓으면 나는 게으름을 잃을 것입니다. – kunteynir

답변

1

Data.List의 일부 기능을 사용하면 쉽게 해결할 수 있습니다. 귀하의 기능이 패턴 및 자연 순서대로 이어지는 대신

[[1,1,1], [1,1,0], [1,0,1], [1,0,0], [0,1,1], [0,1,0], [0,0,1], [0,0,0]] 

을 생성해야 함을 지적하겠습니다.

이 문제의 두 부분으로, 반복 횟수가 1과 0 인 목록 (예 : [0, 1, 0, 1, ..], [0, 0, 1, 1, 0, 0, 1, 1, ..] 등)을 생성 한 다음 올바르게 결합합니다.

첫 번째 문제의 경우 replicate 기능이 매우 편리합니다. 당신은 쉽게 출력 [0, 1] 것, i = 0에 대한 그래서

2^i이 반복 자릿수가
replicate (2^i) 0 ++ replicate (2^i) 1 

와 기본 패턴을 생성 할 수 있으며, i = 3를 들어, 출력 [0, 0, 0, 0, 1, 1, 1, 1]는 것. 반복 자체를 반복, 무한 스트림이 기본 패턴을 설정합니다 Data.List의 기능이 있습니다

, 당신은 자신을 발견 할 것이다 (힌트 :이 유형 서명 [a] -> [a]hoogle있다). 이 함수는 무한한리스트를 생성하기 때문에 take ???으로 크기를 줄여야합니다. 여기서 ???은 트리밍 할 길이입니다. 이것으로, [진리 테이블]의 각 열을 생성 할 수 있어야하지만 0부터 시작하여 1로 시작하고 싶습니다. 1s를 먼저 생성하는 방법을 알아낼 수 있습니까?

각 열을 생성하기위한 스 니펫을 만들었으므로 각 열을 "압축"하는 기능이 필요하지만 내장 된 zip 기능은 특정 번호에서만 작동하기 때문에 여기서는 작동하지 않습니다 목록의 한 번에. n-way zip으로 설명 할 수있는 또 다른 함수가 있습니까?

이것은 시작해야하지만 몇 가지 차이점이 있습니다. 당신이 다시 갇히게되면, 단지 당신이 붙어있는 것에 대해 의견을 말하고 말할 수는 있지만, 당신이 할 수있는 한이 문제를 스스로 해결해야합니다.

1

k가 1이고 0 인 목록, k-1이 1 인 목록, 0이있는 목록, 하스켈에서 0과 k가있는 목록을 검색 할 수있는 방법 느슨하게?

mn 개의 0으로 목록을 만드는 함수를 작성하십시오. 그런 다음이 함수를 k 번 (k0, 그 다음 k-11 등) 및 ++이라고합니다.

1

여기에 적용 할 수있는 펑터를 사용하는 해결책이 있습니다.

generate 0 = [[]] 
generate k = (:) <$> [1,0] <*> generate (k-1) 

이것이 실제로 게으름이라는 것을 어떻게 보여줄지 궁금하십니까?

+2

GHCi에서'let x = generate 3','take 3 x',': print x'로 이것을 쉽게 확인할 수 있습니다. 'x = [1,1,1] : [1,1,0] : [1,0,1] : (_t1 :: [[Integer]])'와 같은 결과를보아야한다. 단지'x'의 처음 세 요소 만 계산하면됩니다. – bheklilr

+0

': print' 명령을 주셔서 감사합니다! 나는 그런 존재가 있는지 몰랐다. –

+0

그러나 이것은 최대로 게으르지 않습니다. 'head (generate (10^8))'는 매우 오랜 시간이 걸립니다. 이것을 해결할 수있는 방법이 있습니다. 입력이 얼마나 큰지에 상관없이 즉각적으로 반응합니다. ;-) – luqui