I need to generate an infinite list of strings using numbers and letters. The first string should simply be \"a\", then \"b\" through to \"z\", then \"0\" through to \"9\", the
This can be done by getting all combinations for strings of length 1,2,3..., then concating them all together.
I started with a combos function, which returned all list of strings with the given characters and the given length:
combos :: [Char] -> Int -> [String]
The fist case is simple, just turn the input chars into lists:
combos chars 1 = map (:[]) chars
The next case we want 'aa', 'ab', 'ac'... to 'zx', 'zy', 'zz'. This is the same as map ("a" ++) ["a", "b", "c"...] ++ map ("b" ++) ["a","b",...]
right up to map ("z" ++) ["a","b"...]
.
["a".."z"]
is the same as combos chars 1
. That function can be written as:
combos chars 2 = concatMap (\front -> map (front ++) (combos chars 1)) (combos chars 1)
The next case we want 'aaa', 'aab', ... 'zzy', 'zzz'. This is actually very similar to combos 2, except we are using as the front combos chars 2
instead of combos chars 1
:
combos chars 3 = concatMap (\front -> map (front ++) (combos chars 1)) (combos chars 2)
(note the combos chars 1
doesn't change, that just gives us the list of one character strings to append to the end.)
See the pattern here? It can now be generalized for all n as:
combos :: [Char] -> Int -> [String]
combos chars 1 = map (:[]) chars
combos chars n = concatMap (\front -> map (front ++) (combos chars 1)) $ combos chars (n - 1)
Finally, to get the infinite list of all strings, just concat all the results of combos together with the required characters and all lengths:
allCombos :: [String]
allCombos = concatMap (combos (['a'..'z'] ++ ['0'..'9'])) [1..]
Example output:
> take 100 allCombos
["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","aa","ab","ac","ad","ae","af","ag","ah","ai","aj","ak","al","am","an","ao","ap","aq","ar","as","at","au","av","aw","ax","ay","az","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","ba","bb","bc","bd","be","bf","bg","bh","bi","bj","bk","bl","bm","bn","bo","bp","bq","br","bs","bt","bu","bv","bw","bx","by","bz","b0","b1"]