+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "{-# LANGUAGE NegativeLiterals #-}\n",
+ "{-# LANGUAGE FlexibleContexts #-}\n",
+ "{-# LANGUAGE OverloadedStrings #-}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import Data.Text (Text)\n",
+ "import qualified Data.Text as T\n",
+ "import qualified Data.Text.IO as TIO\n",
+ "\n",
+ "import Text.Megaparsec\n",
+ "import qualified Text.Megaparsec.Lexer as L\n",
+ "import Text.Megaparsec.Text (Parser)\n",
+ "\n",
+ "import qualified Data.Map.Strict as M\n",
+ "import Data.Map.Strict ((!))\n",
+ "\n",
+ "import qualified Data.Set as S\n",
+ "import qualified Control.Applicative as CA"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scanner :: Integer -> Integer -> Integer -> Integer\n",
+ "scanner depth range t = \n",
+ " let t' = (t + depth) `mod` ((range - 1) * 2)\n",
+ " in if t' < range\n",
+ " then t' \n",
+ " else t' + (t' - range + 1) * -2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sc :: Parser ()\n",
+ "sc = L.space (skipSome spaceChar) CA.empty CA.empty\n",
+ "\n",
+ "lexeme = L.lexeme sc\n",
+ "integer = lexeme L.integer\n",
+ "symb = L.symbol sc\n",
+ "\n",
+ "scannersP = many scannerP\n",
+ "\n",
+ "scannerP = (,) <$> integer <*> (symb \":\" *> integer)\n",
+ "\n",
+ "successfulParse :: Text -> [(Integer, Integer)]\n",
+ "successfulParse input = \n",
+ " case parse scannersP \"input\" input of\n",
+ " Left err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err\n",
+ " Right scanners -> scanners"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "[0,1,2,3,4, 3, 2, 1,0,1,2,3] res = t' + x\n",
+ "[0,1,2,3,4, 5, 6, 7,0,1,2,3] t'\n",
+ "[ 0, 1, 2 t' - len\n",
+ " -2,-4,-6 x\n",
+ "\n",
+ "cycle is 5 + (5-2) = 8\n",
+ "\n",
+ "if t' <= 5 then t' else 5 - t' + 1\n",
+ "\n",
+ "\n",
+ "0 1 2 3 4 5 6 7 8 \n",
+ "S . . . . . . .\n",
+ ". S . . . . . .\n",
+ ". . S . . . . .\n",
+ ". . . S . . . .\n",
+ ". . . . S . . .\n",
+ ". . . . . S . .\n",
+ ". . . . . . S .\n",
+ ". . . . . . . S\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,0,1,2,3,4]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "s50 = scanner 0 5\n",
+ "map s50 [0..20]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0,1,2,1,0,1,2,1,0,1,2,1,0,1,2,1,0,1,2,1,0]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "s30 = scanner 0 3\n",
+ "map s30 [0..20]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[3,2,1,0,1,2,3,2,1,0,1,2,3,2,1,0,1,2,3,2,1]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "map (scanner 3 4) [0..20]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0,1,2,0]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "[scanner 0 3 0, scanner 1 2 0, scanner 4 4 0, scanner 6 4 0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sample = [(0, 3), (1, 2), (4, 4), (6, 4)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "24"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "sum $ map (uncurry (*)) $ filter (\\(d, r) -> scanner d r 0 == 0) sample "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "part1 :: [(Integer, Integer)] -> Integer\n",
+ "part1 = sum . map (uncurry (*)) . filter (\\(d, r) -> scanner d r 0 == 0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "main :: IO ()\n",
+ "main = do \n",
+ " text <- TIO.readFile \"../../data/advent13.txt\"\n",
+ " let instrs = successfulParse text\n",
+ " print $ part1 instrs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 66,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1904"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "main"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 68,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scanify = map (uncurry scanner)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "canPass scannersF t = all (\\s -> s t /= 0) scannersF"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scs = scanify sample"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 82,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "10"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "head $ filter (canPass scs) [0..]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 81,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2,1,2,2]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "map (\\s -> s 10) scs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "part2 scannerDefs = head $ filter (canPass scanners) [0..]\n",
+ " where scanners = scanify scannerDefs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "main :: IO ()\n",
+ "main = do \n",
+ " text <- TIO.readFile \"../../data/advent13.txt\"\n",
+ " let instrs = successfulParse text\n",
+ " print $ part1 instrs\n",
+ " print $ part2 instrs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1904\n",
+ "3833504"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "main"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "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
+}