Day 8
[advent-of-code-17.git] / src / advent08 / advent08.ipynb
diff --git a/src/advent08/advent08.ipynb b/src/advent08/advent08.ipynb
new file mode 100644 (file)
index 0000000..888fe22
--- /dev/null
@@ -0,0 +1,416 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{-# LANGUAGE NegativeLiterals #-}\n",
+    "{-# LANGUAGE FlexibleContexts #-}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import Text.Parsec \n",
+    "import Text.ParserCombinators.Parsec.Number\n",
+    "import qualified Data.Map.Strict as M"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "data Instruction = Instruction \n",
+    "                    { register :: String\n",
+    "                    , direction :: String\n",
+    "                    , change :: Int\n",
+    "                    , conditionRegister :: String\n",
+    "                    , operation :: String\n",
+    "                    , comparator :: Int\n",
+    "                    } deriving (Show, Eq)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "type Memory = M.Map String Int"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "onlySpaces = many (oneOf \" \\t\")\n",
+    "symP = (many lower) <* onlySpaces\n",
+    "operationP = (many1 (oneOf \"!<>=\")) <* onlySpaces"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "iFile = iLine `sepBy` newline \n",
+    "iLine = instructify <$> symP \n",
+    "                    <*> symP \n",
+    "                    <*> int \n",
+    "                    <*> ( onlySpaces *> string \"if\" *> onlySpaces *> symP )\n",
+    "                    <*> operationP \n",
+    "                    <*> int\n",
+    "    where instructify r d c cr o p = Instruction { register = r\n",
+    "                                                 , direction = d\n",
+    "                                                 , change = c\n",
+    "                                                 , conditionRegister = cr\n",
+    "                                                 , operation = o\n",
+    "                                                 , comparator = p\n",
+    "                                                 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "parseFile :: String -> Either ParseError [Instruction]\n",
+    "parseFile input = parse iFile \"(unknown)\" input\n",
+    "\n",
+    "parseLine :: String -> Either ParseError Instruction\n",
+    "parseLine input = parse iLine \"(unknown)\" input\n",
+    "\n",
+    "successfulParse :: Either ParseError [a] -> [a]\n",
+    "successfulParse (Left _) = []\n",
+    "successfulParse (Right a) = a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Right (Instruction {register = \"b\", direction = \"inc\", change = 5, conditionRegister = \"a\", operation = \">\", comparator = 1})"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "parseLine \"b inc 5 if a > 1\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sampleT = \"b inc 5 if a > 1\\na inc 1 if b < 5\\nc dec -10 if a >= 1\\nc inc -20 if c == 10\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[Instruction {register = \"b\", direction = \"inc\", change = 5, conditionRegister = \"a\", operation = \">\", comparator = 1},Instruction {register = \"a\", direction = \"inc\", change = 1, conditionRegister = \"b\", operation = \"<\", comparator = 5},Instruction {register = \"c\", direction = \"dec\", change = -10, conditionRegister = \"a\", operation = \">=\", comparator = 1},Instruction {register = \"c\", direction = \"inc\", change = -20, conditionRegister = \"c\", operation = \"==\", comparator = 10}]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "sample = successfulParse $ parseFile sampleT\n",
+    "sample"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "conditionEval :: Int -> String -> Int -> Bool\n",
+    "conditionEval reg op val\n",
+    "    | op == \"==\" = reg == val\n",
+    "    | op == \"<\"  = reg < val\n",
+    "    | op == \">\"  = reg > val\n",
+    "    | op == \"<=\" = reg <= val\n",
+    "    | op == \">=\" = reg >= val\n",
+    "    | op == \"!=\" = reg /= val"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "-- effectiveChange :: String -> Int -> Int\n",
+    "-- effectiveChange dir val\n",
+    "--     | dir == \"inc\" = val\n",
+    "--     | dir == \"dec\" = - val"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "effectiveChange :: String -> Int -> Int\n",
+    "effectiveChange \"inc\" val = val\n",
+    "effectiveChange \"dec\" val = -val"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "processInstruction memory instruction = memory'\n",
+    "    where v = M.findWithDefault 0 (register instruction) memory\n",
+    "          cv = M.findWithDefault 0 (conditionRegister instruction) memory\n",
+    "          condition = conditionEval cv (operation instruction) (comparator instruction)\n",
+    "          delta = effectiveChange (direction instruction) (change instruction)\n",
+    "          memory' = if condition\n",
+    "                    then M.insert (register instruction) (v + delta) memory\n",
+    "                    else memory"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "processInstructions = foldl processInstruction M.empty "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "fromList [(\"a\",1),(\"c\",-10)]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "processInstructions sample"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "largestValue m \n",
+    "    | M.null m = 0\n",
+    "    | otherwise = maximum $ M.elems m"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "largestValue $ processInstructions sample"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "part1 = largestValue . processInstructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "-- part1 = processInstructions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "main :: IO ()\n",
+    "main = do \n",
+    "        text <- readFile \"../../data/advent08.txt\"\n",
+    "        let instrs = successfulParse $ parseFile text\n",
+    "        print $ part1 instrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4647"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "main"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "processInstructionH (highest, memory) instruction = (highest', memory')\n",
+    "    where memory' = processInstruction memory instruction\n",
+    "          h = largestValue memory'\n",
+    "          highest' = if h > highest then h else highest"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "processInstructionsH = foldl processInstructionH (0, M.empty)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(10,fromList [(\"a\",1),(\"c\",-10)])"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "processInstructionsH sample"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "part2 = fst . processInstructionsH"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "main :: IO ()\n",
+    "main = do \n",
+    "        text <- readFile \"../../data/advent08.txt\"\n",
+    "        let instrs = successfulParse $ parseFile text\n",
+    "        print $ part1 instrs\n",
+    "        print $ part2 instrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4647\n",
+       "5590"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "main"
+   ]
+  },
+  {
+   "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
+}