10年ぐらい前の問題をHaskellで解いてみた。 問題は、「8×8ますの正方形のパネルを同じ形に2分割する分け方はいくつあるか」というもの。 ↓のコードは回転同型は考慮しているが鏡像同型は考慮してない。でもすっきりと書けたんじゃないかな。 (追記)Node型を修正。
type Point = (Int, Int) type Pair = (Point, Point) type Node = [Pair] main :: IO () main = do print $ length $ solve 8 plus :: Point -> Point -> Point plus (x1, y1) (x2, y2) = (x1+x2, y1+y2) minus :: Point -> Point -> Point minus (x1, y1) (x2, y2) = (x1-x2, y1-y2) move :: Pair -> Point -> Pair move (f, b) p = (f `plus` p, b `minus` p) moves :: Pair -> Pair -> [Pair] moves (pf, pb) (qf, qb) = map (move (pf, pb)) [f, r, l] where (dx, dy) = pf `minus` qf f = (dx, dy) r = (-dy, dx) l = (dy, -dx) nexts :: Node -> [Node] nexts (p1:p0:ps) = [p2:p1:p0:ps | p2 <- moves p1 p0] exists :: Point -> [Pair] -> Bool exists p = any (either p) where either p (pf, pb) = p == pf || p == pb solve :: Int -> [Node] solve size = solutions initial where center :: Point center = (size `div` 2, size `div` 2) p0 :: Pair p0 = (center, center) initial :: Node initial = [move p0 (0, 1), p0] atboundary :: Point -> Bool atboundary (x, y) = (x == 0) || (x == size) || (y == 0) || (y == size) solutions :: Node -> [Node] solutions n | atboundary f = [n] | exists f ps = [] | otherwise = [n'' | n' <- nexts n, n'' <- solutions n'] where (f,b):ps = n