Ninety-Nine Haskell Problems 8
1to10 11to20 21to30 31to40 51to60 61to70 71to80 81to90 91to99 all Ninety-Nine Haskell Problems
八問目.
8 Problem 8 (**) Eliminate consecutive duplicates of list elements. If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed. Example: * (compress '(a a a a b c c a a d e e e e)) (A B C A D E) Example in Haskell: *Main> compress ['a','a','a','a','b','c','c','a','a','d','e','e','e','e'] ['a','b','c','a','d','e']http://www.haskell.org/haskellwiki/99_questions/1_to_10#Problem_8
で,とりあえず,Haskell/Control structuresで,if文について調べて,できたのが次.
compress (x:(y:[])) = if x == y then [x] else [x, y] compress (x:(y:ys)) = if x == y then compress (y:ys) else ([x] ++ compress (y:ys))
これで実行してみると,
Main> compress [1,1, 2] [1,2] Main> compress [1,2] [1,2] Main> compress [1,1,1,2,2,3,4,4,4,5,1,1,2] [1,2,3,4,5,1,2]
おお,なんかうまくいってる模様.
しかし,
Main> compress ['a','a','a','a','b','c','c','a','a','d','e','e','e','e'] "abcade"
駄目でした.
うーん,一回切り離してから,文字を結合してるから,全部繋がって文字列になっちゃうってわけだな.
と,思ったけど,
Main> ['a','b','c','a','d','e'] "abcade"
ってなるから,いいのかな?どういうこっちゃ.
とりあえず,解答.
Solution: compress :: Eq a => [a] -> [a] compress = map head . group We simply group equal values together (group), then take the head of each. Note that (with GHC) we must give an explicit type to compress otherwise we get: Ambiguous type variable `a' in the constraint: `Eq a' arising from use of `group' Possible cause: the monomorphism restriction applied to the following: compress :: [a] -> [a] Probable fix: give these definition(s) an explicit type signature or use -fno-monomorphism-restriction We can circumvent the monomorphism restriction by writing compress this way (See: section 4.5.4 of the report): compress xs = map head $ group xs An alternative solution is compress [] = [] compress [a] = [a] compress (x : y : xs) = (if x == y then [] else [x]) ++ compress (y : xs)
おう,長いやんけ.
groupが謎なんだけど,とりあえず,mapについて調べる.
map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = f x : map f xshttp://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/src/GHC-Base.html#map
よし,非常にわかりやすい.リストの各要素にfをかけるってことだな.
で,謎なのがgroup.WinHugsで実行してみても,Undefinedとか言われちゃう.
たぶん,WinHugsには含まれてないんだろう.かといって,GHCiでも実行できない.なのにググるとでてくる.もうやだ,よくわからん.
無視!!
で,
compress [] = [] compress [a] = [a] compress (x : y : xs) = (if x == y then [] else [x]) ++ compress (y : xs)
は,少しだけ,僕のつくったのと似てる.でもこっちのほうがわかりやすくていいな.同じ場合は,[]でスルーして,違う場合だけ残すって感じか.しかたないけど,若干くやしい.
おわり.
1to10 11to20 21to30 31to40 51to60 61to70 71to80 81to90 91to99 all Ninety-Nine Haskell Problems