1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プログラミングコンテスト: パネルの2分割

Last updated at Posted at 2012-03-07

10年ぐらい前の問題をHaskellで解いてみた。

問題は、「8×8ますの正方形のパネルを同じ形に2分割する分け方はいくつあるか」というもの。

↓のコードは回転同型は考慮しているが鏡像同型は考慮してない。でもすっきりと書けたんじゃないかな。

main.hs
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
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?