Fun with a Functional Programming Interview Question
danielbmarkham.com
danielbmarkham.com
Prelude> :m Data.List
Prelude Data.List> let f xs = [(head ys, length ys) | ys <- group xs]
Prelude Data.List> f "aaaabbbcca"
[('a',4),('b',3),('c',2),('a',1)]
Of course using the "group" function instead of programming it myself is cheating a bit ... "aaaabbbcca" |> String.codepoints() |> Enum.chunk_by(& &1) |> Enum.map(&{hd(&1), length(&1)}) map (head &&& length) . group
(Although in an actual full program, there would be other considerations (what considerations those are depends on the program being written), and in a full program I probably would not be using Haskell, but rather C.) runLengthEncode :: String -> [(Char, Int)]
runLengthEncode [] = []
runLengthEncode input =
let
chFirst = head input
zipped = zip input $ chFirst : input
in
rle zipped (chFirst, 0)
where
rle :: [(Char, Char)] -> (Char, Int) -> [(Char, Int)]
rle [] (ch, count) = [(ch, count)]
rle ((ch1, ch2) : cs) (ch, count) =
if ch1 == ch2 then
rle cs (ch1, count + 1)
else
(ch2, count) : rle cs (ch1, 1) [(m.group(1), len(m.group()))
for m in re.finditer(r"([a-z])\1*", “aaaabbbcca") import itertools
[(c, len(list(it))) for (c, it) in itertools.groupby("aaaabbbcca")]
It's not the first time I've wanted def ilen(it):
return sum(1 for _ in it)
as part of itertools. Which would make the second line be: [(c, itertools.ilen(it)) for (c, it) in itertools.groupby("aaaabbbcca")]
Rejected many times, eg, from 2010: https://bugs.python.org/issue9547 .(set 'L '()) (dolist (s (explode "aaaabbbcca")) (if (!= (ref-all s L) '((0 0))) (push (list s 1) L) (inc (L 0 1)))) (print (reverse L))