{ "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 }