Day 23 done
[advent-of-code-17.git] / src / advent23 / advent23.ipynb
diff --git a/src/advent23/advent23.ipynb b/src/advent23/advent23.ipynb
new file mode 100644 (file)
index 0000000..e6d3944
--- /dev/null
@@ -0,0 +1,906 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{-# LANGUAGE NegativeLiterals #-}\n",
+    "{-# LANGUAGE FlexibleContexts #-}\n",
+    "{-# LANGUAGE OverloadedStrings #-}\n",
+    "{-# LANGUAGE TypeFamilies #-}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>/* Styles used for the Hoogle display in the pager */\n",
+       ".hoogle-doc {\n",
+       "display: block;\n",
+       "padding-bottom: 1.3em;\n",
+       "padding-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-code {\n",
+       "display: block;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "}\n",
+       ".hoogle-text {\n",
+       "display: block;\n",
+       "}\n",
+       ".hoogle-name {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-head {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-sub {\n",
+       "display: block;\n",
+       "margin-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-package {\n",
+       "font-weight: bold;\n",
+       "font-style: italic;\n",
+       "}\n",
+       ".hoogle-module {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-class {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".get-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "white-space: pre-wrap;\n",
+       "}\n",
+       ".show-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "margin-left: 1em;\n",
+       "}\n",
+       ".mono {\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "}\n",
+       ".err-msg {\n",
+       "color: red;\n",
+       "font-style: italic;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "display: block;\n",
+       "}\n",
+       "#unshowable {\n",
+       "color: red;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".err-msg.in.collapse {\n",
+       "padding-top: 0.7em;\n",
+       "}\n",
+       ".highlight-code {\n",
+       "white-space: pre;\n",
+       "font-family: monospace;\n",
+       "}\n",
+       ".suggestion-warning { \n",
+       "font-weight: bold;\n",
+       "color: rgb(200, 130, 0);\n",
+       "}\n",
+       ".suggestion-error { \n",
+       "font-weight: bold;\n",
+       "color: red;\n",
+       "}\n",
+       ".suggestion-name {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       "</style><span class='err-msg'>&lt;interactive&gt;:1:1: error:<br/>    Failed to load interface for ‘Data.Numbers.Primes’</span>"
+      ],
+      "text/plain": [
+       "<interactive>:1:1: error:\n",
+       "    Failed to load interface for ‘Data.Numbers.Primes’\n",
+       "    Use -v to see a list of the files searched for."
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "-- import Prelude hiding ((++))\n",
+    "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",
+    "\n",
+    "import qualified Data.Map.Strict as M\n",
+    "import Data.Map.Strict ((!))\n",
+    "\n",
+    "import Control.Monad (when)\n",
+    "import Control.Monad.State.Lazy\n",
+    "import Control.Monad.Reader\n",
+    "import Control.Monad.Writer\n",
+    "\n",
+    "import Data.Numbers.Primes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "data Location = Literal Integer | Register Char deriving (Show, Eq)\n",
+    "data Instruction =   Set Location Location \n",
+    "                   | Sub Location Location \n",
+    "                   | Mul Location Location\n",
+    "                   | Jnz Location Location\n",
+    "                   deriving (Show, Eq)\n",
+    "\n",
+    "data Machine = Machine { registers :: M.Map Char Integer\n",
+    "                       , pc :: Int\n",
+    "                       } \n",
+    "               deriving (Show, Eq)\n",
+    "\n",
+    "type ProgrammedMachine = WriterT [String] (ReaderT [Instruction] (State Machine)) ()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "emptyMachine = Machine {registers = M.empty, pc = 0}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sc :: Parser ()\n",
+    "sc = L.space (skipSome spaceChar) CA.empty CA.empty\n",
+    "\n",
+    "lexeme  = L.lexeme sc\n",
+    "\n",
+    "integer       = lexeme L.integer\n",
+    "signedInteger = L.signed sc integer\n",
+    "\n",
+    "symbol = L.symbol sc\n",
+    "\n",
+    "-- reg :: Parser String\n",
+    "-- reg = id <$> some letterChar\n",
+    "\n",
+    "reg = lexeme (some letterChar)\n",
+    "\n",
+    "location = (Literal <$> signedInteger) <|> register\n",
+    "register = (Register . head) <$> reg\n",
+    "\n",
+    "instructionsP = instructionP `sepBy` space\n",
+    "instructionP = choice [setP, subP, mulP, jnzP]\n",
+    "\n",
+    "setP = Set <$> (try (symbol \"set\") *> register) <*> location\n",
+    "subP = Sub <$> (try (symbol \"sub\") *> register) <*> location\n",
+    "mulP = Mul <$> (try (symbol \"mul\") *> register) <*> location\n",
+    "jnzP = Jnz <$> (try (symbol \"jnz\") *> location) <*> location\n",
+    "\n",
+    "successfulParse :: Text -> [Instruction]\n",
+    "successfulParse input = \n",
+    "        case parse instructionsP \"input\" input of\n",
+    "                Left  _error -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err\n",
+    "                Right instructions  -> instructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sample = T.pack \"set a 1\\nsub a 2\\nmul a a\\njnz a 5\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[Set (Register 'a') (Literal 1),Sub (Register 'a') (Literal 2),Mul (Register 'a') (Register 'a'),Jnz (Register 'a') (Literal 5)]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "sampleInstructions = successfulParse sample\n",
+    "sampleInstructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "isMul :: Instruction -> Bool\n",
+    "isMul (Mul _ _ ) = True\n",
+    "isMul _ = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "isJnz :: Instruction -> Bool\n",
+    "isJnz (Jnz _ _ ) = True\n",
+    "isJnz _ = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "evaluate :: Machine -> Location -> Integer\n",
+    "evaluate _ (Literal i)  = i\n",
+    "evaluate m (Register r) = M.findWithDefault 0 r (registers m)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "applyInstruction :: Instruction -> Machine -> Machine\n",
+    "\n",
+    "applyInstruction (Set (Register a) b) m = m {registers = reg', pc = pc'}\n",
+    "    where pc' = pc m + 1\n",
+    "          y = evaluate m b\n",
+    "          reg' = M.insert a y $ registers m\n",
+    "\n",
+    "applyInstruction (Sub (Register a) b) m = m {registers = reg', pc = pc'}\n",
+    "    where pc' = pc m + 1\n",
+    "          x = evaluate m (Register a) \n",
+    "          y = evaluate m b\n",
+    "          reg' = M.insert a (x - y) $ registers m\n",
+    "\n",
+    "applyInstruction (Mul (Register a) b) m = m {registers = reg', pc = pc'}\n",
+    "    where pc' = pc m + 1\n",
+    "          x = evaluate m (Register a) \n",
+    "          y = evaluate m b\n",
+    "          reg' = M.insert a (x * y) $ registers m\n",
+    "\n",
+    "applyInstruction (Jnz a b) m = m {pc = pc'}\n",
+    "    where x = evaluate m a\n",
+    "          y = evaluate m b\n",
+    "          pc' = if x /= 0 then pc m + (fromIntegral y) else pc m + 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "executeInstructionPeep :: ProgrammedMachine\n",
+    "executeInstructionPeep =\n",
+    "    do  instrs <- ask\n",
+    "        m <- get\n",
+    "        let sample1 = take (length sample1Target) $ drop (pc m) $ instrs\n",
+    "        if sample1 == sample1Target\n",
+    "            -- then trace (\"Peeping 1 \" ++ (show m) ++ \" to \" ++ (show m1)) m1\n",
+    "            then do let reg1 = M.union (M.fromList [ ('d', 2), ('e', evaluate m (Register 'b'))\n",
+    "                                                   , ('f', 0), ('g', 0)\n",
+    "                                                   ]) \n",
+    "                                       (registers m)\n",
+    "                    let m1 = m {registers = reg1, pc = pc m + (length sample1)}\n",
+    "                    put m1\n",
+    "            else executeInstruction\n",
+    "    where \n",
+    "--           sample1 = take (length sample1Target) $ drop (pc m) $ instrs\n",
+    "          sample1Target = [ Set (Register 'b') (Literal 4)\n",
+    "                          , Set (Register 'f') (Literal 1)\n",
+    "                          , Set (Register 'd') (Literal 2)\n",
+    "                          , Set (Register 'e') (Literal 2)\n",
+    "                          , Set (Register 'g') (Register 'd')\n",
+    "                          , Mul (Register 'g') (Register 'e')\n",
+    "                          , Sub (Register 'g') (Register 'b')\n",
+    "                          , Jnz (Register 'g') (Literal 2)\n",
+    "                          , Set (Register 'f') (Literal 0)\n",
+    "                          , Sub (Register 'e') (Literal (-1))\n",
+    "                          , Set (Register 'g') (Register 'e')\n",
+    "                          , Sub (Register 'g') (Register 'b')\n",
+    "                          , Jnz (Register 'g') (Literal (-8))\n",
+    "                          ]\n",
+    "--           reg1 = M.union (M.fromList [ ('d', 2), ('e', evaluate m (Register 'b'))\n",
+    "--                                      , ('f', 0), ('g', 0)\n",
+    "--                                      ]) \n",
+    "--                          (registers m)\n",
+    "--           m1 = m {registers = reg1, pc = pc m + (length sample1)}\n",
+    "          "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "executeInstruction :: ProgrammedMachine\n",
+    "executeInstruction =\n",
+    "    do  instrs <- ask\n",
+    "        m <- get\n",
+    "        let instr = instrs!!(pc m)\n",
+    "--         tell [(\"pc = \" ++ show (pc m))]\n",
+    "        put (applyInstruction instr m)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "executeInstructions = \n",
+    "    do  instrs <- ask\n",
+    "        m <- get\n",
+    "        when (pc m >= 0 && pc m < length instrs)\n",
+    "            $\n",
+    "            do when (isMul $ instrs !! pc m) (tell [\"mul\"])\n",
+    "               when (isJnz $ instrs !! pc m) (tell [show m])\n",
+    "--                executeInstructionPeep\n",
+    "               executeInstruction\n",
+    "               executeInstructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "executeInstructionsPeep = \n",
+    "    do  instrs <- ask\n",
+    "        m <- get\n",
+    "        when (pc m >= 0 && pc m < length instrs)\n",
+    "            $\n",
+    "            do -- when (isMul $ instrs !! pc m) (tell [\"mul\"])\n",
+    "               -- when (isJnz $ instrs !! pc m) (tell [show m])\n",
+    "               executeInstructionPeep\n",
+    "               executeInstructionsPeep"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((),[\"mul\",\"Machine {registers = fromList [('a',1)], pc = 3}\"]),Machine {registers = fromList [('a',1)], pc = 8})"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "runState (runReaderT (runWriterT executeInstructions) sampleInstructions ) emptyMachine"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((),[\"mul\",\"Machine {registers = fromList [('a',1)], pc = 3}\"]),Machine {registers = fromList [('a',1)], pc = 8})"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "runState (\n",
+    "    runReaderT (\n",
+    "        runWriterT executeInstructions\n",
+    "               ) \n",
+    "        (take 7 sampleInstructions) \n",
+    "         ) \n",
+    "         emptyMachine"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[Set (Register 'a') (Literal 1),Sub (Register 'a') (Literal 2),Mul (Register 'a') (Register 'a'),Jnz (Register 'a') (Literal 5)]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "sampleInstructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "part1 instructions = \n",
+    "    runState (\n",
+    "        runReaderT (\n",
+    "            runWriterT executeInstructions\n",
+    "                   ) \n",
+    "            instructions \n",
+    "             ) \n",
+    "             emptyMachine"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "main :: IO ()\n",
+    "main = do \n",
+    "        text <- TIO.readFile \"../../data/advent23.txt\"\n",
+    "        let instrs = successfulParse text\n",
+    "        let ((result, l), machinef) = part1 instrs\n",
+    "--         print $ head l\n",
+    "        print $ length $ filter (== \"mul\") l\n",
+    "--         print $ part2 instrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "6724"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "main"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>/* Styles used for the Hoogle display in the pager */\n",
+       ".hoogle-doc {\n",
+       "display: block;\n",
+       "padding-bottom: 1.3em;\n",
+       "padding-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-code {\n",
+       "display: block;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "}\n",
+       ".hoogle-text {\n",
+       "display: block;\n",
+       "}\n",
+       ".hoogle-name {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-head {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-sub {\n",
+       "display: block;\n",
+       "margin-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-package {\n",
+       "font-weight: bold;\n",
+       "font-style: italic;\n",
+       "}\n",
+       ".hoogle-module {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-class {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".get-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "white-space: pre-wrap;\n",
+       "}\n",
+       ".show-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "margin-left: 1em;\n",
+       "}\n",
+       ".mono {\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "}\n",
+       ".err-msg {\n",
+       "color: red;\n",
+       "font-style: italic;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "display: block;\n",
+       "}\n",
+       "#unshowable {\n",
+       "color: red;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".err-msg.in.collapse {\n",
+       "padding-top: 0.7em;\n",
+       "}\n",
+       ".highlight-code {\n",
+       "white-space: pre;\n",
+       "font-family: monospace;\n",
+       "}\n",
+       ".suggestion-warning { \n",
+       "font-weight: bold;\n",
+       "color: rgb(200, 130, 0);\n",
+       "}\n",
+       ".suggestion-error { \n",
+       "font-weight: bold;\n",
+       "color: red;\n",
+       "}\n",
+       ".suggestion-name {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       "</style><div class=\"suggestion-name\" style=\"clear:both;\">Eta reduce</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">runTest instructions machine0\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructions) instructions)\n",
+       "      machine0</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">runTest instructions\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructions) instructions)</div></div>"
+      ],
+      "text/plain": [
+       "Line 1: Eta reduce\n",
+       "Found:\n",
+       "runTest instructions machine0\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructions) instructions)\n",
+       "      machine0\n",
+       "Why not:\n",
+       "runTest instructions\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructions) instructions)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "runTest instructions machine0 = \n",
+    "    runState (\n",
+    "        runReaderT (\n",
+    "            runWriterT executeInstructions\n",
+    "                   ) \n",
+    "            instructions \n",
+    "             ) \n",
+    "             machine0"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>/* Styles used for the Hoogle display in the pager */\n",
+       ".hoogle-doc {\n",
+       "display: block;\n",
+       "padding-bottom: 1.3em;\n",
+       "padding-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-code {\n",
+       "display: block;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "}\n",
+       ".hoogle-text {\n",
+       "display: block;\n",
+       "}\n",
+       ".hoogle-name {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-head {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-sub {\n",
+       "display: block;\n",
+       "margin-left: 0.4em;\n",
+       "}\n",
+       ".hoogle-package {\n",
+       "font-weight: bold;\n",
+       "font-style: italic;\n",
+       "}\n",
+       ".hoogle-module {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".hoogle-class {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".get-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "white-space: pre-wrap;\n",
+       "}\n",
+       ".show-type {\n",
+       "color: green;\n",
+       "font-weight: bold;\n",
+       "font-family: monospace;\n",
+       "margin-left: 1em;\n",
+       "}\n",
+       ".mono {\n",
+       "font-family: monospace;\n",
+       "display: block;\n",
+       "}\n",
+       ".err-msg {\n",
+       "color: red;\n",
+       "font-style: italic;\n",
+       "font-family: monospace;\n",
+       "white-space: pre;\n",
+       "display: block;\n",
+       "}\n",
+       "#unshowable {\n",
+       "color: red;\n",
+       "font-weight: bold;\n",
+       "}\n",
+       ".err-msg.in.collapse {\n",
+       "padding-top: 0.7em;\n",
+       "}\n",
+       ".highlight-code {\n",
+       "white-space: pre;\n",
+       "font-family: monospace;\n",
+       "}\n",
+       ".suggestion-warning { \n",
+       "font-weight: bold;\n",
+       "color: rgb(200, 130, 0);\n",
+       "}\n",
+       ".suggestion-error { \n",
+       "font-weight: bold;\n",
+       "color: red;\n",
+       "}\n",
+       ".suggestion-name {\n",
+       "font-weight: bold;\n",
+       "}\n",
+       "</style><div class=\"suggestion-name\" style=\"clear:both;\">Eta reduce</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">runTestPeep instructions machine0\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructionsPeep) instructions)\n",
+       "      machine0</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">runTestPeep instructions\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructionsPeep) instructions)</div></div>"
+      ],
+      "text/plain": [
+       "Line 1: Eta reduce\n",
+       "Found:\n",
+       "runTestPeep instructions machine0\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructionsPeep) instructions)\n",
+       "      machine0\n",
+       "Why not:\n",
+       "runTestPeep instructions\n",
+       "  = runState\n",
+       "      (runReaderT (runWriterT executeInstructionsPeep) instructions)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "runTestPeep instructions machine0 = \n",
+    "    runState (\n",
+    "        runReaderT (\n",
+    "            runWriterT executeInstructionsPeep\n",
+    "                   ) \n",
+    "            instructions \n",
+    "             ) \n",
+    "             machine0"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[Set (Register 'b') (Literal 4),Set (Register 'f') (Literal 1),Set (Register 'd') (Literal 2),Set (Register 'e') (Literal 2),Set (Register 'g') (Register 'd'),Mul (Register 'g') (Register 'e'),Sub (Register 'g') (Register 'b'),Jnz (Register 'g') (Literal 2),Set (Register 'f') (Literal 0),Sub (Register 'e') (Literal (-1)),Set (Register 'g') (Register 'e'),Sub (Register 'g') (Register 'b'),Jnz (Register 'g') (Literal (-8))]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "peepTest1T = T.pack \"set b 4\\nset f 1\\nset d 2\\nset e 2\\nset g d\\nmul g e\\nsub g b\\njnz g 2\\nset f 0\\nsub e -1\\nset g e\\nsub g b\\njnz g -8\"\n",
+    "peepTest1 = successfulParse peepTest1T\n",
+    "peepTest1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[\"mul\",\"Machine {registers = fromList [('b',4),('d',2),('e',2),('f',1),('g',0)], pc = 7}\",\"Machine {registers = fromList [('b',4),('d',2),('e',3),('f',0),('g',-1)], pc = 12}\",\"mul\",\"Machine {registers = fromList [('b',4),('d',2),('e',3),('f',0),('g',2)], pc = 7}\",\"Machine {registers = fromList [('b',4),('d',2),('e',4),('f',0),('g',0)], pc = 12}\"]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "((v, t), m) = runTest peepTest1 emptyMachine\n",
+    "t"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "text <- TIO.readFile \"../../data/advent23.txt\"\n",
+    "let fullInstrs = successfulParse text"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[Set (Register 'b') (Literal 84),Set (Register 'c') (Register 'b'),Jnz (Register 'a') (Literal 2),Jnz (Literal 1) (Literal 5),Mul (Register 'b') (Literal 100),Sub (Register 'b') (Literal (-100000)),Set (Register 'c') (Register 'b'),Sub (Register 'c') (Literal (-17000)),Set (Register 'f') (Literal 1),Set (Register 'd') (Literal 2),Set (Register 'e') (Literal 2),Set (Register 'g') (Register 'd'),Mul (Register 'g') (Register 'e'),Sub (Register 'g') (Register 'b'),Jnz (Register 'g') (Literal 2),Set (Register 'f') (Literal 0),Sub (Register 'e') (Literal (-1)),Set (Register 'g') (Register 'e'),Sub (Register 'g') (Register 'b'),Jnz (Register 'g') (Literal (-8)),Sub (Register 'd') (Literal (-1)),Set (Register 'g') (Register 'd'),Sub (Register 'g') (Register 'b'),Jnz (Register 'g') (Literal (-13)),Jnz (Register 'f') (Literal 2),Sub (Register 'h') (Literal (-1)),Set (Register 'g') (Register 'b'),Sub (Register 'g') (Register 'c'),Jnz (Register 'g') (Literal 2),Jnz (Literal 1) (Literal 3),Sub (Register 'b') (Literal (-17)),Jnz (Literal 1) (Literal (-23))]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fullInstrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Machine {registers = fromList [('b',84),('c',84),('d',84),('e',84),('f',0),('g',0),('h',1)], pc = 32}"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "((v, t), m) = runTest fullInstrs emptyMachine\n",
+    "m"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Machine {registers = fromList [('b',84),('c',84),('d',84),('e',84),('f',0),('g',0),('h',1)], pc = 32}"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "((v, t), m) = runTestPeep fullInstrs emptyMachine\n",
+    "m"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "((v, t), m) = runTestPeep fullInstrs (emptyMachine {registers = M.fromList [('a', 1)]})\n",
+    "m"
+   ]
+  },
+  {
+   "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
+}