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