Comment detail

文字列の均等分割 (Nested Flatten)

This comment is reply for 4229 shiro: 文字列分のTrueの後にFalseをいく...(文字列の均等分割). Go to thread root.

いや、そもそも後ろにFalseをくっつける必要が無かった。takeはリストの方が短いと結果も短くしてくれるのね。(Gaucheのtake*の動作)

1
2
3
4
5
6
7
8
import Data.List

divid n cs = snd $ mapAccumL taker cs $ transpose $ slices cs
 where
   slices [] = []
   slices xs = (take n xs):(slices $ drop n xs)
   taker cs []         = (cs, [])
   taker (c:cs) (b:bs) = let (cs',frag) = (taker cs bs) in (cs', c:frag)
私の用意していたものはshiroさんの解と本質的に同じでした。
slices と taker にも汎用性がありそうなのでトップレベルでの定義にしてあります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import Data.List
import qualified System.IO.UTF8 as U

divid :: Int -> [a] -> [[a]]
divid n xs 
  = snd $ mapAccumL ((swap .) . flip splitWith) xs $  transpose $ slices n xs

swap :: (a,b) -> (b,a)
swap (x,y) = (y,x)

splitWith :: [b] -> [a] -> ([a],[a])
splitWith _  [] = ([],[])
splitWith [] xs = ([],xs)
splitWith (x:xs) (y:ys) = case splitWith xs ys of (zs,ws) -> (y:zs,ws)

slices :: Int -> [a] -> [[a]]
slices n = unfoldr phi
  where 
    phi [] = Nothing
    phi xs = Just $ splitAt n xs

Index

Feed

Other

Link

Pathtraq

loading...