「人材獲得作戦・4 試験問題ほか」を解こうとしている(再・未完)
いただいたアドバイス (id:rst76:20100115:1263567265) を拝読し、自前実装に取り込んでみた。
コードははしょるけれど、解を Maybe から List にして盤面探索すると以下のふたつしか見つからない:
************************** *S* *$$$$ * *$* *$ *$ ************* * *$*$$$* $ ************ * *$$$ * $$$$$$$ * **************$*********** * $$$$$$$$$$$$$ * **$*********************** * $$$ *$$$$$$$$$$$$$$G * * *$$$$$ *********** * * * * ******* * * * * * ************************** ************************** *S* *$$$$ * *$* *$ *$ ************* * *$*$$$* $ ************ * *$$$ * $$$$$$$ * **************$*********** * $$$$$$$$$$$$$ * **$*********************** * $$$ * G$ * * *$$$ *********** *$ * * *$$$$ ******* *$ * * *$$$$$$$$$$$$$$$ * **************************
既訪の位置を記憶していることが原因だとはわかるのだけれど、これがなかなか解決できず思案中。
何手目にそこに訪れたかを覚えておけばいいとおもって以下のコードを書いたのだけれど、これは訪問済みを覚える前とおなじコードになっている疑惑。何をどうやって除外しているのか、もういちど冷静に考えることにする。
import Control.Monad type Depth = Int type Cordinate = (Int, Int) type Position = (Depth, Cordinate) type Board = [String] type State = (Position, Board) main :: IO () main = do input <- fmap lines getContents let answer = solve [] $ (next.from) input putStrLn $ unlines $ map unlines $ take 10 answer solve :: [Position] -> [State] -> [Board] solve _ [] = mzero solve vs ((p@(d,c),b):queue) | on 'G' = return b `mplus` solve vs queue | on ' ' && before p vs = solve (p:vs) (queue ++ (next.modify) (p,b)) | otherwise = solve vs queue where on = (b!!snd c!!fst c ==) before (d,c) vs = notElem c $ map snd $ filter ((< d).fst) vs next :: State -> [State] next ((d,(x,y)),b) = zip ns (repeat b) where ns = [(d+1,p) | p <- [(x,y-1),(x,y+1),(x-1,y),(x+1,y)]] from :: Board -> State from input = (startOf input, input) startOf :: Board -> Position startOf input = head [(0,(x,y)) | (y,cs) <- zip [0..] input, (x,c) <- zip [0..] cs, c=='S'] modify :: State -> State modify ((d,c@(x,y)),b) = ((d,c), putAt y (putAt x '$' (b!!y)) b) where putAt n v vs = take n vs ++ v : drop (n+1) vs
つまり以下のような盤面に対して…
***** *S * * * * G* *****
以下のような可能性をぜんぶ列挙できるようにしたい。そんなに難しいとはおもえないのに、なんでできないかなあ。
***** *S$$* * $* * G* ***** ***** *S$ * * $$* * G* ***** ***** *S$ * * $ * * $G* ***** ***** *S * *$$$* * G* ***** ***** *S * *$$ * * $G* ***** ***** *S * *$ * *$$G* *****