From: Neil Smith Date: Thu, 21 Dec 2017 21:41:54 +0000 (+0000) Subject: Done day 21 X-Git-Url: https://git.njae.me.uk/?p=advent-of-code-17.git;a=commitdiff_plain;h=5da6dfef190a4e7514c4194ce88e31d1cc96ca49 Done day 21 --- diff --git a/advent-of-code.cabal b/advent-of-code.cabal index e2dd2a8..f9fafce 100644 --- a/advent-of-code.cabal +++ b/advent-of-code.cabal @@ -219,3 +219,12 @@ executable advent20 , text , megaparsec , vector + +executable advent21 + hs-source-dirs: src/advent21 + main-is: advent21.hs + default-language: Haskell2010 + build-depends: base >= 4.7 && < 5 + , containers + , text + , megaparsec diff --git a/data/advent21.txt b/data/advent21.txt new file mode 100644 index 0000000..97f767a --- /dev/null +++ b/data/advent21.txt @@ -0,0 +1,108 @@ +../.. => .../.##/##. +#./.. => .##/.##/#.. +##/.. => ..#/.../### +.#/#. => #.#/..#/##. +##/#. => .#./.#./..# +##/## => #.#/#../### +.../.../... => ..../#.../.##./..#. +#../.../... => ####/#.##/##.#/..#. +.#./.../... => ..##/..##/..##/..## +##./.../... => ..../..#./##../##.# +#.#/.../... => ##.#/..../####/...# +###/.../... => .#.#/.###/.#../.#.# +.#./#../... => .###/#.#./...#/##.. +##./#../... => #.##/#.../####/###. +..#/#../... => ####/...#/...#/#.## +#.#/#../... => .#../##../..##/..#. +.##/#../... => .#../..##/..../.##. +###/#../... => #.../..#./.#.#/#..# +.../.#./... => #.#./.#.#/.###/...# +#../.#./... => ###./.#../...#/.#.. +.#./.#./... => ##.#/.#../#..#/##.. +##./.#./... => #..#/...#/.#.#/###. +#.#/.#./... => .##./#.../#..#/.### +###/.#./... => .#.#/##.#/..../##.# +.#./##./... => ##.#/#.##/.#.#/#.## +##./##./... => #.##/..#./..#./.##. +..#/##./... => ..../#.../..#./..## +#.#/##./... => .##./####/####/#### +.##/##./... => #.##/####/#.##/#..# +###/##./... => .#../.###/##../...# +.../#.#/... => ...#/...#/#.##/#### +#../#.#/... => ..#./..#./###./.##. +.#./#.#/... => .##./##../.###/.#.# +##./#.#/... => #.#./.#../.##./...# +#.#/#.#/... => ##.#/..##/#.../##.# +###/#.#/... => ..##/##../.#.#/..## +.../###/... => .#../#.../.##./.... +#../###/... => ..##/..##/...#/.##. +.#./###/... => #..#/..#./#.#./..## +##./###/... => #.##/.#../##.#/##.# +#.#/###/... => ####/###./.##./...# +###/###/... => #..#/#.##/..../.##. +..#/.../#.. => #.#./.#../##../..#. +#.#/.../#.. => ##.#/####/##../.#.# +.##/.../#.. => ####/##../#..#/..#. +###/.../#.. => ##../..#./####/##.# +.##/#../#.. => ##../#.#./###./..## +###/#../#.. => ..../.#../#..#/...# +..#/.#./#.. => ..#./...#/.###/.#.# +#.#/.#./#.. => ###./..../#.#./###. +.##/.#./#.. => ####/#.##/.#.#/.#.. +###/.#./#.. => ###./#.##/##../#### +.##/##./#.. => ##.#/..##/..#./.#.. +###/##./#.. => ##.#/.##./.###/.##. +#../..#/#.. => #.../###./##.#/#..# +.#./..#/#.. => ..##/.###/...#/..#. +##./..#/#.. => ##../#.#./...#/.#.. +#.#/..#/#.. => ..#./###./##../.### +.##/..#/#.. => #.../.##./..../#.#. +###/..#/#.. => .#.#/#.##/#.##/..#. +#../#.#/#.. => ..##/..##/#.../#### +.#./#.#/#.. => #.../...#/..../..## +##./#.#/#.. => ###./..##/.#../.##. +..#/#.#/#.. => ...#/..##/..#./.#.. +#.#/#.#/#.. => #.#./.#../..../##.. +.##/#.#/#.. => ..#./.###/##.#/.... +###/#.#/#.. => #.##/..##/...#/##.. +#../.##/#.. => #.#./##../###./.#.# +.#./.##/#.. => .###/#..#/.##./.... +##./.##/#.. => .#.#/.#../.###/.##. +#.#/.##/#.. => .#../..##/###./#.## +.##/.##/#.. => ##../.##./..#./.#.. +###/.##/#.. => .#.#/..#./#..#/.### +#../###/#.. => #.##/#..#/.#.#/#.#. +.#./###/#.. => #.../#..#/#.../.#.# +##./###/#.. => ##../####/##../.### +..#/###/#.. => #.../..../####/##.# +#.#/###/#.. => ...#/..../...#/..## +.##/###/#.. => .#../####/#.##/.#.. +###/###/#.. => ###./.#.#/#.../##.. +.#./#.#/.#. => ...#/##../####/...# +##./#.#/.#. => ####/#..#/###./#.## +#.#/#.#/.#. => .###/#..#/..#./...# +###/#.#/.#. => ###./.###/##.#/###. +.#./###/.#. => #..#/#.../..#./#### +##./###/.#. => #.../..../#..#/..## +#.#/###/.#. => #..#/.#.#/#.../##.. +###/###/.#. => .#.#/..../.#.#/#.## +#.#/..#/##. => .#../..##/...#/###. +###/..#/##. => .###/..#./##.#/##.# +.##/#.#/##. => ####/#.##/.##./##.. +###/#.#/##. => #..#/#..#/####/#.## +#.#/.##/##. => .###/#.#./#..#/.#.# +###/.##/##. => #.#./#.#./#.##/..## +.##/###/##. => ####/###./##.#/##.# +###/###/##. => ##../..##/#.#./#... +#.#/.../#.# => .#../###./.###/##.# +###/.../#.# => ..../.#.#/#..#/##.. +###/#../#.# => ..#./#.../.##./...# +#.#/.#./#.# => ...#/#.../##.#/.##. +###/.#./#.# => ..../..../#.#./##.# +###/##./#.# => .#../...#/...#/###. +#.#/#.#/#.# => ...#/#.../##../.### +###/#.#/#.# => #.../...#/.#../#.## +#.#/###/#.# => ..../.##./..../##.. +###/###/#.# => .##./.#.#/#.##/.##. +###/#.#/### => #.#./####/.##./.##. +###/###/### => .#.#/..##/#.##/.##. \ No newline at end of file diff --git a/problems/day21.html b/problems/day21.html new file mode 100644 index 0000000..4d1bc0f --- /dev/null +++ b/problems/day21.html @@ -0,0 +1,195 @@ + + + + +Day 21 - Advent of Code 2017 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 42*

          2017

