ぷよぷよ19連鎖
ゲーム「ぷよぷよ」で、フィールドの状態がテキストで与えられたとき、消える「ぷよ」を消して次のフィールドの状態を出力するプログラムを書け。
http://okajima.air-nifty.com/b/2011/01/2011-ffac.html
この問題を見たときに、Haskellで解いてみたいと思ったのだが、フラグ等の副作用を使わないうまい書き方が思いつかなくてお蔵入りにしてた。
今回、ふとしたことで方針を思いついたので書いてみた。
import Data.List input = [" GYRR" ,"RYYGYG" ,"GYGYRR" ,"RYGYRG" ,"YGYRYG" ,"GYRYRG" ,"YGYRYR" ,"YGYRYR" ,"YRRGRG" ,"RYGYGG" ,"GRYGYR" ,"GRYGYR" ,"GRYGYR"] h = length input w = length $ head input near (i,j,c) (i',j',c') = c==c' && abs(i'-i)+abs(j'-j)==1 xyc n cs = [(div i n,mod i n,c) | (i,c) <- zip [0..] cs] tr xs = [(j,i,c) | (i,j,c) <- xs] str xs = [c | (_,_,c) <- sort xs] joins xs = foldr f [] [x | x@(_,_,c) <- xs, c/=' ' && c/='\n'] where f x r = let (ok,ng) = partition (any $ near x) r in (x : concat ok) : ng puyo xs = (str $ tr xs) : if xs==ys then [] else puyo ys where j4 = concat [x | x <- joins xs, length x > 3] ys = xyc h $ str [if elem x j4 then (i,-1,' ') else x | x@(i,_,_) <- xs] main = mapM_ putStrLn $ puyo $ tr $ xyc (w+1) $ unlines input