Day 22
[advent-of-code-17.git] / src / advent22 / advent22b.ipynb
diff --git a/src/advent22/advent22b.ipynb b/src/advent22/advent22b.ipynb
new file mode 100644 (file)
index 0000000..d752b20
--- /dev/null
@@ -0,0 +1,373 @@
+{
+ "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 Prelude hiding (Left, Right)\n",
+    "import Data.List\n",
+    "import qualified Data.Map as M"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "type Point = (Int, Int)\n",
+    "\n",
+    "data Flag = Clean | Weakened | Infected | Flagged deriving (Show, Eq)\n",
+    "\n",
+    "type Infection = M.Map Point Flag\n",
+    "\n",
+    "data Direction = Up | Right | Down | Left deriving (Show, Eq, Enum)\n",
+    "\n",
+    "data World = World { infected :: Infection\n",
+    "                   , position :: Point\n",
+    "                   , direction :: Direction\n",
+    "                   , infectionCount :: Int\n",
+    "                   } deriving (Eq, Show)\n",
+    "                   "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "text <- readFile \"../../data/advent22.txt\"\n",
+    "grid = lines text"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sampleGrid = lines \"..#\\n#..\\n...\\n\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "initialInfected g = M.fromList [((r, c), Infected) | r <- [0..(length g - 1)], c <- [0..((length . head) g - 1)],\n",
+    "                                        g!!r!!c == '#']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "fromList [((0,2),Infected),((1,0),Infected)]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "initialInfected sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "initialPosition g = (length g `div` 2, (length . head) g `div` 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(1,1)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "initialPosition sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "leftOf Up = Left\n",
+    "leftOf x = pred x\n",
+    "\n",
+    "rightOf Left = Up\n",
+    "rightOf x = succ x"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Down"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "leftOf Left"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "delta :: Direction -> Point\n",
+    "delta Up = (-1, 0)\n",
+    "delta Right = (0, 1)\n",
+    "delta Down = (1, 0)\n",
+    "delta Left = (0, -1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "(+:) (r, c) (dr, dc) = (r + dr, c + dc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "initialWorld grid = World \n",
+    "    { infected = initialInfected grid\n",
+    "    , position = initialPosition grid\n",
+    "    , direction = Up\n",
+    "    , infectionCount = 0\n",
+    "    }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "World {infected = fromList [((0,2),Infected),((1,0),Infected)], position = (1,1), direction = Up, infectionCount = 0}"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "initialWorld sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "step world = World {infected = inf', position = pos', direction = dir', infectionCount = ic'}\n",
+    "    where here = position world\n",
+    "          stateHere = M.findWithDefault Clean here (infected world)\n",
+    "          dir' = case stateHere of \n",
+    "                      Clean -> leftOf (direction world)\n",
+    "                      Weakened -> direction world\n",
+    "                      Infected -> rightOf (direction world)\n",
+    "                      Flagged -> rightOf (rightOf (direction world))\n",
+    "          stateHere' = case stateHere of \n",
+    "                      Clean -> Weakened\n",
+    "                      Weakened -> Infected\n",
+    "                      Infected -> Flagged\n",
+    "                      Flagged -> Clean\n",
+    "          inf' = M.insert here stateHere' (infected world)\n",
+    "          \n",
+    "          ic'  = if stateHere' == Infected then infectionCount world + 1\n",
+    "                                           else infectionCount world\n",
+    "          pos' = here +: delta dir'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "World {infected = fromList [((0,2),Infected),((1,0),Flagged),((1,1),Weakened)], position = (0,0), direction = Up, infectionCount = 0}"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "step $ step $ initialWorld sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "progress n = (!! n) . iterate step "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "World {infected = fromList [((0,-1),Weakened),((0,0),Weakened),((0,2),Infected),((1,-1),Infected),((1,0),Clean),((1,1),Weakened)], position = (1,-2), direction = Left, infectionCount = 1}"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "progress 7 $ initialWorld sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "26"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "infectionCount $ progress 100 $ initialWorld sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2511944"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "infectionCount $ progress 10000000 $ initialWorld sampleGrid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2512008"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "infectionCount $ progress 10000000 $ initialWorld grid"
+   ]
+  },
+  {
+   "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
+}