X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=src%2Fadvent08%2Fadvent08.ipynb;fp=src%2Fadvent08%2Fadvent08.ipynb;h=888fe22c3fde5575a0f6bfcb6fc2b7e6474bc3de;hb=51a92db02eaf7bea8f14f9e6a2b01223b606de69;hp=0000000000000000000000000000000000000000;hpb=6761ab55989d276c113c7604b52356789a79c5ca;p=advent-of-code-17.git diff --git a/src/advent08/advent08.ipynb b/src/advent08/advent08.ipynb new file mode 100644 index 0000000..888fe22 --- /dev/null +++ b/src/advent08/advent08.ipynb @@ -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 +}