问题
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
- Make a "to base N" function
f
using your alphabets as the letters. map
f
to[0..]
- 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