Problem:
すごろく

問題

JOI さんは一人ですごろく遊びをしている．
このすごろくには一直線上に N 個のマスがあり，それぞれ移動の指示が書かれている．スタート地点は 1 マス目であり，ゴールはNマス目である．
JOI さんはゴールするまで次を繰り返す．

サイコロを振って出た目の数だけ現在のマスから進み，そのマスの指示に従う．
指示に従って移動した先のマスの指示には従わない．

ちょうど N マス目に止まる時だけでなく，移動先が N マス目を超える場合もゴールとなる．

すごろくの盤面と， M 回分のサイコロの出る目が与えられたとき，サイコロを何回振ったところでゴールするかを出力するプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

各データセットは 1+N+M 行からなる．

入力の 1 行目には２つの整数 N,M （2 ≤ N ≤ 1000 ，1 ≤ M ≤ 1000 ）が空白を区切りとして書かれている．
N はすごろくのマス目の個数を， M は与えられるサイコロの目の個数を表す．

続く N 行には -999 以上 999 以下の整数が１つずつ書かれている．
1+i 行目 （ 1 ≤ i ≤ N ） の整数は，すごろくの i 番目のマスの指示を表す．
書かれている整数を X とする．
X=0 のときは「何もしない」を， X>0 のときは「 X マス進む」を，X<0 のときは「 |X| マス戻る」の指示を表す．ただし， |X| は X の絶対値を表す．

続く M 行には 1 以上 6 以下の整数が１つずつ書かれており， 1+N+j 行目 （ 1 ≤ j ≤ M ）の数は j 回目に出るサイコロの目を表す．

ただし， 2 行目と 1+N 行目の数は必ず 0 である．
1 マス目よりも前のマスに移動させる指示が書かれているマスはない．
また，どの採点用入力データにおいてもサイコロを振る回数が M 以下でゴールできる．

N, M がともに 0 のとき入力の終了を示す.データセットの数は 5 を超えない．

出力

データセットごとに，サイコロを何回振ったところでゴールするかを表す整数を 1 行に出力する．

入出力例

入力例

10 5
0
0
5
6
-3
8
1
8
-4
0
1
3
5
1
5
10 10
0
-1
-1
4
4
-5
0
1
-6
0
1
5
2
4
6
5
5
4
1
6
0 0

出力例

5
6

次の図は1つ目の入力例を表す．

次の図は2つ目の入力例を表す．

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

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import Data.Functor
import Data.Function
import Data.Monoid
import Data.Maybe
import Data.List
import qualified Data.Foldable as Foldable
import qualified Data.Set as Set
import Data.List.Split
import Data.Bits
import Data.Char
import Data.Ix
import Data.Ratio
import Data.Ord
import Data.Tuple
import Data.Array
--import Data.Array.Unboxed
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
-- import System.IO.Unsafe
 
readInt = read :: String -> Int
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getDouble = readLn :: IO Double
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
cond :: a -> a -> Bool -> a
cond t f c = if c then t else f
apply2 :: (a -> a -> b) -> [a] -> b
apply2 f [x,y] = f x y
apply3 :: (a -> a -> a -> b) -> [a] -> b
apply3 f [x,y,z] = f x y z
apply4 :: (a -> a -> a -> a -> b) -> [a] -> b
apply4 f [x,y,z,w] = f x y z w
fnBin :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d
fnBin op f g x = op (f x) $ g x
fnTuple :: (a -> b, a -> c) -> a -> (b, c)
fnTuple (f,g) a = (f a, g a)
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y = map (\z -> if z==x then y else z)
modifyArray :: (Ix i, MArray a e m) => a i e -> i -> (e -> e) -> m ()
modifyArray arr ix f = readArray arr ix >>= writeArray arr ix . f
-- end of templete

f n m b d = runST $ do
    ref <- newSTRef m
    position <- newSTRef 1
    let field = listArray (1,n) b
    forM_ (zip [1..] d) $ \(i,x) -> do
        p <- readSTRef position
        when (p<n) $ do
            let np = p + x
            when (np>=n) $ modifySTRef ref (min i)
            writeSTRef position np
            when (np<n) $ do
                let dp = field!np
                let nnp = np + dp
                when (nnp>=n) $ modifySTRef ref (min i)
                writeSTRef position nnp
    readSTRef ref

main = do
    [n, m] <- getInts
    when (m/=0 || m/=0) $ do
        board <- replicateM n getInt
        dice <- replicateM m getInt
        print $ f n m board dice
        main