+ + + +
+

--- Day 21: Fractal Art ---

You find a program trying to generate some art. It uses a strange process that involves repeatedly enhancing the detail of an image through a set of rules.

+

The image consists of a two-dimensional square grid of pixels that are either on (#) or off (.). The program always begins with this pattern:

+
.#.
+..#
+###
+
+

Because the pattern is both 3 pixels wide and 3 pixels tall, it is said to have a size of 3.

+

Then, the program repeats the following process:

+
    +
  • If the size is evenly divisible by 2, break the pixels up into 2x2 squares, and convert each 2x2 square into a 3x3 square by following the corresponding enhancement rule.
  • +
  • Otherwise, the size is evenly divisible by 3; break the pixels up into 3x3 squares, and convert each 3x3 square into a 4x4 square by following the corresponding enhancement rule.
  • +
+

Because each square of pixels is replaced by a larger one, the image gains pixels and so its size increases.

+

The artist's book of enhancement rules is nearby (your puzzle input); however, it seems to be missing rules. The artist explains that sometimes, one must rotate or flip the input pattern to find a match. (Never rotate or flip the output pattern, though.) Each pattern is written concisely: rows are listed as single units, ordered top-down, and separated by slashes. For example, the following rules correspond to the adjacent patterns:

+
../.#  =  ..
+          .#
+
+                .#.
+.#./..#/###  =  ..#
+                ###
+
+                        #..#
+#..#/..../#..#/.##.  =  ....
+                        #..#
+                        .##.
+
+

When searching for a rule to use, rotate and flip the pattern as necessary. For example, all of the following patterns match the same rule:

+
.#.   .#.   #..   ###
+..#   #..   #.#   ..#
+###   ###   ##.   .#.
+
+

Suppose the book contained the following two rules:

+
../.# => ##./#../...
+.#./..#/### => #..#/..../..../#..#
+
+

As before, the program begins with this pattern:

+
.#.
+..#
+###
+
+

The size of the grid (3) is not divisible by 2, but it is divisible by 3. It divides evenly into a single square; the square matches the second rule, which produces:

+
#..#
+....
+....
+#..#
+
+

The size of this enhanced grid (4) is evenly divisible by 2, so that rule is used. It divides evenly into four squares:

+
#.|.#
+..|..
+--+--
+..|..
+#.|.#
+
+

Each of these squares matches the same rule (../.# => ##./#../...), three of which require some flipping and rotation to line up with the rule. The output for the rule is the same in all four cases:

+
##.|##.
+#..|#..
+...|...
+---+---
+##.|##.
+#..|#..
+...|...
+
+

Finally, the squares are joined into a new grid:

+
##.##.
+#..#..
+......
+##.##.
+#..#..
+......
+
+

Thus, after 2 iterations, the grid contains 12 pixels that are on.

+

How many pixels stay on after 5 iterations?

+
+

Your puzzle answer was 158.

--- Part Two ---

How many pixels stay on after 18 iterations?

+
+

Your puzzle answer was 2301762.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/src/advent21/advent21.hs b/src/advent21/advent21.hs new file mode 100644 index 0000000..62b5b5c --- /dev/null +++ b/src/advent21/advent21.hs @@ -0,0 +1,170 @@ +{-# LANGUAGE NegativeLiterals #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE BangPatterns #-} + +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Text.Megaparsec hiding (State) +import qualified Text.Megaparsec.Lexer as L +import Text.Megaparsec.Text (Parser) +import qualified Control.Applicative as CA +-- import qualified Data.Functor as F + +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) + +import Data.List + + +type Grid = M.Map (Int, Int) Bool +type ExplodedGrid = M.Map (Int, Int) Grid + +data Rule = Rule Grid Grid deriving (Eq, Show) + +rulePre (Rule g _) = g +rulePost (Rule _ g) = g + + +initialGrid = case parse gridP "" ".#./..#/###" of + Left _ -> M.empty + Right g -> g + + +main :: IO () +main = do + text <- TIO.readFile "data/advent21.txt" + let rules = readRules text + print $ countLit $ nthApplication rules 5 + print $ countLit $ nthApplication rules 18 + + +readRules :: Text -> [Rule] +readRules = expandRules . successfulParse + +expandRules = concatMap expandRule +expandRule rule = [Rule l (rulePost rule) | l <- allArrangements (rulePre rule)] + +reflectH g = M.fromList [((r, c) , M.findWithDefault False (rm - r, c) g) | r <- [0..rm], c <- [0..cm] ] + where (rm, cm) = bounds g + +reflectV g = M.fromList [((r, c) , M.findWithDefault False (r, cm - c) g) | r <- [0..rm], c <- [0..cm] ] + where (rm, cm) = bounds g + +transposeG g = M.fromList [((c, r) , M.findWithDefault False (r, c) g) | r <- [0..rm], c <- [0..cm] ] + where (rm, cm) = bounds g + +allArrangements grid = map (\f -> f grid) [ id + , reflectH + , reflectV + , transposeG + , reflectH . transposeG + , reflectV . transposeG + , reflectH . reflectV . transposeG + , reflectV . reflectH + ] + + + + +countLit = M.size . M.filter id + + +applyOnce rules g = contractExploded $ M.map (apply rules) $ explodeGrid g + +nthApplication rules n = (!! n) $ iterate (applyOnce rules) initialGrid + + + +apply rules grid = rulePost thisRule + where ri = head $ findIndices (\r -> rulePre r == grid) rules + thisRule = rules!!ri + + +explodeGrid :: Grid -> ExplodedGrid +explodeGrid g = if (rm + 1) `rem` 2 == 0 + then explodeGrid' 2 g + else explodeGrid' 3 g + where (rm, cm) = bounds g + +contractExploded :: ExplodedGrid -> Grid +contractExploded gs = foldl1 (>|<) $ map (foldl1 (>-<)) rows + where rows = explodedRows gs + + +explodeGrid' :: Int -> Grid -> ExplodedGrid +explodeGrid' n g = M.fromList [((bigR, bigC), subGrid n g bigR bigC) | bigR <- [0..bigRm], bigC <- [0..bigCm]] + where (rm, cm) = bounds g + bigRm = (rm + 1) `div` n - 1 + bigCm = (cm + 1) `div` n - 1 + + +subGrid :: Int -> Grid -> Int -> Int -> Grid +subGrid n g bigR bigC = M.fromList [ ((r, c), + M.findWithDefault False (r + rStep, c + cStep) g) + | r <- [0..(n - 1)], c <- [0..(n - 1)] + ] + where rStep = bigR * n + cStep = bigC * n + + +explodedRows eg = [M.filterWithKey (\(r, _) _ -> r == row) eg | row <- [0..rowMax] ] + where (rowMax, _) = bounds eg + +(>-<) g1 g2 = M.union g1 g2' + where (_, cm) = bounds g1 + g2' = M.mapKeys (\(r, c) -> (r, c + cm + 1)) g2 + +(>|<) g1 g2 = M.union g1 g2' + where (rm, _) = bounds g1 + g2' = M.mapKeys (\(r, c) -> (r + rm + 1, c)) g2 + + + + + +bounds :: M.Map (Int, Int) a -> (Int, Int) +bounds grid = (maximum $ map fst $ M.keys grid, maximum $ map snd $ M.keys grid) + + +showGrid g = unlines [[showGChar $ M.findWithDefault False (r, c) g | + c <- [0..cm] ] | r <- [0..rm] ] + where (rm, cm) = bounds g + showGChar True = '#' + showGChar False = '.' + + +onlySpace = (char ' ') <|> (char '\t') + +sc :: Parser () +sc = L.space (skipSome onlySpace) CA.empty CA.empty + +lexeme = L.lexeme sc + +symbol = L.symbol sc +rowSep = symbol "/" +ruleJoin = symbol "=>" + +present = id True <$ symbol "#" +absent = id False <$ symbol "." + +rulesP = ruleP `sepBy` space +ruleP = Rule <$> gridP <*> (ruleJoin *> gridP) + +gridP = gridify <$> rowP `sepBy` rowSep + where gridify g = M.fromList $ concat + [map (\(c, v) -> ((r, c), v)) nr | + (r, nr) <- zip [0..] + [zip [0..] r | r <- g]] + + +rowP = some (present <|> absent) + +successfulParse :: Text -> [Rule] +successfulParse input = + case parse rulesP "input" input of + Left _error -> [] + Right instructions -> instructions \ No newline at end of file diff --git a/src/advent21/advent21.ipynb b/src/advent21/advent21.ipynb new file mode 100644 index 0000000..82fb65b --- /dev/null +++ b/src/advent21/advent21.ipynb @@ -0,0 +1,1276 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "{-# LANGUAGE NegativeLiterals #-}\n", + "{-# LANGUAGE FlexibleContexts #-}\n", + "{-# LANGUAGE OverloadedStrings #-}\n", + "{-# LANGUAGE TypeFamilies #-}\n", + "{-# LANGUAGE BangPatterns #-}" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import Data.Text (Text)\n", + "import qualified Data.Text as T\n", + "import qualified Data.Text.IO as TIO\n", + "\n", + "import Text.Megaparsec hiding (State)\n", + "import qualified Text.Megaparsec.Lexer as L\n", + "import Text.Megaparsec.Text (Parser)\n", + "import qualified Control.Applicative as CA\n", + "-- import Data.Functor (void)\n", + "\n", + "import qualified Data.Map.Strict as M\n", + "import Data.Map.Strict ((!))\n", + "\n", + "-- import Data.Vector ((!), (//))\n", + "-- import qualified Data.Vector as V\n", + "\n", + "import Data.List \n", + "import qualified Data.Functor as F" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "type Grid = M.Map (Int, Int) Bool\n", + "-- type Grid = [[Char]]\n", + "-- type Grid = [[Bool]]\n", + "\n", + "type ExplodedGrid = M.Map (Int, Int) Grid\n", + "\n", + "data Rule = Rule Grid Grid deriving (Eq, Show)\n", + "\n", + "rulePre (Rule g _) = g\n", + "rulePost (Rule _ g) = g" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "onlySpace = (char ' ') <|> (char '\\t')\n", + "\n", + "sc :: Parser ()\n", + "sc = L.space (skipSome onlySpace) CA.empty CA.empty" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "lexeme = L.lexeme sc\n", + "\n", + "symbol = L.symbol sc\n", + "rowSep = symbol \"/\"\n", + "ruleJoin = symbol \"=>\"\n", + "\n", + "-- present :: Parser Bool\n", + "present = id True <$ symbol \"#\"\n", + "\n", + "-- absent :: Parser Bool\n", + "absent = id False <$ symbol \".\"\n", + "\n", + "rulesP = ruleP `sepBy` space\n", + "ruleP = Rule <$> gridP <*> (ruleJoin *> gridP)\n", + "\n", + "gridP = gridify <$> rowP `sepBy` rowSep\n", + " where gridify g = M.fromList $ concat \n", + " [map (\\(c, v) -> ((r, c), v)) nr | \n", + " (r, nr) <- zip [0..] \n", + " [zip [0..] r | r <- g]]\n", + "\n", + "\n", + "rowP = some (present <|> absent)\n", + " \n", + "successfulParse :: Text -> [Rule]\n", + "successfulParse input = \n", + " case parse rulesP \"input\" input of\n", + " Left _error -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err\n", + " Right instructions -> instructions" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Rule (fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]) (fromList [((0,0),False),((0,1),True),((0,2),True),((1,0),False),((1,1),True),((1,2),True),((2,0),True),((2,1),False),((2,2),False)])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "parseTest ruleP \"#./.. => .##/.##/#..\"" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Rule (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),True),((2,0),False),((2,1),False),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),True),((0,3),False),((1,0),False),((1,1),True),((1,2),False),((1,3),False),((2,0),False),((2,1),True),((2,2),True),((2,3),False),((3,0),False),((3,1),False),((3,2),False),((3,3),True)])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "parseTest ruleP \"##./#.#/... => #.#./.#../.##./...#\"" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "testRule = head $ successfulParse \"##./#.#/... => #.#./.#../.##./...#\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Rule (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),True),((2,0),False),((2,1),False),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),True),((0,3),False),((1,0),False),((1,1),True),((1,2),False),((1,3),False),((2,0),False),((2,1),True),((2,2),True),((2,3),False),((3,0),False),((3,1),False),((3,2),False),((3,3),True)])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "testRule" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Rule (fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]) (fromList [((0,0),False),((0,1),True),((0,2),True),((1,0),False),((1,1),True),((1,2),True),((2,0),True),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),True),((2,0),False),((2,1),False),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),True),((0,3),False),((1,0),False),((1,1),True),((1,2),False),((1,3),False),((2,0),False),((2,1),True),((2,2),True),((2,3),False),((3,0),False),((3,1),False),((3,2),False),((3,3),True)])]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "parseTest rulesP \"#./.. => .##/.##/#..\\n##./#.#/... => #.#./.#../.##./...#\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Rule (fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]) \n", + " (fromList [((0,0),False),((0,1),True),((0,2),True),((1,0),False),((1,1),True),((1,2),True),((2,0),True),((2,1),False),((2,2),False),((2,3),True),((2,4),True),((2,5),False),((3,0),True),((3,1),False),((3,2),True),((4,0),False),((4,1),False),((4,2),False)]),\n", + " \n", + "Rule (fromList []) \n", + " (fromList [((0,0),True),((0,1),False),((0,2),True),((0,3),False),((1,0),False),((1,1),True),((1,2),False),((1,3),False),((2,0),False),((2,1),True),((2,2),True),((2,3),False),((3,0),False),((3,1),False),((3,2),False),((3,3),True)])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "g = [[False,True,True],[False,True,True],[True,False,False]]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[((0,0),False),((0,1),True),((0,2),True),((1,0),False),((1,1),True),((1,2),True),((2,0),True),((2,1),False),((2,2),False)]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "concat [map (\\(c, v) -> ((r, c), v)) nr | (r, nr) <- zip [0..] [zip [0..] r | r <- g]]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "bounds :: M.Map (Int, Int) a -> (Int, Int)\n", + "bounds grid = (maximum $ map fst $ M.keys grid, maximum $ map snd $ M.keys grid)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(3,3)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bounds (rulePost testRule)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "showGrid g = unlines [[showChar $ M.findWithDefault False (r, c) g | \n", + " c <- [0..cm] ] | r <- [0..rm] ]\n", + " where (rm, cm) = bounds g\n", + " showChar True = '#'\n", + " showChar False = '.'" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "#.#.\n", + ".#..\n", + ".##.\n", + "...#" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ rulePost testRule" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "initialGrid = case parse gridP \"\" \".#./..#/###\" of \n", + " Left _ -> M.empty \n", + " Right g -> g" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "fromList [((0,0),False),((0,1),True),((0,2),False),((1,0),False),((1,1),False),((1,2),True),((2,0),True),((2,1),True),((2,2),True)]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".#.\n", + "..#\n", + "###" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "reflectH g = M.fromList [((r, c) , M.findWithDefault False (rm - r, c) g) | r <- [0..rm], c <- [0..cm] ]\n", + " where (rm, cm) = bounds g" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "###\n", + "..#\n", + ".#." + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ reflectH initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "reflectV g = M.fromList [((r, c) , M.findWithDefault False (r, cm - c) g) | r <- [0..rm], c <- [0..cm] ]\n", + " where (rm, cm) = bounds g" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".#.\n", + "#..\n", + "###" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ reflectV initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "transpose g = M.fromList [((c, r) , M.findWithDefault False (r, c) g) | r <- [0..rm], c <- [0..cm] ]\n", + " where (rm, cm) = bounds g" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "..#\n", + "#.#\n", + ".##" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ transpose initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "allArrangements grid = map (\\f -> f grid) [ id\n", + " , reflectH\n", + " , reflectV\n", + " , transpose\n", + " , reflectH . transpose\n", + " , reflectV . transpose\n", + " , reflectH . reflectV . transpose\n", + " , reflectV . reflectH\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[\".#.\\n..#\\n###\\n\",\"###\\n..#\\n.#.\\n\",\".#.\\n#..\\n###\\n\",\"..#\\n#.#\\n.##\\n\",\".##\\n#.#\\n..#\\n\",\"#..\\n#.#\\n##.\\n\",\"##.\\n#.#\\n#..\\n\",\"###\\n#..\\n.#.\\n\"]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "map showGrid $ allArrangements initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sampleRulesCompact = successfulParse \"../.# => ##./#../...\\n.#./..#/### => #..#/..../..../#..#\"\n", + "length sampleRulesCompact" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "expandRule rule = [Rule l (rulePost rule) | l <- allArrangements (rulePre rule)]\n", + "expandRules = concatMap expandRule" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[\"##.\\n#.#\\n...\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\"...\\n#.#\\n##.\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\".##\\n#.#\\n...\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\"##.\\n#..\\n.#.\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\".#.\\n#..\\n##.\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\".##\\n..#\\n.#.\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\".#.\\n..#\\n.##\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\",\"...\\n#.#\\n.##\\n=>#.#.\\n.#..\\n.##.\\n...#\\n\"]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "[showGrid (rulePre r) ++ \"=>\" ++ showGrid (rulePost r) | r <- expandRule testRule]" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "16" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "length $ expandRules sampleRulesCompact" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "readRules = expandRules . successfulParse" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Rule (fromList [((0,0),False),((0,1),False),((1,0),False),((1,1),True)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),True),((1,0),False),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),False),((1,0),True),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),False),((1,0),False),((1,1),True)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),True),((1,0),False),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),False),((1,0),True),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]) (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),False),((2,2),False)]),Rule (fromList [((0,0),False),((0,1),True),((0,2),False),((1,0),False),((1,1),False),((1,2),True),((2,0),True),((2,1),True),((2,2),True)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),True),((0,1),True),((0,2),True),((1,0),False),((1,1),False),((1,2),True),((2,0),False),((2,1),True),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),False),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),False),((2,0),True),((2,1),True),((2,2),True)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),False),((0,1),False),((0,2),True),((1,0),True),((1,1),False),((1,2),True),((2,0),False),((2,1),True),((2,2),True)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),False),((0,1),True),((0,2),True),((1,0),True),((1,1),False),((1,2),True),((2,0),False),((2,1),False),((2,2),True)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),True),((0,1),False),((0,2),False),((1,0),True),((1,1),False),((1,2),True),((2,0),True),((2,1),True),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),True),((0,1),True),((0,2),False),((1,0),True),((1,1),False),((1,2),True),((2,0),True),((2,1),False),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)]),Rule (fromList [((0,0),True),((0,1),True),((0,2),True),((1,0),True),((1,1),False),((1,2),False),((2,0),False),((2,1),True),((2,2),False)]) (fromList [((0,0),True),((0,1),False),((0,2),False),((0,3),True),((1,0),False),((1,1),False),((1,2),False),((1,3),False),((2,0),False),((2,1),False),((2,2),False),((2,3),False),((3,0),True),((3,1),False),((3,2),False),((3,3),True)])]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sampleRules = readRules \"../.# => ##./#../...\\n.#./..#/### => #..#/..../..../#..#\"\n", + "sampleRules" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [], + "source": [ + "text <- TIO.readFile \"../../data/advent21.txt\"\n", + "rules = readRules text" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "864" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "length rules" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "apply rules grid = rulePost thisRule\n", + " where ri = head $ findIndices (\\r -> rulePre r == grid) rules\n", + " thisRule = rules!!ri" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "#..#\n", + "....\n", + "....\n", + "#..#" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ apply sampleRules initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "subGrid :: Int -> Grid -> Int -> Int -> Grid\n", + "subGrid n g bigR bigC = M.fromList [ ((r, c), \n", + " M.findWithDefault False (r + rStep, c + cStep) g) \n", + " | r <- [0..(n - 1)], c <- [0..(n - 1)]\n", + " ]\n", + " where rStep = bigR * n\n", + " cStep = bigC * n" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "explodeGrid' :: Int -> Grid -> ExplodedGrid\n", + "explodeGrid' n g = M.fromList [((bigR, bigC), subGrid n g bigR bigC) | bigR <- [0..bigRm], bigC <- [0..bigCm]]\n", + " where (rm, cm) = bounds g\n", + " bigRm = (rm + 1) `div` n - 1\n", + " bigCm = (cm + 1) `div` n - 1" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "explodeGrid :: Grid -> ExplodedGrid\n", + "explodeGrid g = if (rm + 1) `rem` 2 == 0 \n", + " then explodeGrid' 2 g\n", + " else explodeGrid' 3 g\n", + " where (rm, cm) = bounds g" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "fromList [((0,0),\"#.\\n..\\n\"),((0,1),\".#\\n..\\n\"),((1,0),\"..\\n#.\\n\"),((1,1),\"..\\n.#\\n\")]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "testEg = explodeGrid $ apply sampleRules initialGrid\n", + "M.map showGrid testEg" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [], + "source": [ + "explodedRows eg = [M.filterWithKey (\\(r, _) _ -> r == row) eg | row <- [0..rowMax] ]\n", + " where (rowMax, _) = bounds eg" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[fromList [((0,0),fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]),((0,1),fromList [((0,0),False),((0,1),True),((1,0),False),((1,1),False)])],fromList [((1,0),fromList [((0,0),False),((0,1),False),((1,0),True),((1,1),False)]),((1,1),fromList [((0,0),False),((0,1),False),((1,0),False),((1,1),True)])]]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "explodedRows testEg" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "(>-<) g1 g2 = M.union g1 g2'\n", + " where (_, cm) = bounds g1\n", + " g2' = M.mapKeys (\\(r, c) -> (r, c + cm + 1)) g2" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "(>|<) g1 g2 = M.union g1 g2'\n", + " where (rm, _) = bounds g1\n", + " g2' = M.mapKeys (\\(r, c) -> (r + rm + 1, c)) g2" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "fromList [((0,0),True),((0,1),False),((1,0),False),((1,1),False)]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "M.findWithDefault M.empty (0, 0) testEg" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Redundant bracket
Found:
(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Why Not:
M.findWithDefault M.empty (0, 1) testEg >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Redundant bracket
Found:
(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Why Not:
(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " M.findWithDefault M.empty (0, 0) testEg
" + ], + "text/plain": [ + "Line 1: Redundant bracket\n", + "Found:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)\n", + "Why not:\n", + "M.findWithDefault M.empty (0, 1) testEg >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)Line 1: Redundant bracket\n", + "Found:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " (M.findWithDefault M.empty (0, 0) testEg)\n", + "Why not:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >-<\n", + " M.findWithDefault M.empty (0, 0) testEg" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "\".##.\\n....\\n\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "showGrid $ (M.findWithDefault M.empty (0, 1) testEg) >-< (M.findWithDefault M.empty (0, 0) testEg)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Redundant bracket
Found:
(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Why Not:
M.findWithDefault M.empty (0, 1) testEg >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Redundant bracket
Found:
(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)
Why Not:
(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " M.findWithDefault M.empty (0, 0) testEg
" + ], + "text/plain": [ + "Line 1: Redundant bracket\n", + "Found:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)\n", + "Why not:\n", + "M.findWithDefault M.empty (0, 1) testEg >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)Line 1: Redundant bracket\n", + "Found:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " (M.findWithDefault M.empty (0, 0) testEg)\n", + "Why not:\n", + "(M.findWithDefault M.empty (0, 1) testEg) >|<\n", + " M.findWithDefault M.empty (0, 0) testEg" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "\".#\\n..\\n#.\\n..\\n\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "showGrid $ (M.findWithDefault M.empty (0, 1) testEg) >|< (M.findWithDefault M.empty (0, 0) testEg)" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [], + "source": [ + "contractExploded :: ExplodedGrid -> Grid\n", + "contractExploded gs = foldl1 (>|<) $ map (foldl1 (>-<)) rows\n", + " where rows = explodedRows gs" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"#..#\\n....\\n....\\n#..#\\n\"" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "showGrid $ contractExploded testEg" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "##.##.\n", + "#..#..\n", + "......\n", + "##.##.\n", + "#..#..\n", + "......" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ contractExploded $ M.map (apply sampleRules) testEg" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [], + "source": [ + "applyOnce rules g = contractExploded $ M.map (apply rules) $ explodeGrid g" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".#.#.#.#..##..#.##\n", + ".#.#...#..##....##\n", + "..####..##..####..\n", + "..#.#..##.###.#.#.\n", + "....#..##.###...#.\n", + "###..##..#..###..#\n", + "..#.##..#.##.##...\n", + "....##....##.##.##\n", + "####..####..#..##.\n", + "#.#.#.#.#.#.....#.\n", + "#...#.#...#..##.#.\n", + "###..####..###...#\n", + "..#.##..#.##..#.##\n", + "....##....##....##\n", + "####..####..####..\n", + "#.#.#.#.#.#.#.#.#.\n", + "#...#.#...#.#...#.\n", + "###..####..####..#" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ (!! 5) $ iterate (applyOnce rules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".#\n", + "##" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ (!(1, 2)) $ explodeGrid $ last $ take 3 $ iterate (applyOnce rules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [], + "source": [ + "countLit = M.size . M.filter id" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "countLit initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "##.##.\n", + "#..#..\n", + "......\n", + "##.##.\n", + "#..#..\n", + "......" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "putStrLn $ showGrid $ (!! 2) $ iterate (applyOnce sampleRules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "countLit $ (!! 2) $ iterate (applyOnce sampleRules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "158" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "countLit $ (!! 5) $ iterate (applyOnce rules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2301762" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "countLit $ (!! 18) $ iterate (applyOnce rules) initialGrid" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Haskell", + "language": "haskell", + "name": "haskell" + }, + "language_info": { + "codemirror_mode": "ihaskell", + "file_extension": ".hs", + "name": "haskell", + "version": "8.0.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}