244 Sliders

15 puzzle が2色に塗り分けられたときの話．

なので，適当にコードをつくった．

はじめは，Lは空白を左に動かす操作だと思っていた．正しくは，空白の右隣のピースを左に動かす操作である．

これで，一瞬ハマリかけた．

```import Data.Char (ord)
import Data.Array.Unboxed (UArray ,listArray, range, (//), (!))
import Data.Maybe (mapMaybe)
import Data.Map (toList, fromListWith)
type Board = ((Int, Int), UArray (Int, Int) Bool)
type State = (Board, [Integer])
start, goal :: Board
start = ((1,1), listArray ((1,1), (4,4)).cycle \$ [False, False, True, True])
goal  = ((1,1), listArray ((1,1), (4,4)).cycle \$ [False, True, False, True,
True, False, True, False])
move :: State -> Char -> Maybe State
move ( ((x,y), b), css ) c
| not.elem (x + dx, y + dy).range \$ ((1,1),(4,4))  = Nothing
| otherwise = Just ( ((x + dx,y + dy), b //[ ((x,y), a), ((x + dx,y + dy), False) ] ), map (updateCS c) css )
where a = b ! (x + dx, y + dy)
dx | c == 'U'  =  1
| c == 'D'  = -1
| otherwise =
dy | c == 'L'  =  1
| c == 'R'  = -1
| otherwise =
updateCS :: Char -> Integer -> Integer
updateCS c cs = mod (cs*243 + toInteger (ord c)) 100000007
step :: [State] -> [State]
step ss  = toList.fromListWith (++).concatMap next \$ ss
where next s = mapMaybe (move s) \$ "LRUD"
main :: IO ()
main = print.sum.snd.head.filter ((==goal).fst).(!!32).iterate step \$ [(start, [])]
```

ものすごい，そのままの幅優先探索である．