リストによる正方行列(つづき)

cf. 今日の一行 – リストによる正方行列処理

週をまたいでしまった。解答例もでてるけど。

問題3。これも内包表記で。

boxing :: [[a]] -> [[a]]
boxing m = [[m!!x!!y| x <- [0..l1], y <- [0..l1], x`div`l2 == i, y`div`l2 == j] | i <- [0..l3], j <- [0..l3]]
  where
    l1 = length m - 1
    l2 = (floor . sqrt . fromIntegral . length) m
    l3 = l2 -1

行列のサイズから n を求めるとこで型が合わずにはまった(sqrt(Floating a) => a -> a,必要なのは Int)。結局 floor を使った。

パターンの回転

パソコン甲子園というのを見つけた。
プログラミング部門の問題が公開されてるので(↓)ちょっとやってみよう。

正方行列つながりってことで問題01。

8文字×8行のパターンを右回りに90度、180度、270度回転させて出力し終了するプログラムを作成してください。

rotateMatrixR で右に90度回転させる。左に回転させる rotateMatrixL があるのは,勘違いしてさきに書いちゃったから。でも考えると右回転はちょっと面倒そうだな。これで正解かも。
main は手抜き。美しくない。

module Main (main) where

main :: IO ()
main = do cs <- getContents >>= return . lines
          putStrLn "90"
          showMatrix $ rotateMatrixR cs
          putStrLn "180"
          showMatrix $ rotateMatrixR $ rotateMatrixR cs
          putStrLn "270"
          showMatrix $ rotateMatrixR $ rotateMatrixR $ rotateMatrixR cs

rotateMatrixL :: [[a]] -> [[a]]
rotateMatrixL [xs] = [[x]| x <- reverse xs]
rotateMatrixL (xs:xss) = zipWith (:) (reverse xs) (rotateMatrixL xss)

rotateMatrixR :: [[a]] -> [[a]]
rotateMatrixR = reverse . rotateMatrixL . reverse

showMatrix :: [String] -> IO ()
showMatrix = putStr . unlines

実行例。

D:\>type input01.txt
#*******
#*******
#*******
#*******
#*******
#*******
#*******
########
D:\>runhaskell problem01.hs < input01.txt
90
########
#*******
#*******
#*******
#*******
#*******
#*******
#*******
180
########
*******#
*******#
*******#
*******#
*******#
*******#
*******#
270
*******#
*******#
*******#
*******#
*******#
*******#
*******#
########

追記:
右回転の方が簡単だった……orz

rotateMatrixR' :: [[a]] -> [[a]]
rotateMatrixR' = transpose . reverse
*Main> showMatrix sampleMatrix
#*******
#*******
#*******
#*******
#*******
#*******
#*******
########
*Main> showMatrix $ rotateMatrixR' sampleMatrix
########
#*******
#*******
#*******
#*******
#*******
#*******
#*******
*Main> showMatrix $ rotateMatrixR' $ rotateMatrixR' sampleMatrix
########
*******#
*******#
*******#
*******#
*******#
*******#
*******#

さらに追記:
ちがう!左回転も同じくらい簡単だ。

rotateMatrixL' :: [[a]] -> [[a]]
rotateMatrixL' = reverse . transpose