module Data.CA.List (withDimensions, combinations) where import qualified Control.Applicative as Ap import qualified Data.CA.Pattern as Pat import Data.CA.Pattern (Pattern, Cell) composeN :: Int -> (a -> a) -> a -> a composeN n f | n <= 0 = id | otherwise = f . composeN (n - 1) f possible1 :: Int -> [[Cell]] possible1 n = composeN n (Ap.liftA2 (:) [False, True]) [[]] possible2 :: Int -> Int -> [[[Cell]]] possible2 h w = let rows = possible1 w in composeN h (Ap.liftA2 (:) rows) [[]] {-| A list of every possible h by w pattern. This function is necessarily exponential in both arguments, so it's only practical if the dimensions are very small. -} withDimensions :: Int -- ^ h -> Int -- ^ w -> [Pattern] withDimensions h w = map Pat.fromRectList (possible2 h w) {-| Combine two patterns in multiple ways. Useful for creating a list of spaceship / still life collisions. See 'Pat.combine'. -} combinations :: (Int, Int) -- ^ min and max vertical offset -> (Int, Int) -- ^ min and max horizonal offset -> Pattern -> Pattern -> [Pattern] combinations (yMin, yMax) (xMin, xMax) pat1 pat2 = let combine y x = Pat.combine y x pat1 pat2 in Ap.liftA2 combine [yMin .. yMax] [xMin .. xMax]