状態処理
PC甲子園、2010年本戦の問題第3問で、セグメント数字表示機への指示の遷移を出力せよ、みたいな問題がありました。
詳しくは公式HPのPDF参照。
これは、Stateモナド使って解けるなーと思い。
モナドやろうやろうと思いつつ、なかなか題材がなかったので、これを機にやってみた
import Control.Monad import Control.Monad.State type SegState = ([Int],[[Int]]) type SegCommand = [[Int]] seg = [[1,1,1,1,1,1,0],--0 [0,1,1,0,0,0,0],--1 [1,1,0,1,1,0,1],--2 [1,1,1,1,0,0,1],--3 [0,1,1,0,0,1,1],--4 [1,0,1,1,0,1,1],--5 [1,0,1,1,1,1,1],--6 [1,1,1,0,0,1,0],--7 [1,1,1,1,1,1,1],--8 [1,1,1,1,0,1,1]]--9 start = ([0,0,0,0,0,0,0],[]) --(切り替えた後のセグメントの状態,切り替えるための指示) order :: [Int]->[Int]->[Int] order [] [] = [] order (a:as) (b:bs) = case a == b of True -> 0:order as bs False -> 1:order as bs deal_input :: [Int] -> State SegState SegCommand deal_input [] = do (_,command) <- get return command deal_input (x:xs) = do (now,command) <- get put (seg!!x,command++[order now (seg!!x)]) deal_input xs main = do n <- getLine cs <- getContents forM_ (evalState (deal_input.map read.take (read n) $ lines cs) start) print
実際の問題とは、出力される数字の順番は逆になっています。
私が問題をちゃんと読んでなかったから笑
本来は、-1を入力するまで処理し続けるようにしないといけないんですが、
それは、昔type the numbersをHaskellで作ったときに実現しているのであれと同様。
自分でやる分には、応用より実際が大事と思っているので。