2012-01-06 42 views
10

Đối với những người có tâm trí đáng ngờ, đây không phải là bài tập về nhà, chỉ tò mò thôi.Danh sách vô hạn các quầy vô hạn

Với một bảng chữ cái hữu hạn, có thể xây dựng một danh sách các từ dài vô hạn được làm từ bảng chữ cái theo thứ tự ngược lại không?

ví dụ cho bảng chữ cái "ab"

là nó có thể để xây dựng danh sách:

["aaaaaa...", "baaaaa...", "abaaaa...", "bbaaaa...", "aabaaa...", ...] 

nơi ... đại diện cho danh sách (và danh sách liệt kê) kéo dài đến chiều dài vô hạn.

Một nỗ lực ngây thơ là:

counters alphabet = [c:ounter | ounter <- counters alphabet, c <- alphabet] 

nhưng điều này không làm việc kể từ khi nó bị bỏ đệ quy. Tất nhiên, với một phiên bản làm việc, nếu bạn cố in kết quả, bạn sẽ chỉ thấy phần tử đầu tiên được in dưới dạng danh sách vô hạn của phần tử đầu tiên từ bảng chữ cái. Tuy nhiên, bạn sẽ có thể làm điều này:

mapM_ (print . take 2) . take 4 . counters $ "ab" 

và xem kết quả:

aa 
ba 
ab 
bb 
+3

bạn nhận thức được có uncountably nhiều từ, do đó danh sách sẽ không bao gồm tất cả trong số họ? – sdcvvc

+0

không phải là có một đẳng cấu cho tập hợp các số nguyên dương? A ở bên phải của b cuối cùng giống như số 0 đứng đầu trong một số nguyên – pat

+2

Có, nhưng bạn đã viết trong câu hỏi "tất cả các từ dài vô hạn"; nó không phải tất cả, chỉ có những người được tạo thành từ "a" từ một số điểm. – sdcvvc

Trả lời

11

Tại sao không fix?

ghci> let bar = let foo ~(st:sts) = [c:st | c <- "ab"] ++ foo sts in fix foo 
ghci> take 5 . map (take 5) $ bar 
["aaaaa","baaaa","abaaa","bbaaa","aabaa"] 
take 10 . map (take 5) $ bar 
["aaaaa","baaaa","abaaa","bbaaa","aabaa","babaa","abbaa","bbbaa","aaaba","baaba"] 
+0

Ngọt ngào! Tôi đã đi đến nhận thức rằng một mô hình lười biếng là cần thiết vì nó không phải là cách khác decidable cho dù kết quả là không có sản phẩm nào. – pat

7

Có lẽ không phải là giải pháp hiệu quả nhất, nhưng ít nhất nó hoạt động:

counters alphabet = map f [0..] 
    where f n = let (q, r) = quotRem n (length alphabet) in alphabet !! r : f q 
> take 10 $ map (take 5) $ counters "ab" 
["aaaaa","baaaa","abaaa","bbaaa","aabaa","babaa","abbaa","bbbaa","aaaba","baaba"] 
1

Tiến trình trông giống như mã hóa số cơ sở-N với số lần đào ít quan trọng nhất nó ở bên trái, vì vậy chúng ta có thể tiếp cận nó như

  1. Thực hiện một "căn N" chức năng sử dụng fbảng chữ cái của bạn như các chữ cái.
  2. mapf đến [0..]
  3. Thêm repeat $ head alphabets vào từng phần tử trong danh sách.
6

Bạn có thể tìm ra phương pháp sau đây gây cười/khó hiểu:

duplicates s ss = cycle ss : duplicates s (ss >>= \c -> s >> [c]) 
counters = transpose . join duplicates 

này xuất phát từ quan sát rằng các chữ cái đầu tiên theo mô hình "ababab...", các chữ cái thứ hai theo mô hình "aabbaabbaabb...", các chữ cái thứ ba theo mẫu "aaaabbbbaaaabbbb...", v.v.

+0

Rất đẹp. +1 chắc chắn. –

2

Điều này thì sao?

[email protected](a:as) = a:('b':a):concatMap (\x -> ['a':x,'b':x]) as where a = ['a','a'..] 

Cũng (\x -> ['a':x,'b':x]) thể được viết bằng Applicative như ([('a':),('b':)] <*>) . pure nếu bạn coi nó là tao nhã hơn.

1

Tuy nhiên, một phiên bản dựa trên ý tưởng của Daniel:

counters = transpose $ map cycle $ iterate (>>= \x -> [x,x]) "ab" 
+0

Yêu sự đơn giản! Cách tuyệt vời để tạo ra các từ từ bất kỳ bảng chữ cái nào! Đối với bất kỳ ai thắc mắc, '(>> = \ x -> [x, x])' bằng 'concat. bản đồ (\ x -> [x, x]) 'cho danh sách. Do đó sự phức tạp là tối ưu là tốt. –

Các vấn đề liên quan