Infinite list of infinite counters

亡梦爱人 提交于 2019-12-21 09:16:58

问题


For those with suspicious minds, this is not homework, just curious.

Given a finite alphabet, is it possible to construct a list of infinitely long words made from the alphabet in reverse lexographic order?

i.e. given the alphabet "ab"

is it possible to construct the list:

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

where ... represents the list (and list of lists) extending to infinite length.

A naïve attempt is:

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

but this doesn't work since it is left recursive.

Of course, with a working version, if you tried to print the result, you would only see the first element being printed as an infinite list of the first element from the alphabet. However, you should be able to do this:

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

and see the output:

aa
ba
ab
bb

回答1:


Why not fix it?

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"]



回答2:


Probably not the most efficient solution, but at least it works:

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"]



回答3:


You may find the following approach amusing/confusing:

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

This comes from the observation that the first letters follow the pattern "ababab...", the second letters follow the pattern "aabbaabbaabb...", the third letters follow the pattern "aaaabbbbaaaabbbb...", etc.




回答4:


What about this?

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

Also (\x -> ['a':x,'b':x]) can be written in Applicative as ([('a':),('b':)] <*>) . pure if you consider it to be more elegant.




回答5:


The progression looks like encoding a base-N number with the least-significant-digit on the left, so we could approach it as

  1. Make a "to base N" function f using your alphabets as the letters.
  2. map f to [0..]
  3. Append repeat $ head alphabets to each element of the list.



回答6:


Yet another version based on Daniel's idea:

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


来源:https://stackoverflow.com/questions/8763361/infinite-list-of-infinite-counters

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!