Problem:
JOIとIOI

問題

与えられた文字列内の連続する3文字が，JOIまたはIOIという並びになっている個所がそれぞれ何個所あるのかを数え上げるプログラムを作成せよ．文字列はアルファベットの大文字だけからなる．例えば下図の「JOIOIOI」という文字列にはJOIが1個所，IOIが2個所に含まれている．

入力

入力は複数のデータセットからなる．各データセットは1行であり，10000文字以下のアルファベットの大文字からなる．入力は EOF で終了する.

データセットの数は 5 を超えない．

出力

データセットごとに, 1行目に見つかったJOIの個数，2行目に見つかったIOIの個数をそれぞれ出力せよ．

入出力例

入力例

JOIJOI
JOIOIOIOI
JOIOIJOINXNXJIOIOIOJ

出力例

2
0
1
3
2
3

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative ((<$>), (<*>))
import Control.Monad
import Data.List

main :: IO ()
main = do
  getc solve >>= mapM_ (mapM_ print)

solve :: [String] -> [[Int]]
solve = map (f 0 0)
  where
    f j i ss | length ss < 3 = [j,i]
             | s == "JOI" = f (j+1) i (drop 2 ss)
             | s == "IOI" = f j (i+1) (drop 2 ss)
             | otherwise = f j i (tail ss)
      where
        s = take 3 ss

getc :: ([String] -> a) -> IO a
getc f = f . lines <$> getContents