This solution is based solely on list processing. The main datatype, Region a, is simply an alias for [[a]]. At each step, the region is broken into sub-regions (the 2x2 squares), each is rotated or frozen appropriately, and then the sub-regions are combined back into a single region.

This solution is based solely on list processing. The main datatype, Region a, is simply an alias for [[a]]. At each step, the region is broken into sub-regions (the 2x2 squares), each is rotated or frozen appropriately, and then the sub-regions are combined back into a single region.

−

The output follows the Ruby Quiz convention of ' ' for vacuum, '.' for vapor and '*' for ice. A '|' is added on the left side of each line of the grid to distinguish them from separator lines.

+

The text output follows the Ruby Quiz convention of ' ' for vacuum, '.' for vapor and '*' for ice. A '|' is added on the left side of each line of the grid to distinguish them from separator lines.

−

This code makes use of the [[New monads/MonadRandom|random monad]].

+

The default output of this program is a number of PPM images of each step in the process. They are called frostNNN.ppm, where NNN starts from 100.

−

<haskell>

+

This code makes use of the [[New monads/MonadRandom|random monad]] and the [[New monads/MonadRandomSplittable|splittable random monad]].

The following is some auxiliary code to output PPM images of the results:

+

+

<haskell>

+

module PPImage ( Point

+

, Image

+

, Color(..)

+

, PPM(..)

+

, red

+

, yellow

+

, green

+

, cyan

+

, blue

+

, magenta

+

, black

+

, white

+

, pixelate )

+

where

+

+

type Point = (Double, Double)

+

type Image a = Point -> a

+

+

data Color = Color { r :: Int, g :: Int, b :: Int }

+

+

data PPM = PPM {

+

pixels :: [[Color]],

+

width :: Int,

+

height :: Int,

+

depth :: Int

+

}

+

+

instance Show Color where

+

show (Color r g b) = unwords [show r, show g, show b]

+

+

instance Show PPM where

+

show pg = "P3\n"

+

++ show w ++ " " ++ show h ++ "\n"

+

++ show d ++ "\n"

+

++ (unlines . map unlines . map (map show) . pixels $ pg) ++ "\n"

+

where h = height pg

+

w = width pg

+

d = depth pg

+

+

black = Color 0 0 0

+

red = Color 255 0 0

+

yellow = Color 255 255 0

+

green = Color 0 255 0

+

cyan = Color 0 255 255

+

blue = Color 0 0 255

+

magenta = Color 255 0 255

+

white = Color 255 255 255

+

+

pixelate n m d (x0, x1) (y0, y1) i = PPM pixels n m d

+

where

+

pixels = [ i (x, y) | x <- px, y <- py ]

+

dx = (x1 - x0) / fromIntegral n

+

dy = (y0 - y1) / fromIntegral m

+

px = take n $ iterate (+dx) x0

+

py = take m $ iterate (+dy) y1

</haskell>

</haskell>

Latest revision as of 08:12, 13 December 2009

This solution is based solely on list processing. The main datatype, Region a, is simply an alias for a. At each step, the region is broken into sub-regions (the 2x2 squares), each is rotated or frozen appropriately, and then the sub-regions are combined back into a single region.

The text output follows the Ruby Quiz convention of ' ' for vacuum, '.' for vapor and '*' for ice. A '|' is added on the left side of each line of the grid to distinguish them from separator lines.

The default output of this program is a number of PPM images of each step in the process. They are called frostNNN.ppm, where NNN starts from 100.