2013-09-09 8 views
2

Я возиться с печатью случайного 2d массив Ints, в этом простом формате изображения (PPM)Печать 2d массив в Haskell

0 1 0 0 1 
1 0 0 1 0 
0 1 1 0 0 
0 1 1 1 0 
0 0 0 1 0 

Ниже мой код, который работает, но кажется, что путь слишком много кода для такой простой операции. Есть лучший способ сделать это?

import System.Random 
import Data.Array.IArray 

main = do 
    g <- newStdGen 
    let img = listArray ((0,0),(5,5)) (myRands g) :: Array (Int,Int) Int 
    putStrLn $ printArray img 

myRands :: RandomGen g => g -> [Int] 
myRands g = randomRs (0,1) g 

make2dRange :: Int -> Int -> Int -> Int -> [(Int,Int)] 
make2dRange x1 y1 x2 y2 = range ((x1,y1),(x2,y2)) 

printArray :: (Array (Int,Int) Int) -> String 
printArray arr = unlines rows 
    where rows = map (unwords . map (show . (!) arr)) rowIndices 
     rowIndices = map (\y -> make2dRange 0 y 5 y) [0..5] 

Кроме очевидного, конечно (размеры массива являются жёстко, например)

+1

Вы делаете какие-либо другие вещи с 2D-массив, так что вам действительно нужно использовать 'Array', или было бы приемлемым решение с использованием только списков? – bennofs

ответ

7

Я хотел бы использовать списковый манипулировать показатели.

printArray arr = 
    unlines [unwords [show (arr ! (x, y)) | x <- [0..5]] | y <- [0..5]] 
0

за: http://lambda.haskell.org/platform/doc/current/packages/split-0.2.2/doc/html/Data-List-Split.html#v%3achunksOf

chunksOf :: Int -> [е] -> [[е]]

chunksOf п разбивает список на длины п штук. Последний фрагмент будет короче, если n равномерно разделит длину списка. Если n < = 0, chunksOf n l возвращает бесконечный список пустых списков.

использованием chunksOf моя реализация будет ..

printArray arr = mapM_ (putStrLn . unwords) $ map (map show) $ chunksOf 5 arr 

использование:

Prelude System.Random Data.List Data.List.Split> printArray [0..25] 
0 1 2 3 4 
5 6 7 8 9 
10 11 12 13 14 
15 16 17 18 19 
20 21 22 23 24 
25