From 39598d4a19968acde767a9af7ce4cf0736062e47 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 27 Dec 2020 12:53:05 +0000 Subject: [PATCH 01/16] Done day 18 --- problems/day18.html | 168 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 problems/day18.html diff --git a/problems/day18.html b/problems/day18.html new file mode 100644 index 0000000..9ac73d5 --- /dev/null +++ b/problems/day18.html @@ -0,0 +1,168 @@ + + + + +Day 18 - Advent of Code 2020 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 35*

   $year=2020;

+ + + +
+ +

--- Day 18: Operation Order ---

As you look out the window and notice a heavily-forested continent slowly appear over the horizon, you are interrupted by the child sitting next to you. They're curious if you could help them with their math homework.

+

Unfortunately, it seems like this "math" follows different rules than you remember.

+

The homework (your puzzle input) consists of a series of expressions that consist of addition (+), multiplication (*), and parentheses ((...)). Just like normal math, parentheses indicate that the expression inside must be evaluated before it can be used by the surrounding expression. Addition still finds the sum of the numbers on both sides of the operator, and multiplication still finds the product.

+

However, the rules of operator precedence have changed. Rather than evaluating multiplication before addition, the operators have the same precedence, and are evaluated left-to-right regardless of the order in which they appear.

+

For example, the steps to evaluate the expression 1 + 2 * 3 + 4 * 5 + 6 are as follows:

+
1 + 2 * 3 + 4 * 5 + 6
+  3   * 3 + 4 * 5 + 6
+      9   + 4 * 5 + 6
+         13   * 5 + 6
+             65   + 6
+                 71
+
+

Parentheses can override this order; for example, here is what happens if parentheses are added to form 1 + (2 * 3) + (4 * (5 + 6)):

+
1 + (2 * 3) + (4 * (5 + 6))
+1 +    6    + (4 * (5 + 6))
+     7      + (4 * (5 + 6))
+     7      + (4 *   11   )
+     7      +     44
+            51
+
+

Here are a few more examples:

+
    +
  • 2 * 3 + (4 * 5) becomes 26.
  • +
  • 5 + (8 * 3 + 9 + 3 * 4 * 3) becomes 437.
  • +
  • 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4)) becomes 12240.
  • +
  • ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2 becomes 13632.
  • +
+

Before you can help with the homework, you need to understand it yourself. Evaluate the expression on each line of the homework; what is the sum of the resulting values?

+
+

Your puzzle answer was 75592527415659.

The first half of this puzzle is complete! It provides one gold star: *

+

--- Part Two ---

You manage to answer the child's questions and they finish part 1 of their homework, but get stuck when they reach the next section: advanced math.

+

Now, addition and multiplication have different precedence levels, but they're not the ones you're familiar with. Instead, addition is evaluated before multiplication.

+

For example, the steps to evaluate the expression 1 + 2 * 3 + 4 * 5 + 6 are now as follows:

+
1 + 2 * 3 + 4 * 5 + 6
+  3   * 3 + 4 * 5 + 6
+  3   *   7   * 5 + 6
+  3   *   7   *  11
+     21       *  11
+         231
+
+

Here are the other examples from above:

+
    +
  • 1 + (2 * 3) + (4 * (5 + 6)) still becomes 51.
  • +
  • 2 * 3 + (4 * 5) becomes 46.
  • +
  • 5 + (8 * 3 + 9 + 3 * 4 * 3) becomes 1445.
  • +
  • 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4)) becomes 669060.
  • +
  • ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2 becomes 23340.
  • +
+

What do you get if you add up the results of evaluating the homework problems using these new rules?

+
+

Answer:

+

Although it hasn't changed, you can still get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file -- 2.34.1 From cc6239892b5dea639d6787a53bffef90a5cf2841 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Mon, 28 Dec 2020 16:17:45 +0000 Subject: [PATCH 02/16] Done day 19, but not sure why attoparsec isn't working --- advent19/package.yaml | 77 +++++ advent19/src/advent19.hs | 87 +++++ advent19/src/advent19atto.hs | 104 ++++++ advent19/src/advent19mega.hs | 114 +++++++ data/advent19.txt | 626 +++++++++++++++++++++++++++++++++++ data/advent19a.txt | 12 + data/advent19b.txt | 47 +++ data/advent19tiny.txt | 11 + problems/day19.html | 233 +++++++++++++ stack.yaml | 1 + 10 files changed, 1312 insertions(+) create mode 100644 advent19/package.yaml create mode 100644 advent19/src/advent19.hs create mode 100644 advent19/src/advent19atto.hs create mode 100644 advent19/src/advent19mega.hs create mode 100644 data/advent19.txt create mode 100644 data/advent19a.txt create mode 100644 data/advent19b.txt create mode 100644 data/advent19tiny.txt create mode 100644 problems/day19.html diff --git a/advent19/package.yaml b/advent19/package.yaml new file mode 100644 index 0000000..1feb922 --- /dev/null +++ b/advent19/package.yaml @@ -0,0 +1,77 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent19 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + +executables: + advent19: + main: advent19.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - containers + + advent19atto: + main: advent19atto.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - attoparsec + - containers + advent19mega: + main: advent19mega.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - megaparsec + - containers diff --git a/advent19/src/advent19.hs b/advent19/src/advent19.hs new file mode 100644 index 0000000..01e872d --- /dev/null +++ b/advent19/src/advent19.hs @@ -0,0 +1,87 @@ +-- import Debug.Trace + +import Text.ParserCombinators.ReadP +-- import Text.ParserCombinators.ReadP ((+++)) +import Data.Char (isDigit, isAlpha) + +import qualified Data.IntMap.Strict as M +import Data.IntMap.Strict ((!)) + +import Data.Functor (void) +import Data.Either + + +data Rule = Letter Char + -- | Then2 Rule Rule + -- | Then3 Rule Rule Rule + | Then [Rule] + | Or Rule Rule + | See Int + deriving (Show, Eq) + +type RuleSet = M.IntMap Rule + + +main :: IO () +main = + do text <- readFile "data/advent19.txt" + -- print text + let (rules, messages) = parse inputP text + print $ part1 rules messages + print $ part2 rules messages + -- print $ part2 text + +setup fname = + do text <- readFile fname + let (rules, messages) = parse inputP text + let newRules = parse rulesP "8: 42 | 42 8\n11: 42 31 | 42 11 31" + let updatedRules = M.union newRules rules + let myParser = makeParser updatedRules (See 0) + return (myParser, updatedRules, messages) + + +part1 = countMatches + +part2 rules messages = countMatches updatedRules messages + where newRules = parse rulesP "8: 42 | 42 8\n11: 42 31 | 42 11 31" + updatedRules = M.union newRules rules + +countMatches rules messages + = length $ filter ((== "") . snd) results + where myParser = makeParser rules (See 0) + results = concatMap (readP_to_S myParser) messages + + +parse :: ReadP a -> String -> a +parse parser str = fst $ head $ filter ((== "") . snd) $ readP_to_S parser str + + +-- Generate the rules + +makeParser :: RuleSet -> Rule -> ReadP () +makeParser m (Letter c) = void $ char c +makeParser m (Then rs) = mapM_ (makeParser m) rs +makeParser m (Or a b) = (makeParser m a) +++ (makeParser m b) +makeParser m (See i) = makeParser m (m!i) + + +-- Parse the input + +rulesP = M.fromList <$> ruleP `sepBy` endOfLine +ruleP = (,) <$> decimal <* (string ": ") <*> ruleBodyP +ruleBodyP = choice [letterRuleP, orRuleP, thenRuleP, seeRuleP] + +letterRuleP = Letter <$> between (string "\"") (string "\"") get +orRuleP = Or <$> thenRuleP <* (string " | ") <*> thenRuleP +thenRuleP = Then <$> seeRuleP `sepBy` (string " ") +seeRuleP = See <$> decimal + + +inputP = (,) <$> rulesP <* blankLines <*> messagesP + +messagesP = (munch1 isAlpha) `sepBy` endOfLine + +blankLines = skipMany1 endOfLine + +decimal = read <$> many1 (satisfy isDigit) +endOfLine = char '\n' diff --git a/advent19/src/advent19atto.hs b/advent19/src/advent19atto.hs new file mode 100644 index 0000000..b322324 --- /dev/null +++ b/advent19/src/advent19atto.hs @@ -0,0 +1,104 @@ +-- import Debug.Trace + +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text +-- import Data.Attoparsec.Combinator +import Control.Applicative +-- import Control.Applicative.Combinators + +import qualified Data.IntMap.Strict as M +import Data.IntMap.Strict ((!)) +import Data.Functor (void) +import Prelude hiding (take) +import Data.Either + + +data Rule = Letter Char + -- | Then2 Rule Rule + -- | Then3 Rule Rule Rule + | Then [Rule] + | Or Rule Rule + | See Int + deriving (Show, Eq) + +-- data Tree = TEmpty +-- | TLetter Char +-- | TThen [Tree] +-- deriving (Show, Eq) + + +type RuleSet = M.IntMap Rule + + +main :: IO () +main = + do text <- TIO.readFile "data/advent19b.txt" + -- print text + let (rules, messages) = successfulParse inputP text + let messagesT = map T.pack messages + -- print rules + -- print messages + print $ part1 rules messagesT + print $ part2 rules messagesT + -- print $ part2 text + +setup fname = + do text <- TIO.readFile fname + let (rules, messages) = successfulParse inputP text + let messagesT = map T.pack messages + let Right newRules = parseOnly rulesP "8: 42 | 42 8\n11: 42 31 | 42 11 31" + let updatedRules = M.union newRules rules + let myParser = (makeParser updatedRules (See 0)) <* endOfInput + return (myParser, updatedRules, messagesT) + + + +part1 = countMatches + +part2 rules messages = countMatches updatedRules messages + where Right newRules = parseOnly rulesP "8: 42 | 42 8\n11: 42 31 | 42 11 31" + updatedRules = M.union newRules rules + +countMatches rules messages + = length + $ filter isRight + $ map (parseOnly myParser) messages + where myParser = ((makeParser rules (See 0)) <* endOfInput) + + +-- Generate the rules + +makeParser :: RuleSet -> Rule -> Parser () +makeParser m (Letter c) = void $ char c +makeParser m (Then rs) = mapM_ (makeParser m) rs +makeParser m (Or a b) = (makeParser m a) <|> (makeParser m b) +makeParser m (See i) = makeParser m (m!i) + + +-- Parse the input + +rulesP = M.fromList <$> ruleP `sepBy` endOfLine +ruleP = (,) <$> decimal <* ": " <*> ruleBodyP +ruleBodyP = choice [letterRuleP, orRuleP, thenRuleP, seeRuleP] + +letterRuleP = Letter <$> ("\"" *> anyChar) <* "\"" +orRuleP = Or <$> thenRuleP <* " | " <*> thenRuleP +thenRuleP = Then <$> seeRuleP `sepBy` (string " ") +seeRuleP = See <$> decimal + + +inputP = (,) <$> rulesP <* blankLines <*> messagesP + +messagesP = (many1 letter) `sepBy` endOfLine + +blankLines = skipMany1 endOfLine + + +-- successfulParse :: Text -> (Integer, [Maybe Integer]) +successfulParse parser input = + case parseOnly parser input of + Left _err -> (M.empty, []) -- TIO.putStr $ T.pack $ parseErrorPretty err + Right expressions -> expressions diff --git a/advent19/src/advent19mega.hs b/advent19/src/advent19mega.hs new file mode 100644 index 0000000..073d6cf --- /dev/null +++ b/advent19/src/advent19mega.hs @@ -0,0 +1,114 @@ +-- import Debug.Trace + +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Void (Void) + +import Text.Megaparsec hiding (State) +import Text.Megaparsec.Char +import qualified Text.Megaparsec.Char.Lexer as L +import qualified Control.Applicative as CA + +import qualified Data.IntMap.Strict as M +import Data.IntMap.Strict ((!)) +import Data.Functor (void) +import Prelude hiding (take) +import Data.Either + + +data Rule = Letter Char + | Then [Rule] + | Or Rule Rule + | See Int + deriving (Show, Eq) + +type RuleSet = M.IntMap Rule + + +main :: IO () +main = + do text <- TIO.readFile "data/advent19b.txt" + -- print text + let (rules, messages) = successfulParse text + let messagesT = map T.pack messages + -- print rules + -- print messages + print $ part1 rules messagesT + print $ part2 rules messagesT + -- print $ part2 text + +setup fname = + do text <- TIO.readFile fname + let (rules, messages) = successfulParse text + let messagesT = map T.pack messages + let Right newRules = parse rulesP "rules" "8: 42 | 42 8\n11: 42 31 | 42 11 31" + let updatedRules = M.union newRules rules + let myParser = (makeParser updatedRules (See 0)) -- <* eof + return (myParser, updatedRules, messagesT) + + + +part1 = countMatches + +part2 rules messages = countMatches updatedRules messages + where Right newRules = parse rulesP "rules" "8: 42 | 42 8\n11: 42 31 | 42 11 31" + updatedRules = M.union newRules rules + +countMatches rules messages + = length + $ filter isRight + $ map (parse myParser "message") messages + where myParser = (makeParser rules (See 0)) -- <* eof + +prettyResults rs = map p rs + where p (Left e) = errorBundlePretty e + p (Right r) = "^" ++ show r + + +-- Generate the rules + +makeParser :: RuleSet -> Rule -> Parser () +makeParser m (Letter c) = void $ char c +makeParser m (Then rs) = mapM_ (makeParser m) rs +makeParser m (Or a b) = (try (makeParser m a)) <|> (makeParser m b) +makeParser m (See i) = makeParser m (m!i) + + +-- Parse the input + +type Parser = Parsec Void Text + +sc :: Parser () +sc = L.space (skipSome (char ' ')) CA.empty CA.empty + +lexeme = L.lexeme sc +integer = lexeme L.decimal +symb = L.symbol sc +colonP = symb ":" +pipeP = symb "|" +quoteP = symb "\"" + + +rulesP = M.fromList <$> ruleP `sepEndBy` newline +ruleP = (,) <$> integer <* colonP <*> ruleBodyP +ruleBodyP = choice [(try letterRuleP), (try orRuleP), (try thenRuleP), (try seeRuleP)] + +letterRuleP = Letter <$> between quoteP quoteP letterChar +orRuleP = Or <$> thenRuleP <* pipeP <*> thenRuleP +thenRuleP = Then <$> some seeRuleP +seeRuleP = See <$> integer + + +inputP = (,) <$> rulesP <* (some newline) <*> messagesP + +messagesP = messageP `sepBy` newline +messageP = some letterChar + + +-- successfulParse :: Text -> (Integer, [Maybe Integer]) +successfulParse input = + case parse inputP "input" input of + Left _err -> (M.empty, []) -- TIO.putStr $ T.pack $ parseErrorPretty err + Right expressions -> expressions diff --git a/data/advent19.txt b/data/advent19.txt new file mode 100644 index 0000000..273c118 --- /dev/null +++ b/data/advent19.txt @@ -0,0 +1,626 @@ +25: 53 116 +122: 116 92 | 53 53 +100: 53 73 | 116 125 +111: 67 116 | 91 53 +71: 116 58 | 53 78 +55: 116 54 | 53 21 +123: 53 97 | 116 108 +104: 56 116 | 125 53 +19: 125 53 +56: 116 116 | 116 53 +60: 116 121 | 53 59 +75: 53 20 | 116 124 +6: 53 131 | 116 33 +62: 53 53 | 116 116 +101: 116 127 | 53 26 +128: 116 125 | 53 93 +34: 53 28 | 116 125 +65: 63 116 | 135 53 +50: 32 53 | 76 116 +2: 53 10 | 116 132 +133: 28 53 | 131 116 +85: 53 131 +125: 116 53 +118: 87 116 | 3 53 +135: 73 53 | 125 116 +28: 53 53 +110: 116 122 | 53 56 +91: 5 53 | 74 116 +73: 92 116 | 53 53 +80: 15 116 | 109 53 +124: 128 116 | 17 53 +87: 92 53 | 53 116 +43: 116 27 | 53 37 +66: 46 53 | 93 116 +106: 116 77 | 53 83 +137: 72 116 | 104 53 +93: 116 116 | 53 116 +129: 92 103 +12: 116 56 | 53 131 +45: 53 132 | 116 12 +102: 65 116 | 2 53 +24: 116 101 | 53 95 +14: 116 84 | 53 29 +57: 93 116 | 56 53 +70: 108 116 | 100 53 +51: 116 1 | 53 68 +26: 73 53 +15: 116 93 | 53 125 +42: 53 134 | 116 106 +79: 116 33 | 53 122 +5: 116 125 | 53 3 +74: 53 122 | 116 73 +18: 93 53 | 87 116 +20: 47 53 | 17 116 +114: 116 85 | 53 118 +37: 53 73 | 116 87 +47: 116 73 | 53 125 +107: 116 3 | 53 46 +69: 53 25 | 116 125 +32: 53 28 | 116 93 +76: 3 53 | 125 116 +38: 92 33 +119: 116 39 | 53 80 +8: 42 +21: 125 53 | 125 116 +58: 75 116 | 119 53 +64: 116 44 | 53 113 +68: 90 53 | 45 116 +1: 23 116 | 60 53 +53: "a" +81: 73 53 | 33 116 +86: 116 129 | 53 35 +90: 110 116 | 13 53 +82: 53 93 | 116 25 +95: 99 116 | 66 53 +27: 116 56 | 53 3 +120: 116 51 | 53 40 +126: 116 96 | 53 52 +116: "b" +84: 116 123 | 53 49 +134: 116 61 | 53 14 +78: 116 102 | 53 86 +96: 130 53 | 98 116 +10: 87 116 | 33 53 +88: 53 116 | 116 92 +40: 126 53 | 24 116 +127: 56 116 +59: 87 53 | 3 116 +11: 42 31 +41: 116 137 | 53 16 +44: 116 22 | 53 79 +109: 88 53 | 87 116 +49: 136 116 | 94 53 +113: 107 116 | 81 53 +77: 116 64 | 53 36 +3: 53 116 | 53 53 +9: 133 53 | 112 116 +98: 92 93 +117: 3 92 +39: 53 19 | 116 21 +16: 6 116 | 117 53 +132: 131 116 | 125 53 +63: 116 122 | 53 33 +22: 131 116 | 56 53 +89: 116 125 | 53 131 +115: 55 53 | 50 116 +99: 116 33 | 53 93 +92: 116 | 53 +121: 53 73 | 116 56 +13: 73 92 +103: 53 3 | 116 62 +83: 111 116 | 41 53 +61: 105 116 | 115 53 +130: 56 92 +136: 33 116 | 125 53 +30: 53 76 | 116 7 +94: 92 87 +52: 97 116 | 18 53 +7: 116 28 | 53 46 +97: 25 53 | 33 116 +35: 89 116 | 82 53 +72: 53 131 | 116 87 +48: 34 116 | 38 53 +54: 116 46 | 53 131 +131: 116 116 +23: 116 4 | 53 57 +31: 116 71 | 53 120 +29: 116 30 | 53 114 +108: 116 25 | 53 46 +33: 92 92 +4: 131 116 | 3 53 +36: 70 116 | 9 53 +67: 69 116 | 117 53 +0: 8 11 +105: 48 116 | 43 53 +46: 116 53 | 53 116 +17: 93 116 | 122 53 +112: 122 53 | 3 116 + +babbbbabaabaaabbbbbaaabbbbababba +ababaaaaabbbabbbbbabbbba +aabbaabaabbababaababbaba +bbbbabaaabaaabbbbbbbbaab +babbbabababaabbaaaabbbba +bbaabbababbaaabaaaababbbabaaaaaaaaaaababbaabbbbaaaaaaabaabababbbbabbbaababbbaabbbbababab +babbabbabbaababbbbbbbaab +baababababbaababaaabaaab +aababaababbaaaabbbababbbbbbbbbaabbbbabbbbbabbababbababaabaabaaaabbabaaaaabbaaaaa +baabbbbaaabbabbbababbbba +baabbabaaaaababbaababbbbaababaaabbbbbaaabababaab +babbabbabaabbabbaabbabaa +baaabbbbabbaaabbaaaaaabbbbabaaba +abababbaaabaabbbabbbaaaa +ababababbbbaaaababaabaaa +baaababbbbbabababbbaaabaaaabaababaaabbbbaaabbbbaabbaabbbabbbaaab +babaaabaabbabaababbabaaaabbbaaaa +ababaaabaabaabaabbbbababbbaabababaababaaabaabbbb +abbaaaabaabababaabaabbaa +baaaaaabaaaaababbababaaa +aabaaabbababaabbbaaabbbbaabbbaaa +baaabbbaaaaaaaaaaabbbbba +abbbbbabbbbabaabaabbbbabbbaabaabaabbbbbb +baabbbababababbabbaaaaaaabbbaabbbababbbaababaaaaaabbbbaa +bbbbbbbbabababaabaaabbbabbaaabbbaaaaaabaabbaabbabbabbbba +abaabbabaabaaaaabaabaaaa +aabababbababaaaaabbbbbaa +bbbabbaaabaaaababababbbabbbaabab +aabababbaabbbababaabaaab +aabaaababaabbabaaabaaaab +abbbabaabbaabbabaaabbbba +baaabbbbaababbabbbbabbaabaabbbbbabbbbabbbabbaaba +bbaaababaabaaabbabbbbbabbabaaabbbbaabbbbaabbbaaabbabbabb +baabaabaaababbbbbbaabbaa +bbaaabbbbababbabaaaababa +bbabbbbabaaaaabbbaaaaababbbbbaaabaababbbbabbabaabaabbabaabbababbaaaaaaabbbabaaabbbbbbabb +abaabbbababaaaabaabbbbbbbbabbbab +ababaaaaabababbabbbaababbaaabbaaabbaaaba +bbabbaabababbabbbaaaaaabaaabaabb +baabaaaaababbbbabbabbabbbababbaa +aaaaaaaabaaabaabababaaba +baabbababaaabaaaaabaabaaaababbbbaaabbbbb +abaaaabaabbababaababbbab +bbaaabababbababbababbbbb +baababbaaaabababbaaaaaabbaaaabbb +bbbbbbbaabababbabbabbbba +bbaaaaaaaabaabbbabaabbaa +abbabababbaaaaababbbabbbbbaaaaaaababaaaababaaaba +abaababbaabaaaaaaabaaaab +abababaabbaaabbaabababbaaabbabaa +babbabbbbbbbbbbabbaabbaa +bbabbbaaaabaaababbaaababbaaabaabaabbbaababbaabaaaabbbaaaabbaabbbaabbbbba +abbbaabbababaaabbababbbaabbbbababababaaa +bbaaabbabbbaabaaabbbabaaaaababbbbaababbb +baabaaaabbaaabbaaabbaababbbbbbababbbabbbbbbabbba +abaabbbaabaababaaaabbabb +bbbbabaaaabaabbbbbbbbaab +bbaaaaabababbabbaababbab +babbaabaabbbbaaaaabbbbbb +baaabaabbbbbaaaaabbbaaab +aaabbaabbabbabbbbabbbbba +aabbababaabababaaabbabbbbbbbbbbaaaabbaaaababbabbabaaabaabbababaabbbbbabbbabbbbabaabaabaabaababba +ababaabbaabbbabababbabab +bbbabbbabaaabbbaaaabbbab +aabababbaabaabaaabaaabbbaabbbaaa +aaaaaabaabbabbaabbbbaaaaaabbaabbaaabaaaaabbbbaabaaaabbbaababbbbbababbaaa +ababaabbabababbabababbbaaabababaaabbbbaaaabbbabb +babbabbaabbabbbaababaaba +abbbbaaabbbbbbbabbababbbbaabbaab +babbaabaabbbbabbaaaaaaabaabbabba +bbaaababbaabbabbbbbbabbbbabbabaabbabaaaa +aaabaabaaabbababbababaab +bbaaabbbababaabbaabaaababaabbbbbbbabbaaa +abbabbbabaaabbbbbabbbabaaabbaabababbbbbaabbbaabababaabba +aaaaaaaaabbabbaabbabbbaaaabababbbaaabaababaabbaabbababab +aabbbabababbabaaaaabababbabbbbba +abbababbbbbbabbaaabbbbbb +bbbbbbbaabaaaaababbaabbb +aabababbabaaabbaababbaaabbbbababbbabbabbbaaababbabbbbbabaaabaabaabbabaabaaabbaaa +abbbbbabbbbbabaaabaabaab +abbabbbabbbbabababbbbbba +abababbabaaaaaabbbabaaaa +aaaaababbbbbaabbaaabaabaabaaabababbabbabbbbaabbb +baabbbbabbbaaaaababaaabb +bbaaaababbaaaabaababaaaaaabbbaabbbbabaaa +babbbbbbbabbbaaabababaabbabbbaabbbaaabaa +aabaaabbaabbaabbbababaab +baaaabbbbbabbbababbaababbabaaabaabababbaabaabbabbaaaaabaabbaaabb +abababbabaabbbbaaaaababa +aabbbbabbbbbaabaaaabbaabbbabaabababbbbaabbaabbabbaabbaaa +aaabaabaaabbababbabbbababaabbabb +bbbaaababbbbbbbbbbbababbabbbaaab +bababbaaaaaabbbbbabaaaab +bbaaaabaaaaaaabababbbabaaaaabaaa +aabbabbbbbaaababbbababaa +abbaaaababbbbbabaaaaabbb +bbaaaaaabbbaabababaabaab +ababaabbabaababbbbabbaabbbbbbbbbaaabbababbabbabbabbaabaa +bbaabbbaabababbaaaababbb +bbbbabbaaabaabaababaaaaa +bbaabbababbbbaabbababbbabbbbababbbbaaabbbaaaababaababbbababbaabb +bbaaaababababbabbabbbbaaabbbaaab +babaababaaabbaabbbababaa +ababababababbaabbabababa +abbabbbbaaaaaabbabbbabaababaabbaabbbababbbbaabaaaaaaaaabbbaabbba +bbbaaabaaaaaaaaaababbabbbbaabaab +abbbaabbabbbbaaaaaaabaab +abbbbbbbaaabbbbaaaababbaaaaabbabbababaabbbaabbabaabababa +aababbaaabaababbababaabb +babbaaabaabbabbbbbabbaaaaaaabaab +aabababaabbbbabbaaaaabaaaabaabababbaaaba +baabbabbbbaaabababaabbbb +abbaaabbbbbabaabbbbbaabbabbbbaabbaabaaabaabaaaab +bbaabbbabbbbbabbbababbbb +babaababbbbababaabaaaabbbabbabaabaabababaabababb +bbababbabbaabbbbbbbbabbbabbaabaaabbbaaaabbaabaababaaaaaa +babbbbabbbbbbbaaababbbba +abbbbababbbaaaaaaaabbbab +baaaaaabaabbbaabbabbbabbabbaaabaababbaaaabbaaababbaaaaaabaaaaaabbaababababaaabbbabaabaaa +aabaabbbabbbbaaaaababbaaababaabbabbbabbababaabba +aabababbbbbbabbaabbbbbbb +baabababbbaaaaababbbbaabbabbabbbaaababbaaaabaaab +baaabbbababbaabaabbabaaa +abaababbabbbbaabaababbbbbbbaaaab +aababaababbbabbbababbaaa +baaabbbbbbbbabbabbbbbaab +bbabbaabaaabbbaaaabbbaaa +bbabaabaababbaababbbabbbabaabbabbaabbaab +bbbbbbbaaabbaabaababaaba +aababababaaabbbaababbbaa +babbbbbabbbababbaaababaaaababbaaaaabbbabaaababaaabbbbbbbbbbaaaabbaaabbaabaaaababbbaaaaab +aababbaaabaaaababbbbabaaabbbbabaabbbbabbbabbbabb +bbbaabaaaabbbbabaababbaabbabaababbaabaaaababbbba +abaabbbaabbbaaabbabaaaab +bbbbbbbbaaabbabababaaabbbbaaaabbbabaaabb +baaaaabbbaaaaabbabbaaaaa +ababaaaaaabbbaababbaabba +bbaaaaaaaaabbababaaaaaaaaabaaaab +bbbabababbbbabbaabaaaaaa +bbaaaababaaabbbabbbabaabaabaabab +bbbabbbaaabbbbaaabbaabbaabaabbbaaabbbbba +babbabbabbbbbbbaaababababaaabaabbaaaaaabaaaaabaaabbbbbbaaabbbbbabbaabbaa +ababbabbaabbaabbbaaaaabbaababaaaabbabbab +abbabbbbbaabbbbbbabaabbb +abbbaabbaaaaababbbaabbabaababaabaababaababbbbbbbbbaabaab +baaaaaaabbbabbbaaaabbbba +bbaaabbbababbbabbaaaabaabaabbabbbbbbbbbbabbabbabbababababbaababbbbabbaba +bbbbababbaabbababbabbbab +baaabaabaababbbbbbabbbbb +abbbbababbbababbbbabbababbabaabbbbaaaabb +bbaaaaaaabbbabbbabbbbbaa +bbabaabaabbabbaaababbbaa +aabbbaababaabbabbabaabba +baaabbbaaaabaababbaaaabb +babbbbaabbbbaabaabbbaaaa +abbaabbbaababbabbaaabbababbbabab +aaabaaaaaabbabababbbbabbbbabbbbbaaabaaab +babbbaababbaaaaaaabaaababbaaabbb +bbbbaababbaaaaaabbbbbaab +bbaaaaaaabbbbababaabaaab +babaababbabbabbbaabababaabaabaab +abbbabbbabbabbaaaababaababbabaab +bbbbaaaaaabbaababbabaaabbbabaaaabbabbabb +aaabbaabbaaabbbbbbbbbaaa +abbbbaabaabbbabaabaaabababaabbba +babbabbabaaababbbbaaabbababaabaabaabbaababaabaaa +babbabbaaabaabbaaaaaabaaabbbaabaabbaaaaabbbaaabaaababbaabbbbaabaabbbbaba +aabaaabbabbaaabbbabbbabb +bbaaaaaabaabbbbaabbbaaab +bbbbaaaabbbaaabaabbbbabbbababaaa +abbbabaabbabbaabbabbbbba +aaaaaaabaababbbbababbbab +abbbababbbabbbbabbbbbabbbabaaababbababaabbbaaaab +babaaabaaabbbaaaaabbbbbbabbaaaaabaabaabbabbbababaababaaaaaabbaaababbbabbbaaababb +abbababbbaaaaaabbabaaabb +bbabbababbabbaabbababbbb +babbbbaaaabbaaababbbbaaaaabbababaaabbaabbbbbaaab +aabbaabbabaaaabbaabababaabaaaabaaaabaaaaaaabaabababababa +abababbaaaabaabaaaababbb +bababbabaaabbbaaababbbbb +baaaababbabbbabababaabba +abbbbabaaaaababbbbbaabbabaaaabbaaaababba +aabbababbbaababbabaababa +babbaaabbbaabaabbbaaabbabaaaaabaabbabbaabaabbaabbbbbababbbbabbbb +aaabbbaaabbabbabaabaaaaaaabaaaaa +aababbaaaababbbbabbbaaaa +baaabbbabababbbaaabaabba +bbabbaabbbbabaaabaaabbbbbbbaabababbaabbbbabbabbaaabaaabb +baabaabaababababaaabaabb +abbababbbbbbababbbaabaab +abababbabababbabbaaaaaab +bababbbaaabaaabababababb +aabbabbbbaaababbbbabbaaa +abbaaaababbabababbaabbbabbaabaab +bbbabbbaababaaaabbbaaabababbaaaaababbabaaabbabaaaaaaabba +baabaabaababaaabbbbbababbabbabbabababbbb +bbbbbaaabbaababaabbbbbaaababaaba +bbaaaabaabbaaaabbbababbbbbbababaabbabaababbbaaaaabaabaaa +bbabaaaaababbbbbbababbbbbbbababbbabbbbab +ababababbaaabaabbbbaababaababababaabbbaaaaababbbbabaaabb +babbbabaaabbabbbaababbba +aaaaaaaababbbababbaababbabbbaabb +aababababbaaaaaabaaaaaba +aaaaaaabbaaaabaaaababaabbbabbabb +bbabbabbbbbbabbaabbbaabaababbbaabaaabababaabbbbbbabbbbbb +bbbaabbaabaaaabaabaaabaa +babaabbabbabbaaabaabaaaaabaabaaa +aababababbbbaabaabbbbbaa +baabababbaabaabbaaaaaabbaaaaabababbabbaaabbabbaaaaaaabbb +bbabaabaababbabbbabbaabb +abaaaababbbbbbbabbabaaaa +bababbabbbbbabaababbbbbb +aabbabbbbbbbabababbabaab +abbababababbabaaaabbbaaa +aabababbabbaabbbbbbaaaabbbbbaaaa +abbbabbbaaaaaaabbaabbbbb +bbbbbbbaaabaaababbbbababbabaaabaabababbb +aaaababbaaaaaabaaabaabba +abaaaabbbbbbababbbababbbabaabaaababaabaa +bbabbbaaababbabbbbbaaaab +aababaaabaabbbbbbbbabbbb +aabbbaababbbbbabbababaaa +aabbaaababbaababbbbbababbbbbababbbbbaabbbaabbbbbabaabbaabbbabbbb +baaabbbbbbbaaabaabaabaab +baaabbaaaababaabbabaaaaa +aaabababaababbabaababababbbbbbaabbabbbaabaabaabbaaabaabaababbbbb +aabaaabbbaaabaaabbbabaab +bbbaabbaababbabababbbbbababbbabbbbaabbbbbbabaaaaaaaabbab +aabbaaabbbaabbabaaababbb +bbbbabaabbbabbbaaabaaaab +aabbaabbbabaababbaababaa +aaaaaaaababbbbababaaaabaaabababbabaaababababababaaabbabbababbbbbaaaabbab +babbbbabbababbbabaabbaaa +aabbaaabbbaababbbbbbabaaababaabbbabaaabaaabbbabbababbaba +bbbaaaaabbaaabababbabbbb +bbbbabbababbaaaabbbabbbaabbaabbbbbaabaaa +aaaababbabbaababbabababb +bababbabaaabaaabbaabbbaabaaababa +babaababbaaaaaabababbaabbababbaaaaababbb +aabbabababaaabbababaaaba +bbbaaabbabaababbbababbaa +abbabbbaabbaababbabaabba +baaababbaaaaaabaaabbbaaa +baaaaaabaabababbaaabbaabababbaababbaaabbaababbba +abbbbabbbbabbabaaaaaaabbbabbaabb +abbbbaabaaabaababbbababaaabbbaabbabbabbabbabaaababbabbbbbaababaa +bbbabababaabbaaabbaaababbabaaaaabbaaaaaa +abbbbaababbbabbbaabaaaab +bbababaaaaaabababaaabbbbbbabbaaababbabbabaaaababaaaabababbabaabaabaabaab +bbbabbaabbbbabababaaabaa +abaaabbabaaaabaaaaabbabaababbaba +babbaabaabbabbaabaaaaaba +aababababbabbbaaabbaabba +bbbabaabbaaabbbabbabbaaa +bbbababaaabbabababababbb +aabbbbababaaaabbbaabbabbbaabbaab +bbaaaababababaababbbaaab +abbbaabbaaaaabbaaabaaaabbabaaabaaaaabbabbaababaa +babbabaabababbabbbbbabbbaabbbaba +bbbbbbbaabbbaabbbbbabbab +abaabbabbaabaababaabababbbbaaababababbaaaabbbabbabbaabbb +abababbabbaaaaabaabbabba +abbabaaababbababaabaababbabaaaaabbaaabaabbabbaaa +babbabaabbababbbbbabbaaa +aabaaabaababaaaaaaaabbba +bbaabbbabbbbaaaabaabababaabaaabaaabbabba +abaaaabaaabaaabbabbabbbb +abaaaaabaaaaaaaabaaaaaba +aaabbabababbbbaaaaaabbbb +bbbbaabbabaaabababaaabbababbbabaababbaabbabaabba +bbbabbbaaabbbababbaaabbbbbbabbabbbbbbabbabbbbbbb +abaaaababaaabaabababaaba +baaabaaabbabbbaaaabbaababaaaabba +bbbbabbbbbaabbbabaabbbbb +ababbaababbbbabaababaaaaaabbaaabaaaaabbb +baaaababaaaaababbababbaa +aabaababbabbaabbbaabbababaabbaabaaabaaabbabaabbababaaabbabbbaaab +abbabbaaaaaaabbabaaaabbaababbaaa +bbbbaabaabbbbabbaabbabbbaababbbbbabaaaba +bbbaaabbbaaabbbaaaababbb +baaabbbabbbaaaaabbbaaabaaabababbabaaabbababbabab +aabaaabbabaaaaababbbaaab +bbaaaaabaabbabababbbbaaababbababaabaabba +bbaaababbbbbaaaabababbbaaaabbabb +bbababbbbbabbababbbbabaabbbbaaaaaabbbaabbabbabbbbbbabbbb +bababbbaaaabbaabaaaabbba +ababbaababaabbabaaaaabba +aaaaaabaaaabbbaaababbaba +babbbbaaabbbabbbbbbabbab +bbbbbbbabbbbabbbabbaaaba +baaabaaaaabbaabbabaaababaaababbb +baabaabababbabbbaabbbabb +bbaaaaaaabbbbabbabaabbabbabbaaabaaaababaaaaaabba +baaaaaaaaaaaaaaaaaaababa +abbaababaabbbbabaaababba +bbbbababaabbbaabaababbaaaaabaaab +aababaabaabaababbbbbaaaaababaaaaabaababbbabbbbaaabaaaaabababbbab +babaababbbaabbabbbaabbaa +baabbababaaaabaabababbaa +bbaaabbabbaaabbbbbabbabb +baabbbbabbaaaabaaaabbbba +bbababbbbaabbbbaaaaabaab +aaabababaaaaaabbabaaaabababbbbbb +bbbbbbababaaabbbbaaaaaaabbaabbaabbbbbaabaabaaabbaaabbbbabbaabaabbbbaaabbabbbaabb +aabbbaaababbabbbbaabbbbababaaaaababaaaaaaaababbbaabababb +bbabbaabbabbaaaaaaaaabba +abbabbaabbaabbabaaabaabaabbaaaaaaabaaaabbbaabaabaabbabaa +abaababbaabbaaabaaabaaaabbaaaabaabaaababaababaaabbbabbababaaabaaabbaabbabbaaabaa +bbaaaaabbbbbabaaaababbaababbabbbaaabbabababbababbabbbbba +babbbbaaaababbaaaabaabbbbaabbbaababbbbbb +aaaababbbbbbbbaabbbabbbb +bbaaababbbaaabbaaabbbabb +abbaaabbbabbaabababaabbb +aabababbabbbbbababbbaabbaaabaaaaabbabbaababaabaabaaaaabaaababbbaababbbab +babbaaaaaabbbbabbbbbbbaabaabbbabbbbbaaab +babbabaaabbaaabbbabaaaaa +aaaaaaabababababbaababbb +ababaabbbabbaaaaabbbbbbb +aabbaaabaabbbabaaaababba +baabbabaaabaabaaabbaaaaa +abaaaabaaabbbaabbabaabaa +bbaaabbbbaaabbbaababbbbb +baaababbbbbaababbbabbaaa +ababbbbbabbababbaaabaabbaabbbaaaaabbaaabbbbbababbaaaaabaaabbbbaaaabbabaaaababbbbabaabaaa +bbbbabbbababababbaabbaab +ababbaabbabbbbaababbabbabaaabbaabaaabaaabaaaabbbababaababaababbb +baaaababbabbbbabbaabbaab +bbaabbbaabaaabbbbababbaa +bbabbbbaabbaaabaabbaabbaabaabbbb +bbbaaaaabbaababbbbaabbababaababbabbaaaba +aabababbaaabbbaaababaabbabbbbbba +abaaaabaaaabaaaabaaaababaabbbaababaabbabaaaaabbaaababbbabaabbaaababaaaab +baaabbbbbababababaaaababbbbaabaaaabaaabbbabbaabbabbbabaabbaaaaba +abbbbabbbbbbabbbbabbbbbb +bbbbabbbabbaaabbbbabaabaababaababbaaaabb +ababaaaaaababaabbaabbabaabbbabaaababbaaaabbbaaaa +bbbbbbbbbbbbaabbaaaabaab +aababaabbabbabaaaaaabaab +ababaaababbabbbabbaabaaa +bbbababbabbbbbabaaaaabaa +abbbaabbbabbbbabaaabbaaa +abbaaaabbbaaaaabaabaabba +aaabbabaaabaabbbaaabbabb +ababaaababbbbaaababaababbbbaabbbbaabaaaa +baabababbaababbabaabbaab +bbaaabbbaaabaabaababbaba +baaaaabbbbbaabaabaaabaaabaabbbbb +aabbbababaaaaaabababbaaa +baaaababbaaababbaaaaabaa +aabababaabaabbababababbb +bbaaaaaabaababbabbbbabaabbbbbbaaaabbaaabbababaab +bbbbababaabababaaabbbaaa +baaabaababbabbbaaababbaa +babaaaaaabbaababaaabbbbaabababbababaaaababaabaabbbbaabbbaaaaababaabaabbabbbbbbbbabababbaabaaaaab +bbbaababbaabbbbabaaaabaaabbbbbba +aababaabaababaaabbbaaababbbabaabbbaabaab +bbbbababaaabaaaabbbaaaab +bbbbbbbbabbbabbbaababaabbbabbabbbbaabaab +baaabaaabaaabbbbaabaaabbaaabaabaaabbbbaa +bbbabaabbaaaababaaabaaab +ababababbbbbabbbaaabababbaabbaab +abbababbaababaaaaababbaa +ababababaabbaabbbababaaa +ababbabbaaaaaabbababbbab +aaabbabbbaabababaabbaabbaaabaabbbabbaabb +bbbbababaabaaaaaabaaaaaa +bbaababaababbaabaaaabaaaaabbabaabaaaaaaaaabbaaba +bbababbbbaaaaabbaaababba +bbbbbbaaabbaababbaaabbaaabbbbabababbbbba +aabbbaabbbbababbbaaababa +aabaabaabaaabaababbabbbb +bbbbabaabaabbbbababaabab +abbbaaaaaabbbbbababbababbaaaabba +aaaaaaabaaabaababbbaaaaaaabbbbbbbbaabaaaabbaaaba +baaabbabbaaabaababbaabababbabbbabaabababaaababbbbbabbaabaabbbabb +aaaaababbaaabbaabbaaaabb +bbbabbbabaabbabaabbbabbaababaaaabbbbabbabbaabbaaaabaaabbabbbbaab +baabaabaabbbbbababaaaabbbbbabaabbbbaaaabbbbbbaabbaabbbbb +bbaaaaaabbabbaabbaabaaba +abbababbbabbbbabbaaaaaabaaaaaabaaaaaabbb +abaababbaabbbaabbabaabbb +baabababbaabababbbbaaaaabbababbbbaaaabbb +baabaabaabaabbbbbaabababbabababbbbabbbaabaaaaabaaaaabaaababbbbababbbaaabbbabaaba +abbbbaaaaaabbbaabaaaabaaaaaabbaa +baababababbaaabbbabbaabb +aaaaaabaabababbabbabbbbb +aaabbabaaabbaabbbbabaaab +abbbaabbbbbbabaaaaaabaaa +aabbabbbabaaaabbaabbbaaa +aabbababbaaabbbbabbbbbabaabaabab +bbbaababaabbbbbabbabaaaabaaaabba +bbbbababaabababaaabbabaa +ababaabbbbbbbbbaaaaabbbb +aaabababbabbaaaaababbbbb +bbbbabbabbbbbbaaaabaabbbbabbbbba +bbbababbaaababababbaababbbabbaabbabaaabaabbabaab +baaabbbaabababbaababbbaa +aaaaaababbbabbaaaabaaaaaabababababbaabaababaaaba +bbabbaabbbbbbbaabbbaaaab +babbaabaabbaaabbbbaabbbaabababbaaaabbbaabaababbbabbbaaaa +baabaabbbaaababababaaabbabbbbaaaaabaaaaababbabaaabbbbbbabaabaababbbbbaaabaaaaaaa +abbaababbbbabaabababbaba +bbaababbababababbbbbbaab +bbbbaababbaaaababaaabbaaabaabbbbbbbbbaaa +babbbaaabaababaababbbabbabbaabbabbaaaabaaababaababaabaaaabbaaaba +bbababbbabaaaaabbbbbbabb +babbabbbababaaaababbbabaaaabbababbabbbbbabababbb +abbbaabbbbaaabbbaaabbabaaaaaaababaabaabbaabbbaabababbbabbbbbbbabababbbbbaaababaa +aaaaabbabbbaaaabbaaababbbaaaababaaabbabbbabbabbaabbabaabaabbaaaaabbaabaababaabaababbabaa +baaababaababbbabbaaaabbaababbaaababababababbaabbbbbabbbababbababaaabbbbaababbaba +babbabbaabbbabaaabbaaaaa +bbbaaabaaaabababbaaabbbabababbbb +bababbbaababaaaabaabaabaaabbabbbbbabababbabbbaab +aababaaaabaabbabbabaabaa +aababbaaaaabbaabaaaababa +babbbbaababbbbaaaaabbbaabbaababbbbabaaabbaaabbabababbbaa +abaaaababababbabbababbbabbabbaabbbaaabaa +aabbababaabbaababaaaaabbbabbaaaabababbabbbbabbaaaaabbbbb +aabaaababbaaaabbaabbabaaaaababbabababbbb +abbbbbaabbbabaaaaaaaabbaaabbbaaa +bbbbabaaaabbbababbbabbbb +bbbababaababaaabaabbabaa +abaababbbaaababbbabbbbaaabaabaab +aaabbaababbbbaaaaabbbbba +aabaaaabababbaaaaaabaabbaaaabbaa +baaabbabbbabaaabaaaabaabababbbbb +abaaaaabbbaaaaaabaababaa +bababbabbbbabbaaaaabbbab +abaaababbaabbabaaabaaabbabbbbabaaaaababaaabaaaabbbbabbbbbaabbaaa +aabababbaaabaaaaabbaabba +ababaaabbabbabaabbbaaaaaaaaaaabbaaabaaab +aabaaababbbababaaabaabaabbbbaaaaaabbaaaa +bababaaabbababbabbbabaaa +abaaabbabaaabaabbababbaa +abbbabaabbaabbbababbbbbb +aabbbbabbaaabaaabbaaabaa +bbbbabbaabbbbbbaaaababaa +abbbbabaaabababbaaabbbbb +abaaabbaabaaabbbbbaabbbb +aabaaabaaaaaaabaaaaabbba +abbabbbaababbabbaaaabbbb +babbaabaaaaaaaabbaabbbbabaaaababaabbaaaa +ababbabbabaaaabbbbbababbaabbababbbbababb +abbbabbbbabbbbabbbaabaab +baaababbbbaaabbabbbaaaab +abbbbaabbbbbaabbabaaababbaabaaab +bbbbababbbaaabaaabbababbbabbbbababaababaaaabaaaabaaaabaaabbbaabababbbabbbaaaaaababbaabbb +bbbbabaabbabaabbabbbbbabbabaaabbaabbaaab +baabbabaaabbaababbbbbaab +bbabaaabaabaaaababbbbbaabaaabbaabababbaaaabbaaabaaaababbaaaababaaaaaaaaaababbbbb +abaaaabaabbbabbbaaaaababbaaaaaab +abbbabbbaababbbbabaaaababbaaabbaabbbaabbbbabaaaa +bbaaabbabbaababbbbbabbaabaabbbbabbbaababababbbaa +bbaaaaaababbbbbbbaababaaababbaaabaabaaabbbababbabbabbbbababbaaab +bbaababbbbaaabbbababbaba +bbbaaabbbbbbabaabbabbaaa +bbbababaaababbbbbaababaa +baaaababaababaaaabbbbbbb +aabbbbabaaaababbbabaabba +baaabaabbbbabbbabbaaabbaabbbaabbbbaabaab +aabbbaabbaaaaaaabaaaaabbbbbaabab +baaaabaaaabbaabaabaaababaaaabaab +aaaaaabaaababbaabaaaaaba +aaabaaaaaabbbbabbaabbaaa +abaababbbbbabbbaaaaaaaaaaabaaabbbaabbbabaaabaabb +bbbaabbaabbababaabbabaaa +bbbababbabbabbbabbaaabbabababbaaababbbbb +abaabbbaababbbaaabbabaab +aababaabaaabbababababbbaaaabbabababbbbaaaaaabbbababbabab +bbabbbaaaaaaababbbaaaabababbabaaabbabbbbaaabbbbb +aaaaaabbbbbaaabbbbaabaaaaabbabaa +bbbaabbababbaabaaabbbbbb +abbbabaaaaaaababaababbab +bbabaabaaabbaabbaabbabba +baaaabaaaababaabbbabbbab +bbaabbbaaaabbaaaaaaaabaaaaaabbaa +aabaabaaaababaabbbbaabaabbbaaabbbbabbabb +aaabaabaabbbabbbaabbbbbb +babbaaaaabaaabbbbbaaababaaaaaabaababbbababbabbbbaaabbbba +abbababbbaabbabbabaabbabaaaaabbb +ababaaabbaaaaabbabbbabaabbaabbbaabaaaaabbaabaabbabbbaaaa +babbaaaabaabababbaaaabbb +aaabbbaaaabbbabababaabaa +bbbaaabaababbaabababaaba +aaababbaaabbaababbbbabbabbbabbab +abababbaaababaababbaabba +bbaaabbabbbbababaaaabaab \ No newline at end of file diff --git a/data/advent19a.txt b/data/advent19a.txt new file mode 100644 index 0000000..a76d890 --- /dev/null +++ b/data/advent19a.txt @@ -0,0 +1,12 @@ +0: 4 1 5 +1: 2 3 | 3 2 +2: 4 4 | 5 5 +3: 4 5 | 5 4 +4: "a" +5: "b" + +ababbb +bababa +abbbab +aaabbb +aaaabbb \ No newline at end of file diff --git a/data/advent19b.txt b/data/advent19b.txt new file mode 100644 index 0000000..0962991 --- /dev/null +++ b/data/advent19b.txt @@ -0,0 +1,47 @@ +42: 9 14 | 10 1 +9: 14 27 | 1 26 +10: 23 14 | 28 1 +1: "a" +11: 42 31 +5: 1 14 | 15 1 +19: 14 1 | 14 14 +12: 24 14 | 19 1 +16: 15 1 | 14 14 +31: 14 17 | 1 13 +6: 14 14 | 1 14 +2: 1 24 | 14 4 +0: 8 11 +13: 14 3 | 1 12 +15: 1 | 14 +17: 14 2 | 1 7 +23: 25 1 | 22 14 +28: 16 1 +4: 1 1 +20: 14 14 | 1 15 +3: 5 14 | 16 1 +27: 1 6 | 14 18 +14: "b" +21: 14 1 | 1 14 +25: 1 1 | 1 14 +22: 14 14 +8: 42 +26: 14 22 | 1 20 +18: 15 15 +7: 14 5 | 1 21 +24: 14 1 + +abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa +bbabbbbaabaabba +babbbbaabbbbbabbbbbbaabaaabaaa +aaabbbbbbaaaabaababaabababbabaaabbababababaaa +bbbbbbbaaaabbbbaaabbabaaa +bbbababbbbaaaaaaaabbababaaababaabab +ababaaaaaabaaab +ababaaaaabbbaba +baabbaaaabbaaaababbaababb +abbbbabbbbaaaababbbbbbaaaababb +aaaaabbaabaaaaababaa +aaaabbaaaabbaaa +aaaabbaabbaaaaaaabbbabbbaaabbaabaaa +babaaabbbaaabaababbaabababaaab +aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba \ No newline at end of file diff --git a/data/advent19tiny.txt b/data/advent19tiny.txt new file mode 100644 index 0000000..e5c4bc1 --- /dev/null +++ b/data/advent19tiny.txt @@ -0,0 +1,11 @@ +0: 8 11 +8: 42 | 42 8 +42: "a" +11: 42 31 | 42 11 31 +31: "b" + +ab +aabb +aaa +b +aaab \ No newline at end of file diff --git a/problems/day19.html b/problems/day19.html new file mode 100644 index 0000000..936d811 --- /dev/null +++ b/problems/day19.html @@ -0,0 +1,233 @@ + + + + +Day 19 - Advent of Code 2020 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 38*

 {'year':2020}

+ + + +
+ +

--- Day 19: Monster Messages ---

You land in an airport surrounded by dense forest. As you walk to your high-speed train, the Elves at the Mythical Information Bureau contact you again. They think their satellite has collected an image of a sea monster! Unfortunately, the connection to the satellite is having problems, and many of the messages sent back from the satellite have been corrupted.

+

They sent you a list of the rules valid messages should obey and a list of received messages they've collected so far (your puzzle input).

+

The rules for valid messages (the top part of your puzzle input) are numbered and build upon each other. For example:

+
0: 1 2
+1: "a"
+2: 1 3 | 3 1
+3: "b"
+
+

Some rules, like 3: "b", simply match a single character (in this case, b).

+

The remaining rules list the sub-rules that must be followed; for example, the rule 0: 1 2 means that to match rule 0, the text being checked must match rule 1, and the text after the part that matched rule 1 must then match rule 2.

+

Some of the rules have multiple lists of sub-rules separated by a pipe (|). This means that at least one list of sub-rules must match. (The ones that match might be different each time the rule is encountered.) For example, the rule 2: 1 3 | 3 1 means that to match rule 2, the text being checked must match rule 1 followed by rule 3 or it must match rule 3 followed by rule 1.

+

Fortunately, there are no loops in the rules, so the list of possible matches will be finite. Since rule 1 matches a and rule 3 matches b, rule 2 matches either ab or ba. Therefore, rule 0 matches aab or aba.

+

Here's a more interesting example:

+
0: 4 1 5
+1: 2 3 | 3 2
+2: 4 4 | 5 5
+3: 4 5 | 5 4
+4: "a"
+5: "b"
+
+

Here, because rule 4 matches a and rule 5 matches b, rule 2 matches two letters that are the same (aa or bb), and rule 3 matches two letters that are different (ab or ba).

+

Since rule 1 matches rules 2 and 3 once each in either order, it must match two pairs of letters, one pair with matching letters and one pair with different letters. This leaves eight possibilities: aaab, aaba, bbab, bbba, abaa, abbb, baaa, or babb.

+

Rule 0, therefore, matches a (rule 4), then any of the eight options from rule 1, then b (rule 5): aaaabb, aaabab, abbabb, abbbab, aabaab, aabbbb, abaaab, or ababbb.

+

The received messages (the bottom part of your puzzle input) need to be checked against the rules so you can determine which are valid and which are corrupted. Including the rules and the messages together, this might look like:

+
0: 4 1 5
+1: 2 3 | 3 2
+2: 4 4 | 5 5
+3: 4 5 | 5 4
+4: "a"
+5: "b"
+
+ababbb
+bababa
+abbbab
+aaabbb
+aaaabbb
+
+

Your goal is to determine the number of messages that completely match rule 0. In the above example, ababbb and abbbab match, but bababa, aaabbb, and aaaabbb do not, producing the answer 2. The whole message must match all of rule 0; there can't be extra unmatched characters in the message. (For example, aaaabbb might appear to match rule 0 above, but it has an extra unmatched b on the end.)

+

How many messages completely match rule 0?

+
+

Your puzzle answer was 235.

--- Part Two ---

As you look over the list of messages, you realize your matching rules aren't quite right. To fix them, completely replace rules 8: 42 and 11: 42 31 with the following:

+
8: 42 | 42 8
+11: 42 31 | 42 11 31
+
+

This small change has a big impact: now, the rules do contain loops, and the list of messages they could hypothetically match is infinite. You'll need to determine how these changes affect which messages are valid.

+

Fortunately, many of the rules are unaffected by this change; it might help to start by looking at which rules always match the same set of values and how those rules (especially rules 42 and 31) are used by the new versions of rules 8 and 11.

+

(Remember, you only need to handle the rules you have; building a solution that could handle any hypothetical combination of rules would be significantly more difficult.)

+

For example:

+
42: 9 14 | 10 1
+9: 14 27 | 1 26
+10: 23 14 | 28 1
+1: "a"
+11: 42 31
+5: 1 14 | 15 1
+19: 14 1 | 14 14
+12: 24 14 | 19 1
+16: 15 1 | 14 14
+31: 14 17 | 1 13
+6: 14 14 | 1 14
+2: 1 24 | 14 4
+0: 8 11
+13: 14 3 | 1 12
+15: 1 | 14
+17: 14 2 | 1 7
+23: 25 1 | 22 14
+28: 16 1
+4: 1 1
+20: 14 14 | 1 15
+3: 5 14 | 16 1
+27: 1 6 | 14 18
+14: "b"
+21: 14 1 | 1 14
+25: 1 1 | 1 14
+22: 14 14
+8: 42
+26: 14 22 | 1 20
+18: 15 15
+7: 14 5 | 1 21
+24: 14 1
+
+abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
+bbabbbbaabaabba
+babbbbaabbbbbabbbbbbaabaaabaaa
+aaabbbbbbaaaabaababaabababbabaaabbababababaaa
+bbbbbbbaaaabbbbaaabbabaaa
+bbbababbbbaaaaaaaabbababaaababaabab
+ababaaaaaabaaab
+ababaaaaabbbaba
+baabbaaaabbaaaababbaababb
+abbbbabbbbaaaababbbbbbaaaababb
+aaaaabbaabaaaaababaa
+aaaabbaaaabbaaa
+aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
+babaaabbbaaabaababbaabababaaab
+aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
+
+

Without updating rules 8 and 11, these rules only match three messages: bbabbbbaabaabba, ababaaaaaabaaab, and ababaaaaabbbaba.

+

However, after updating rules 8 and 11, a total of 12 messages match:

+
    +
  • bbabbbbaabaabba
  • +
  • babbbbaabbbbbabbbbbbaabaaabaaa
  • +
  • aaabbbbbbaaaabaababaabababbabaaabbababababaaa
  • +
  • bbbbbbbaaaabbbbaaabbabaaa
  • +
  • bbbababbbbaaaaaaaabbababaaababaabab
  • +
  • ababaaaaaabaaab
  • +
  • ababaaaaabbbaba
  • +
  • baabbaaaabbaaaababbaababb
  • +
  • abbbbabbbbaaaababbbbbbaaaababb
  • +
  • aaaaabbaabaaaaababaa
  • +
  • aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
  • +
  • aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
  • +
+

After updating rules 8 and 11, how many messages completely match rule 0?

+
+

Your puzzle answer was 379.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index ba78e95..f6be361 100644 --- a/stack.yaml +++ b/stack.yaml @@ -53,6 +53,7 @@ packages: - advent16 - advent17 - advent18 +- advent19 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From ffd4e09b86e7edb1694e9a88feaa67b4abef4890 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 29 Dec 2020 14:30:30 +0000 Subject: [PATCH 03/16] A bit of tidying, a bit of investigation --- advent19/src/advent19.hs | 9 ++------- advent19/src/advent19atto.hs | 19 ++++++------------- advent19/src/advent19mega.hs | 15 ++++++--------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/advent19/src/advent19.hs b/advent19/src/advent19.hs index 01e872d..a1fd6cc 100644 --- a/advent19/src/advent19.hs +++ b/advent19/src/advent19.hs @@ -12,9 +12,7 @@ import Data.Either data Rule = Letter Char - -- | Then2 Rule Rule - -- | Then3 Rule Rule Rule - | Then [Rule] + | Then [Rule] | Or Rule Rule | See Int deriving (Show, Eq) @@ -29,7 +27,6 @@ main = let (rules, messages) = parse inputP text print $ part1 rules messages print $ part2 rules messages - -- print $ part2 text setup fname = do text <- readFile fname @@ -66,6 +63,7 @@ makeParser m (See i) = makeParser m (m!i) -- Parse the input +inputP = (,) <$> rulesP <* blankLines <*> messagesP rulesP = M.fromList <$> ruleP `sepBy` endOfLine ruleP = (,) <$> decimal <* (string ": ") <*> ruleBodyP @@ -76,9 +74,6 @@ orRuleP = Or <$> thenRuleP <* (string " | ") <*> thenRuleP thenRuleP = Then <$> seeRuleP `sepBy` (string " ") seeRuleP = See <$> decimal - -inputP = (,) <$> rulesP <* blankLines <*> messagesP - messagesP = (munch1 isAlpha) `sepBy` endOfLine blankLines = skipMany1 endOfLine diff --git a/advent19/src/advent19atto.hs b/advent19/src/advent19atto.hs index b322324..6210406 100644 --- a/advent19/src/advent19atto.hs +++ b/advent19/src/advent19atto.hs @@ -17,33 +17,26 @@ import Data.Either data Rule = Letter Char - -- | Then2 Rule Rule - -- | Then3 Rule Rule Rule | Then [Rule] | Or Rule Rule | See Int deriving (Show, Eq) --- data Tree = TEmpty --- | TLetter Char --- | TThen [Tree] --- deriving (Show, Eq) - type RuleSet = M.IntMap Rule main :: IO () main = - do text <- TIO.readFile "data/advent19b.txt" + do text <- TIO.readFile "data/advent19.txt" -- print text let (rules, messages) = successfulParse inputP text let messagesT = map T.pack messages - -- print rules - -- print messages + -- TIO.writeFile "rules19.atto.txt" $ T.pack $ show rules + print $ length rules + print $ length messages print $ part1 rules messagesT print $ part2 rules messagesT - -- print $ part2 text setup fname = do text <- TIO.readFile fname @@ -73,8 +66,8 @@ countMatches rules messages makeParser :: RuleSet -> Rule -> Parser () makeParser m (Letter c) = void $ char c -makeParser m (Then rs) = mapM_ (makeParser m) rs -makeParser m (Or a b) = (makeParser m a) <|> (makeParser m b) +makeParser m (Then rs) = mapM_ (\r -> try (makeParser m r)) rs +makeParser m (Or a b) = (try (makeParser m a)) <|> (makeParser m b) makeParser m (See i) = makeParser m (m!i) diff --git a/advent19/src/advent19mega.hs b/advent19/src/advent19mega.hs index 073d6cf..2ff5e3c 100644 --- a/advent19/src/advent19mega.hs +++ b/advent19/src/advent19mega.hs @@ -29,15 +29,14 @@ type RuleSet = M.IntMap Rule main :: IO () main = - do text <- TIO.readFile "data/advent19b.txt" - -- print text + do text <- TIO.readFile "data/advent19.txt" let (rules, messages) = successfulParse text let messagesT = map T.pack messages - -- print rules - -- print messages + -- TIO.writeFile "rules19.mega.txt" $ T.pack $ show rules + print $ length rules + print $ length messages print $ part1 rules messagesT print $ part2 rules messagesT - -- print $ part2 text setup fname = do text <- TIO.readFile fname @@ -49,7 +48,6 @@ setup fname = return (myParser, updatedRules, messagesT) - part1 = countMatches part2 rules messages = countMatches updatedRules messages @@ -60,18 +58,17 @@ countMatches rules messages = length $ filter isRight $ map (parse myParser "message") messages - where myParser = (makeParser rules (See 0)) -- <* eof + where myParser = (makeParser rules (See 0)) <* eof prettyResults rs = map p rs where p (Left e) = errorBundlePretty e p (Right r) = "^" ++ show r - -- Generate the rules makeParser :: RuleSet -> Rule -> Parser () makeParser m (Letter c) = void $ char c -makeParser m (Then rs) = mapM_ (makeParser m) rs +makeParser m (Then rs) = mapM_ (\r -> try (makeParser m r)) rs makeParser m (Or a b) = (try (makeParser m a)) <|> (makeParser m b) makeParser m (See i) = makeParser m (m!i) -- 2.34.1 From 68817bdbe7f37d4035261fbe78772b9ae8900181 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Thu, 31 Dec 2020 11:26:19 +0000 Subject: [PATCH 04/16] Done day 20 --- advent19/src/advent19atto.hs | 1 - advent20/package.yaml | 62 ++ advent20/src/advent20.hs | 202 ++++ data/advent20.txt | 1727 ++++++++++++++++++++++++++++++++++ data/advent20a.txt | 107 +++ data/advent20seamonster.txt | 3 + problems/day20.html | 365 +++++++ stack.yaml | 1 + 8 files changed, 2467 insertions(+), 1 deletion(-) create mode 100644 advent20/package.yaml create mode 100644 advent20/src/advent20.hs create mode 100644 data/advent20.txt create mode 100644 data/advent20a.txt create mode 100644 data/advent20seamonster.txt create mode 100644 problems/day20.html diff --git a/advent19/src/advent19atto.hs b/advent19/src/advent19atto.hs index 6210406..30ecd93 100644 --- a/advent19/src/advent19atto.hs +++ b/advent19/src/advent19atto.hs @@ -22,7 +22,6 @@ data Rule = Letter Char | See Int deriving (Show, Eq) - type RuleSet = M.IntMap Rule diff --git a/advent20/package.yaml b/advent20/package.yaml new file mode 100644 index 0000000..b8a3866 --- /dev/null +++ b/advent20/package.yaml @@ -0,0 +1,62 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent20 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + +executables: + advent20: + main: advent20.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - attoparsec + - array + - containers diff --git a/advent20/src/advent20.hs b/advent20/src/advent20.hs new file mode 100644 index 0000000..57a141d --- /dev/null +++ b/advent20/src/advent20.hs @@ -0,0 +1,202 @@ +-- import Debug.Trace + +-- import Data.Text (Text) +-- import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text hiding (take) +-- import Data.Attoparsec.Combinator +import Control.Applicative +-- import Control.Applicative.Combinators + +import qualified Data.Array.Unboxed as A +import Data.Array.Unboxed ((!)) +import qualified Data.Map.Strict as M +import Data.Bool (bool) +import Data.List (delete) +import Control.Monad (guard) +-- import Data.Either (fromRight) + + +type Coord = (Int, Int) +type Pixels = A.UArray Coord Bool +type Border = A.UArray Int Bool + +data Tile = Tile + { tId :: Integer + , pixels :: Pixels + } deriving (Show, Eq) + +type Arrangement = M.Map Coord Tile + + +main :: IO () +main = + do text <- TIO.readFile "data/advent20.txt" + let tiles = successfulParse text + let arrangeRMax = (floor $ sqrt @Double $ fromIntegral $ length tiles) - 1 + let arrangement = arrangeTiles arrangeRMax tiles + let image = assembleImage arrangeRMax arrangement + seaMonster <- readSeaMonster + print $ part1 arrangeRMax arrangement + print $ part2 seaMonster image + + +part1 rMax arrangement + = product $ M.elems + $ M.map tId + $ M.filterWithKey (isCorner rMax) arrangement + +part2 seaMonster image = minimum $ map (countRoughness seaMonster) transImages + where imgTile = Tile 0 image + transImages = map pixels $ transforms imgTile + + +readSeaMonster :: IO Pixels +readSeaMonster = + do text <- TIO.readFile "data/advent20seamonster.txt" + -- return $ fromRight (A.listArray ((0, 0), (1, 1)) []) $ parseOnly pixelsP text + return $ case parseOnly pixelsP text of + Left _err -> A.listArray ((0, 0), (1, 1)) [] + Right seaMonster -> seaMonster + + +isCorner _ (0, 0) _ = True +isCorner l (0, c) _ = c == l +isCorner l (r, 0) _ = r == l +isCorner l (r, c) _ = r == l && c == l + +arrangeTiles :: Int -> [Tile] -> Arrangement +arrangeTiles rMax tiles = head $ arrange (0, 0) rMax M.empty tiles + +arrange :: Coord -> Int -> Arrangement -> [Tile] -> [Arrangement] +-- arrange h _ g ts | trace (show h ++ " " ++ show (M.map tId g) ++ " > " ++ show (length ts)) False = undefined +arrange _ _ grid [] = return grid +arrange (r, c) cMax grid tiles = + do tile <- tiles + transTile <- transforms tile + guard $ if r == 0 then True else matchVertical tileAbove transTile + guard $ if c == 0 then True else matchHorizontal tileLeft transTile + arrange (r', c') + cMax + (M.insert (r, c) transTile grid) + (delete tile tiles) + where tileAbove = grid M.! (r - 1 , c) + tileLeft = grid M.! (r, c - 1) + (r', c') = if c == cMax then (r + 1, 0) else (r, c + 1) + + +matchHorizontal tile1 tile2 = (rightBorder tile1) == (leftBorder tile2) +matchVertical tile1 tile2 = (bottomBorder tile1) == (topBorder tile2) + + +topBorder :: Tile -> Border +topBorder Tile{..} = A.listArray (0, c1) [pixels!(0, c) | c <- [0..c1] ] + where (_, (_, c1)) = A.bounds pixels + +bottomBorder :: Tile -> Border +bottomBorder Tile{..} = A.listArray (0, c1) [pixels!(r1, c) | c <- [0..c1] ] + where (_, (r1, c1)) = A.bounds pixels + +leftBorder :: Tile -> Border +leftBorder Tile{..} = A.listArray (0, r1) [pixels!(r, 0) | r <- [0..r1] ] + where (_, (r1, _)) = A.bounds pixels + +rightBorder :: Tile -> Border +rightBorder Tile{..} = A.listArray (0, r1) [pixels!(r, c1) | r <- [0..r1] ] + where (_, (r1, c1)) = A.bounds pixels + + +transforms :: Tile -> [Tile] +transforms tile = + [ r $ f tile + | r <- [id, tRotate, tRotate . tRotate, tRotate . tRotate . tRotate] + , f <- [id, tFlip] + ] + +-- rotate quarter turn clockwise +tRotate tile = tile {pixels = pixels'} + where bs = pixels tile + (_, (r1, c1)) = A.bounds bs + pixels' = A.ixmap ((0, 0), (c1, r1)) rotateIndex bs + rotateIndex (r, c) = (r1 - c, r) -- how to get to the old index from the new one + +tFlip tile = tile {pixels = pixels'} + where bs = pixels tile + (_, (r1, c1)) = A.bounds bs + pixels' = A.ixmap ((0, 0), (r1, c1)) flipIndex bs + flipIndex (r, c) = (r, c1 - c) -- how to get to the old index from the new one + + +assembleImage :: Int -> Arrangement -> Pixels +assembleImage arrangeRMax arrangement = + A.array ((0,0), (imageRMax, imageRMax)) imageElements + where (_, (tileRMax, _)) = A.bounds $ pixels $ arrangement M.! (0, 0) + tRM1 = tileRMax - 1 + imageRMax = tRM1 * (arrangeRMax + 1) - 1 + imageElements = + do ar <- [0..arrangeRMax] -- arrangement row + ac <- [0..arrangeRMax] + tr <- [1..tRM1] -- tile pixels row + tc <- [1..tRM1] + let px = (pixels $ arrangement M.! (ar, ac)) ! (tr, tc) + let ir = (ar * tRM1) + (tr - 1) -- assembled image row + let ic = (ac * tRM1) + (tc - 1) + return ((ir, ic), px) + + +countRoughness sm image = imPixels - (smPixels * nSeaMonsters) + where smPixels = countPixels sm + imPixels = countPixels image + nSeaMonsters = length $ findSeaMonsters sm image + +countPixels :: Pixels -> Int +countPixels = length . filter (== True) . A.elems + +findSeaMonsters :: Pixels -> Pixels -> [Coord] +findSeaMonsters sm image = [ (r, c) + | r <- [0..(imR - smR)] + , c <- [0..(imC - smC)] + , seaMonsterPresent sm image r c + ] + where (_, (smR, smC)) = A.bounds sm + (_, (imR, imC)) = A.bounds image + +seaMonsterPresent sm image dr dc = all bothPresent $ A.indices sm + where bothPresent (r, c) = if (sm!(r, c)) + then (image!(r + dr, c + dc)) + else True + + +showTile Tile{..} = show tId ++ "\n" ++ (showP pixels) + +showP ps = unlines [[bool ' ' '\x2588' (ps!(r, c)) | c <- [0..cMax] ] | r <- [0..rMax]] + where (_, (rMax, cMax)) = A.bounds ps + -- sb b = bool '.' '#' b + +-- -- Parse the input file + +tilesP = tileP `sepBy` blankLines + +blankLines = many endOfLine + +tileP = Tile <$> ("Tile " *> decimal) <* ":" <* endOfLine <*> pixelsP + +pixelsP = pixify <$> (pixelsRowP `sepBy` endOfLine) +pixelsRowP = many1 (satisfy (inClass " .#")) + +pixify :: [String] -> Pixels +pixify rows = A.array ((0, 0), (nRows, nCols)) + [ ((r, c), (rows!!r)!!c == '#') + | r <- [0..nRows] + , c <- [0..nCols] + ] + where nRows = length rows - 1 + nCols = (length $ head rows) - 1 + + +-- successfulParse :: Text -> (Integer, [Maybe Integer]) +successfulParse input = + case parseOnly tilesP input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right tiles -> tiles diff --git a/data/advent20.txt b/data/advent20.txt new file mode 100644 index 0000000..d7191b5 --- /dev/null +++ b/data/advent20.txt @@ -0,0 +1,1727 @@ +Tile 1621: +.#.##...#. +#..#..#.#. +#.#..#..## +.....#..#. +.#..#...## +#....#...# +.#........ +#.#.#....# +...#...#.. +.#..#....# + +Tile 3671: +..#.#.###. +#.##....## +#......... +##..#.#... +#..###.... +..#.#....# +##..###..# +..#......# +.........# +......###. + +Tile 2803: +#.#.#..#.. +#.....#... +...##..### +#.#.....## +#...#..#.# +..#...##.# +..#...#..# +####.#..## +#..##....# +#..#.##.#. + +Tile 1531: +####.##### +.###...### +##..#..#.# +##.#..#..# +#....#..## +##.#....#. +#.#.##.... +....#..#.. +#...#..... +##....#... + +Tile 1811: +#.#...#..# +##....#.## +#...##.#.. +#..##..... +.#.#.....# +##..#..... +##.#...... +..#...##.. +.#.##....# +##...##..# + +Tile 2143: +##.###.#.# +#..##.##.. +###....... +..##.#...# +#.......#. +#.#....##. +...#..#### +..##...#.# +#.#..#.##. +#.#.#...## + +Tile 2887: +.......##. +#..#..#..# +....#..... +...#..##.. +..#....... +#...##..## +..#...##.. +#.....#.## +##..#..##. +#...#.#### + +Tile 3511: +.#.##....# +#.#...##.# +#...##.### +....#..... +..#......# +.###.#..#. +#......... +#.#....### +.......#.# +#..####### + +Tile 3911: +.#..#.###. +#...#.##.. +.#..#...## +##.#.##.## +....#.#..# +...###.... +.....#...# +...##..#.. +###.#.#.#. +##.....#.# + +Tile 3821: +#####..#.. +##..#..... +....##.#.# +#....#.... +#...##.#.# +#........# +####...... +#.#.#....# +....###### +..#...###. + +Tile 3539: +#####.##.. +#........# +####.#.... +.##..#.#.# +#.....#... +#.#......# +##...###.# +.#..#..... +#.#....... +...#...#.. + +Tile 3251: +....#..##. +.###.#...# +#..#.....# +...#.....# +..#....... +.##..#...# +#.......## +#.....#... +....#..#.# +######.#.# + +Tile 2677: +.#...#...# +...#.###.. +......##.. +#.##.##... +#.#...#.## +#..#####.. +......##.. +......##.# +#..#..#... +..##.####. + +Tile 3011: +#.#..#..## +#.###..#.. +#..#..##.. +#.#..#...# +##...##### +....#..### +.#..#..#.# +..#...#..# +##.##..#.# +.#.##..... + +Tile 1489: +#...##.### +#.#..#.... +#.....#..# +##..#..... +...#....## +.##.##.#.# +#.#......# +#........# +....#..... +##.#.##### + +Tile 3769: +.....####. +##....#### +###....#.# +.##..#.#.# +.......... +##....#### +#...#..#.. +...#.....# +##.#.....# +#...##.### + +Tile 2293: +.#..#.#... +####...... +##...#.... +###.#.#... +.##.##...# +......#.#. +##.....#.. +#..#.##.## +.##....##. +.#.....#.. + +Tile 3947: +.#.#...##. +.......... +..#...##.# +..###..#.# +##...#.### +.#..#..#.. +#.#....#.. +....#.#..# +.#....#### +######..#. + +Tile 1223: +#..#####.# +###..#..## +##.###.... +...##.#... +..#.##.#.. +##.###...# +...#..#.## +...#..#... +.#....#..# +#..####... + +Tile 3331: +#.....##.. +##..###.#. +.##.#...#. +.##..#.#.. +#......#.. +...#.....# +###.#.#... +.##......# +#..#...... +...#...### + +Tile 3691: +#..#..#.## +......#..# +#.#..##..# +###....... +#.#....##. +##.#..##.. +#......#.. +..#....... +...#.#..#. +#..#...... + +Tile 1289: +#.......#. +##.##....# +####...... +.#..#.#..# +#.#.#..### +#..#...... +##.#####.. +.#........ +##.##....# +##.####### + +Tile 2857: +.#.#..#.## +.....#.#.. +#..#...#.. +.##...#..# +##..#..#.# +#..#..#..# +...#...... +#.#.#..... +##...#.... +....#.##.. + +Tile 3559: +#.##..##.. +..#.##.### +##..#....# +#.#..#..#. +##.####..# +.....#...# +#....#.... +##..#.##.. +#..#.....# +###.##..## + +Tile 2633: +...#.#..## +##.......# +#...##..#. +#.#....#.# +.........# +...#.....# +.#.##....# +...#..#... +#.#.##.... +..#..##... + +Tile 1973: +#.#.....#. +#.......#. +#....#.... +.#.#...##. +.........# +#.......#. +...#.##..# +.##...#... +##..#..#.. +####..##.# + +Tile 1373: +#####.#..# +##.##..### +#.####...# +..###.#... +....##...# +#...#....# +##.#....## +.......#.. +##.#.##.#. +#.###.##.# + +Tile 1759: +.#.....##. +#.#..#...# +....###..# +........## +....#..... +.....#..#. +#...#....# +.#..#...#. +...#.#.#.. +##...#..## + +Tile 1213: +#....###.# +###...##.# +.#.....#.# +#......##. +.#...#.##. +.##....... +....##...# +#......... +.........# +#.....#.## + +Tile 2341: +#.....#.#. +...##.#..# +.....##..# +......##.# +#...#....# +..#...###. +..##.#.#.# +.#.#....## +.#.....### +.#.#...##. + +Tile 3547: +####.#.#.# +...###...# +#..#.##... +##..#.#... +#....#.#.# +.#.......# +.#.#...... +###.....#. +#.#....### +.#.##.#... + +Tile 2003: +#####.#### +...#..#..# +.#.......# +#.#.#...## +.#.#.#..#. +#......#.. +...#..#... +.#...#.#.. +#........# +####.###.. + +Tile 2861: +#..##.##.. +..#.#....# +....##.#.. +##........ +#......... +##.....#.# +##.....##. +####.....# +###..##### +.........# + +Tile 3697: +#..##.#### +.....#.... +#.#.#.#.#. +#.##...### +..##.....# +.#.......# +.##....... +#.#..#...# +.#.###.#.. +####.####. + +Tile 3929: +.#.##..#.# +##.#....## +....#.#..# +....#.#.#. +##........ +...#..#... +###....#.# +#........# +.###.##.## +###..##### + +Tile 3527: +#.#.#...#. +####.#.... +......#... +.##......# +.#......## +.##.#.#.## +#..#...... +#.....#... +.#........ +..#..####. + +Tile 1777: +.#..#...## +#....###.. +..#..##.## +..##...#.. +....#.#... +#...##.#.. +#..##.#..# +...##..... +.#....#..# +.#..#..### + +Tile 1543: +......#... +.#...##... +#...#..#.# +.......... +#..##....# +..#.#...## +...#.####. +##....#... +...#..#### +.#.#..#### + +Tile 2063: +##....#... +#.....#... +###.##...# +......#..# +...##..#.. +###.#..... +##.....##. +#..#.##... +##.###..## +#....###.. + +Tile 1181: +#.##...### +####.#.... +.........# +####..##.# +.....#..#. +.......#.. +..###....# +##..##.... +#.#...#..# +.#.#.#...# + +Tile 3491: +#...###.## +..##..#.## +.......##. +.......... +.....#..#. +#..#...... +##....#.#. +...##...#. +..###..... +..#.##..#. + +Tile 1873: +...#.....# +...#.#..#. +##.#...... +.#...#.### +#.#.#..#.. +.....###.# +#..#..#... +....#..... +.....#.#.# +######...# + +Tile 2579: +.####...#. +#..#..#..# +.....#...# +#.#..#...# +#.....##.. +......#..# +#......##. +.#...##... +.#...##... +.##.####.. + +Tile 1481: +.#.#.##### +..#.#.##.. +.###...#.# +...##..... +..#.#.#.#. +.#.......# +##.#....#. +#.#...#... +.###..#... +......##.# + +Tile 2417: +.#..#..#.# +.#.#.....# +.###..##.# +#.#.#..... +#....#.### +..#..#.... +#....#.#.. +####....## +..#.#...## +....###### + +Tile 3581: +..##.....# +.....##..# +#......... +#....##..# +#..#....#. +#.....#..# +.#..#.#.#. +...#...... +.....##..# +#......... + +Tile 3593: +#.##.###.. +###.....## +##.#....#. +###.#....# +###....#.# +#.#..#..## +......#.## +...#....#. +.#...#..#. +..#####..# + +Tile 3167: +#...#.#.#. +......#.## +##.##.#.## +#...#.##.# +....#...#. +..#....##. +...#...##. +...##..#.. +....#.##.# +##.#....#. + +Tile 1439: +...##..### +#.#......# +..#..###.# +....#.#... +#......... +......#..# +..#.#.#..# +##.#.#.... +..#...#..# +#.###.#... + +Tile 1249: +..#.##...# +#.#......# +.......#.. +##.#.#.#.# +.#..#..#.. +..#.#..#.# +.....##.#. +#........# +..#..##.## +..#..##### + +Tile 2687: +##...##... +###.###.#. +#...###..# +.#.......# +....#.#... +.....##### +##.#####.. +#....#.... +..#.####.# +##....#.#. + +Tile 2693: +..#..#..#. +....#..### +....##.... +.#.##..... +.#..###... +..##.#.... +#......... +....##.##. +..#..#.... +.#.#...... + +Tile 1741: +.#.###..## +......#### +#.......## +#.#......# +##..#...#. +##.....#.# +#..#...... +..##.#..## +#..#...... +#.#..###.# + +Tile 3413: +...####.#. +.#..#.##.. +#....#.##. +##.#.....# +##.###..## +.......### +.#....###. +#....##..# +##.####..# +....#.###. + +Tile 3191: +.....####. +##.##..#.. +.##.#.##.# +.......### +....####.. +.#.#..#.#. +...#...#.. +##..#..#.# +...#..#... +..##..#.#. + +Tile 2897: +#.#######. +...#....#. +#.....##.# +###.#...#. +##.#####.# +..#.##..## +#.##...... +##.#.##..# +#.#....#.. +#.##.#.### + +Tile 2017: +##.##...## +#...#.##.. +#..#.#...# +.##....... +##.......# +##..#.#..# +##.#.#.#.# +.......... +.......... +..######.# + +Tile 2939: +#...##.##. +.....#.##. +....#.#... +#.#......# +.#.....#.# +.........# +###.....## +......#..# +#..#..##.. +.##..#.##. + +Tile 1753: +#...#.#.## +.#...#...# +###..#.### +#..##....# +#..#...... +#.##...#.. +..#...#... +#..#...... +.#.......# +....#.#.## + +Tile 3229: +#..####.#. +#.....#..# +......##.. +#.#...##.# +#...#...## +#.#....#.# +.#..##..#. +#..#.....# +#..##..... +.#.#.#..## + +Tile 1367: +####.....# +...#.##... +...#...#.. +.#.###..#. +.........# +.#........ +.......... +.#...###.# +##........ +...##..#.# + +Tile 2851: +..#.#...## +#.....##.# +.##.#..#.# +#...###..# +###...#... +....#..#.# +..#....... +#.....#... +...#.#...# +.###..#..# + +Tile 2357: +....##.#.# +###...#.## +####..##.# +#.####...# +#...##...# +#.#......# +#..##.#.#. +#.#....#.# +.###...#.. +####..#.## + +Tile 1697: +#..#.#.##. +.......#.. +...##....# +##........ +....#....# +##.#.....# +.##......# +#....#..#. +##.##...## +#....#...# + +Tile 1571: +#.###...#. +##..#..#.. +.........# +...#.#.#.. +#........# +#..##.#... +##...##.#. +.......... +....#.#... +.##.....#. + +Tile 3323: +#.#.#..### +#...#...## +.......#.# +#.##...... +..#.#..##. +#.......#. +....####.# +....##...# +..##....## +######.### + +Tile 3461: +#....##.#. +....#..... +#......##. +##.....##. +#..#...##. +.#.......# +##.#...... +.......... +.....#..## +.....#.### + +Tile 2719: +.#.#.#.... +..#..#.##. +..##...### +..#..#...# +##.......# +.#........ +.##..#.... +..##..#... +..#....#.. +.#.#.#..#. + +Tile 3359: +.###...#.# +.....###.# +#..####.#. +.....##..# +..#.#...#. +#.#..###.. +..#....#.# +....#.#..# +.....#..#. +#.###.#..# + +Tile 3803: +.####.#..# +...#...### +.......##. +.......##. +#..#..#..# +##...#.... +....##.... +##........ +..#..##### +..#..##... + +Tile 3019: +##..###.#. +..#....... +##..#.##.# +##......#. +#......#.. +#.#....#.. +.###.###.# +#..#.##..# +###.##.#.# +.###.###.# + +Tile 2791: +......#.#. +#....#.... +##...##### +....##.... +#.....##.# +..##...... +#.#...#..# +...##...#. +..##....#. +##.##..#.. + +Tile 3881: +#....##..# +...#..#..# +.###..#..# +...#....## +#...#..#.# +#.#.#..#.# +#..##..... +...#...... +#.#....#.. +.#..##.### + +Tile 2087: +.#..#.#... +###....### +.###..#.## +........## +###.##..## +...#...#.# +#...#....# +##..#....# +#..####.#. +##..#####. + +Tile 1789: +######.#.. +........#. +..#...##.# +.#.......# +.#...#.... +#..#.#..## +#####.#..# +#...###..# +.#.#....## +####.##.#. + +Tile 2539: +#.###.#..# +..#..#...# +##.##.#... +#.....##.. +#..##..#.. +..###.##.# +#..###...# +.###.#.#.. +#...#..... +..###.##.. + +Tile 2111: +####..###. +#....###.. +..#.....## +#....##.## +#.....#... +#..#.#.... +...#..#### +##..##..#. +##.....#.# +#.#...#.#. + +Tile 1433: +#.....#..# +.#.###.#.# +.#...#.#.# +.......### +#..##.#... +.#...##.#. +#..#....## +#......#.. +....#..#.# +..#.#..##. + +Tile 1667: +..##...... +#..#....#. +.##.#..#.# +.....#.... +#.#.##..#. +...##..... +..#.#....# +#.#..#...# +...#...##. +....#....# + +Tile 2389: +.#.#...#.. +.#.......# +.....#.... +#...###..# +.......... +.#........ +.#.###.#.# +#....#..#. +..#......# +##...#...# + +Tile 1069: +...###..## +...#.....# +##......## +....##.... +..#..##..# +##..#..#.# +##.#.#.#.# +.#..###..# +#.#....... +.#.#.#.... + +Tile 1103: +..###.##.. +...##..#.# +#....##..# +....#..#.# +#....#.#.. +###....### +..#...##.. +..##.....# +#........# +.####..#.. + +Tile 3761: +....#.##.. +###....... +#...#..... +..##.#...# +#........# +.###...... +...#..#... +...#.#.#.. +#....#.#.# +....#...#. + +Tile 2473: +........## +.#.#..#... +.#........ +.####.#.## +##..##...# +##.....#.. +###.#..#.# +.......... +.#.#..##.# +..#....#.# + +Tile 1987: +...#..#.#. +......#... +#....#.### +..#....#.. +..#..##..# +........#. +#..#.....# +...#..#..# +.......#.# +...###.##. + +Tile 1187: +..#.#.#..# +##.#...##. +#......#.# +....#....# +..##...#.# +#..#..#.## +.......... +..##...#.# +...####..# +.#.#.##### + +Tile 2699: +###.#.##.# +.#.#####.# +.#..#..#.. +.###....## +..#..##..# +.....#...# +.......... +#...##...# +#......... +##..#..#.# + +Tile 3643: +..##...#.. +#..#..#.## +#.###.#### +..##..##.. +......#... +##.##..#.. +...#.##.## +....#..#.# +##..#....# +#....#...# + +Tile 3463: +..###.##.# +......##.# +#........# +......##.# +##.......# +##..#..#.# +##.......# +##......#. +##.#.##... +.###..#.## + +Tile 1117: +#.#.##.... +..#..#.### +.#..#..... +...#.#.... +........#. +##.###...# +..#..#.#.# +....#..#.. +..#.#....# +..#.#..#.. + +Tile 1163: +.##.##..## +....#..#.. +##..#..#.. +#..#.....# +#..#.....# +..#.##.... +...#.#.... +..###..#.# +...#...#.# +###.###### + +Tile 3557: +#.#....#.. +....####.# +.#....#### +..#...###. +#......#.. +.......#.. +##....#... +##.....#.. +...#..#.#. +...###.#.. + +Tile 2467: +.####....# +.#.#..##.# +####...... +......#.#. +#.#....#.# +##.....#.. +..#....#.# +..#.##...# +.#.....### +#...##.##. + +Tile 1471: +.###..#.## +##.#...##. +.#...#.... +....##..#. +........#. +##....##.# +###..##.#. +#....###.# +##.....##. +#..#..##.# + +Tile 3931: +#....#..## +#...#..#.. +.#..###### +#.###...#. +....#.##.# +#.#...#### +#....#..#. +....##.#.. +#..#..#### +#.#.#..... + +Tile 2029: +##.#.##### +#.#......# +#...##...# +#...#..... +#..##..... +#.....##.# +....##.... +..##.#.### +###.#.###. +..####.##. + +Tile 1913: +#..###.### +.......### +.#..#.#### +.#..#.#... +..#....... +.#....###. +.###..#.#. +#....#..#. +#.#..#.#.. +.#..#.#.#. + +Tile 2213: +..#.##.### +......###. +..#..#...# +#..#..#.## +#....###.. +...#....#. +#.##.#..#. +##.#...#.. +.##....### +####.#..#. + +Tile 1511: +###.#...## +.##.....#. +.##...#..# +...##.##.. +#.#..#.#.# +##...###.# +###..#.### +.##.##..#. +#......#.. +###.....## + +Tile 2243: +#..#.#...# +##...#.... +.....#.#.# +....##..#. +#..######. +.#..#.##.. +#......... +...#.##.#. +.#.......# +.##...#.## + +Tile 3701: +...####### +#..#...##. +...####..# +..#..#...# +##........ +#.....#..# +##..#.#... +##.#.##.#. +.##....... +###.#...## + +Tile 3137: +.#.####... +#..#.#...# +.......#.# +#..#.....# +#.....#... +#...###.## +.###...#.# +##......## +#.#....#.# +##...####. + +Tile 2437: +#...#..### +.#.#....#. +....#...#. +.......#.# +#.#...##.# +###..#...# +#.##..#... +....#..... +#.#.#.##.. +.#.#.#.### + +Tile 1009: +..#.#.#... +...#..##.. +##...##..# +........## +##...###.# +#....#...# +..#..#...# +..####.### +#......... +####..#..# + +Tile 2399: +..####.#.. +###..#.... +#..#..##.. +...#.#.... +##.##..... +##.###..#. +##..##..## +###....#.# +..#......# +#.###..##. + +Tile 2843: +.....#.... +......#... +.##.#....# +..#....#.. +.##.....## +.#...##.#. +####..##.. +.##....##. +....##...# +#..###...# + +Tile 1193: +##.....### +.......#.. +.#...#.#.. +#.#...#.## +..#.....## +.#.....#.. +#...#....# +##.#..#.#. +##.....#.# +#..#.....# + +Tile 1951: +###......# +.......... +.......... +#####..... +#.##..#... +.........# +##.##..... +#.#..#.##. +.#...#...# +..#.###... + +Tile 1879: +#...#..... +.#.......# +###....... +#####..... +#..#.#.... +...###.##. +#.......#. +#.#......# +.#..##.... +..#.##.### + +Tile 3469: +..####...# +#...#...#. +......###. +........#. +####.....# +#...#...#. +...#....## +#..#..#..# +..#...##.# +#####..#.# + +Tile 2161: +####.####. +###...#.## +.##...#... +#..#...#.. +##...##.#. +#......... +#...##...# +....#.#..# +..#.##..## +#.......## + +Tile 2083: +##.##.#..# +#.##.#..#. +...#.....# +##.#.##.#. +.....#..#. +#.......#. +...###.#.# +....##...# +#.##.#...# +##.#...### + +Tile 2089: +#.#.###.#. +#..##..... +.....#...# +#......... +.##...#### +#...##...# +.#.......# +....#...## +#..##....# +.....##.#. + +Tile 1051: +#.....##.# +.....##.#. +#...#....# +.#.#...... +........#. +.......#.. +##....#.## +#.......## +#........# +####.##.#. + +Tile 3347: +....##.#.. +#.#.#..#.# +##........ +..#....#.. +##...##... +.##.#..... +#........# +#..###.... +.....#...# +##.##.#..# + +Tile 2927: +#.##...... +...#..#.## +.#.#.#.##. +.......... +##....#... +##.#...#.. +....##.##. +#....#.#.. +..#.....#. +##.###.#.. + +Tile 1301: +#..##.#.#. +#.#......# +..#...#..# +##....#..# +#......... +.......#.# +....##.#.. +#..#.###.. +..#.###### +...###.### + +Tile 2459: +#..###.... +...###.### +##........ +##..#..#.. +##.#.##.## +#.##.#..#. +#..##..##. +.#...##..# +#........# +..#.###### + +Tile 1583: +.#.#..#..# +#.#.#....# +.##....... +.........# +#....#.... +##...###.# +#.#....... +.........# +#...#....# +#.###..#.# + +Tile 3533: +.#.##.#..# +.#.......# +........#. +.#...#...# +#......... +.......#.# +...#...#.. +##..#..#.# +...#.###.. +.###..#### + +Tile 1993: +#.####..#. +..##.#.#.# +.#.#...... +.#........ +..#....... +#.##..#..# +##..#..... +.#.##..#.. +........#. +.#.#.###.# + +Tile 3853: +..#.####.# +##....##.# +..#......# +....#..... +.....#.##. +......#..# +..#..#.#.# +##....#... +###.#..##. +##...#.#.# + +Tile 2113: +#..#.#.#.# +#.....#.## +#.....#..# +.##....#.# +##.#.##### +#..#...... +...#...#.. +...#.#..## +.......##. +..##....## + +Tile 3319: +####.#..## +##....#.#. +#.......#. +......#..# +####...##. +.......... +##.....#.. +..#..#..## +#...#..... +.##..#...# + +Tile 3847: +...##..#.# +..#.##...# +...#..#### +#..#.#.#.. +#........# +#....##..# +#....#..## +.#.#.##.## +.####..... +#....##..# + +Tile 1283: +..##..###. +##.......# +#.#.#..... +.#.#....#. +..#..#.... +#...#..... +##.......# +.##.#...## +##.####... +##..#..### + +Tile 2957: +#.####.#.# +#..#..##.. +#..###...# +#.#..#.#.. +#.......#. +#.#..#...# +######.... +#.......## +#...#...#. +.##..#.##. + +Tile 1097: +.###.#.### +#......##. +#........# +....#...#. +..##..#.#. +#....#..## +.###...##. +..##.#...# +#..#.####. +#.#....... + +Tile 1399: +#.###..### +#...##.### +....#.#... +#...##.#.. +..#...#..# +#...###... +.......#.. +..#.#.#... +...##...#. +...##..##. + +Tile 1451: +#.#...#.#. +#........# +#.#....#.# +###.#..... +....##.... +.##.#..#.. +.#.####..# +..#..###.# +...#...#.# +#...##.#.# + +Tile 1559: +#..#.#.### +......#... +.....#..## +#......... +##..#..... +...#...#.. +##.#.#.... +.....#.##. +#...#.#.#. +...#####.. + +Tile 3391: +#.#.#.#..# +##..#..... +.#...###.. +......#..# +#.#.....#. +...#..#... +.#......#. +.......#.. +.....#.#.# +#.#.#.##.# + +Tile 2423: +#.#.#....# +#......#.. +#.#.#.#.## +...#.#.#.# +....#.#.#. +.......#.. +.##.....#. +.........# +#.#..#...# +...##..##. + +Tile 2297: +.....##### +#..#...... +#...#..... +##...#.#.. +.......##. +#.......#. +###....### +..#.....#. +.....##... +##.##.###. + +Tile 2011: +#######... +#.#...#.#. +...##..#.. +...##..#.# +......#..# +#..#.....# +...#.#.... +....#.#... +..#.###..# +#.#####.#. + +Tile 1049: +#.#...#... +.......### +#..#.#..## +##.......# +.#.###...# +##....#... +...#.##... +........#. +...#..#.#. +##...##.## + +Tile 3943: +..#...#### +...#.##... +#.#.###... +.#...###.# +....#.##.. +.##...#..# +####.....# +####.##.#. +##...#.... +.##.#...#. + +Tile 2039: +#####.#..# +#.#....### +.....#.... +##.....#.# +.......#.. +#......#.. +..#...#..# +#.#...#... +..##...#.. +##.####### + +Tile 1297: +.#..##.### +#.....#..# +###..##..# +.##..#..## +...#...... +#..#....## +..#......# +...##.#..# +....##.... +#..###.#.. + +Tile 1597: +.#..#.##.. +###......# +#...##...# +.#.#....## +...##.##.. +#.###....# +###.#..... +..#....#.# +...##....# +###.##.... + +Tile 1319: +...#.##..# +#.#####... +.......... +.#..#..#.. +#...#.#.#. +.#.##..#.. +###....... +#...#.##.. +...#.....# +##.#####.# + +Tile 2333: +#..##..##. +...#...#.# +..##.#.... +#....#.##. +..##..##.# +..##..###. +...##.#..# +.....#.#.# +#......#.# +########.. + +Tile 1423: +#.##..##.. +#.##.....# +#.#..##... +##.#####.. +...#.#..#. +.#..#.#.#. +#.##....## +...###..## +#.#.#...#. +#..##.###. + +Tile 1303: +.######### +##..#....# +..#.#.#### +.......... +#...#..... +#.#..#...# +###.#..... +.##.#....# +#.#.#..#.. +##..##..#. diff --git a/data/advent20a.txt b/data/advent20a.txt new file mode 100644 index 0000000..b3aed46 --- /dev/null +++ b/data/advent20a.txt @@ -0,0 +1,107 @@ +Tile 2311: +..##.#..#. +##..#..... +#...##..#. +####.#...# +##.##.###. +##...#.### +.#.#.#..## +..#....#.. +###...#.#. +..###..### + +Tile 1951: +#.##...##. +#.####...# +.....#..## +#...###### +.##.#....# +.###.##### +###.##.##. +.###....#. +..#.#..#.# +#...##.#.. + +Tile 1171: +####...##. +#..##.#..# +##.#..#.#. +.###.####. +..###.#### +.##....##. +.#...####. +#.##.####. +####..#... +.....##... + +Tile 1427: +###.##.#.. +.#..#.##.. +.#.##.#..# +#.#.#.##.# +....#...## +...##..##. +...#.##### +.#.####.#. +..#..###.# +..##.#..#. + +Tile 1489: +##.#.#.... +..##...#.. +.##..##... +..#...#... +#####...#. +#..#.#.#.# +...#.#.#.. +##.#...##. +..##.##.## +###.##.#.. + +Tile 2473: +#....####. +#..#.##... +#.##..#... +######.#.# +.#...#.#.# +.######### +.###.#..#. +########.# +##...##.#. +..###.#.#. + +Tile 2971: +..#.#....# +#...###... +#.#.###... +##.##..#.. +.#####..## +.#..####.# +#..#.#..#. +..####.### +..#.#.###. +...#.#.#.# + +Tile 2729: +...#.#.#.# +####.#.... +..#.#..... +....#..#.# +.##..##.#. +.#.####... +####.#.#.. +##.####... +##..#.##.. +#.##...##. + +Tile 3079: +#.#.#####. +.#..###### +..#....... +######.... +####.#..#. +.#...#.##. +#.#####.## +..#.###... +..#....... +..#.###... \ No newline at end of file diff --git a/data/advent20seamonster.txt b/data/advent20seamonster.txt new file mode 100644 index 0000000..ab9cbbf --- /dev/null +++ b/data/advent20seamonster.txt @@ -0,0 +1,3 @@ + # +# ## ## ### + # # # # # # diff --git a/problems/day20.html b/problems/day20.html new file mode 100644 index 0000000..ea347bb --- /dev/null +++ b/problems/day20.html @@ -0,0 +1,365 @@ + + + + +Day 20 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 20: Jurassic Jigsaw ---

The high-speed train leaves the forest and quickly carries you south. You can even see a desert in the distance! Since you have some spare time, you might as well see if there was anything interesting in the image the Mythical Information Bureau satellite captured.

+

After decoding the satellite messages, you discover that the data actually contains many small images created by the satellite's camera array. The camera array consists of many cameras; rather than produce a single square image, they produce many smaller square image tiles that need to be reassembled back into a single image.

+

Each camera in the camera array returns a single monochrome image tile with a random unique ID number. The tiles (your puzzle input) arrived in a random order.

+

Worse yet, the camera array appears to be malfunctioning: each image tile has been rotated and flipped to a random orientation. Your first task is to reassemble the original image by orienting the tiles so they fit together.

+

To show how the tiles should be reassembled, each tile's image data includes a border that should line up exactly with its adjacent tiles. All tiles have this border, and the border lines up exactly when the tiles are both oriented correctly. Tiles at the edge of the image also have this border, but the outermost edges won't line up with any other tiles.

+

For example, suppose you have the following nine tiles:

+
Tile 2311:
+..##.#..#.
+##..#.....
+#...##..#.
+####.#...#
+##.##.###.
+##...#.###
+.#.#.#..##
+..#....#..
+###...#.#.
+..###..###
+
+Tile 1951:
+#.##...##.
+#.####...#
+.....#..##
+#...######
+.##.#....#
+.###.#####
+###.##.##.
+.###....#.
+..#.#..#.#
+#...##.#..
+
+Tile 1171:
+####...##.
+#..##.#..#
+##.#..#.#.
+.###.####.
+..###.####
+.##....##.
+.#...####.
+#.##.####.
+####..#...
+.....##...
+
+Tile 1427:
+###.##.#..
+.#..#.##..
+.#.##.#..#
+#.#.#.##.#
+....#...##
+...##..##.
+...#.#####
+.#.####.#.
+..#..###.#
+..##.#..#.
+
+Tile 1489:
+##.#.#....
+..##...#..
+.##..##...
+..#...#...
+#####...#.
+#..#.#.#.#
+...#.#.#..
+##.#...##.
+..##.##.##
+###.##.#..
+
+Tile 2473:
+#....####.
+#..#.##...
+#.##..#...
+######.#.#
+.#...#.#.#
+.#########
+.###.#..#.
+########.#
+##...##.#.
+..###.#.#.
+
+Tile 2971:
+..#.#....#
+#...###...
+#.#.###...
+##.##..#..
+.#####..##
+.#..####.#
+#..#.#..#.
+..####.###
+..#.#.###.
+...#.#.#.#
+
+Tile 2729:
+...#.#.#.#
+####.#....
+..#.#.....
+....#..#.#
+.##..##.#.
+.#.####...
+####.#.#..
+##.####...
+##..#.##..
+#.##...##.
+
+Tile 3079:
+#.#.#####.
+.#..######
+..#.......
+######....
+####.#..#.
+.#...#.##.
+#.#####.##
+..#.###...
+..#.......
+..#.###...
+
+

By rotating, flipping, and rearranging them, you can find a square arrangement that causes all adjacent borders to line up:

+
#...##.#.. ..###..### #.#.#####.
+..#.#..#.# ###...#.#. .#..######
+.###....#. ..#....#.. ..#.......
+###.##.##. .#.#.#..## ######....
+.###.##### ##...#.### ####.#..#.
+.##.#....# ##.##.###. .#...#.##.
+#...###### ####.#...# #.#####.##
+.....#..## #...##..#. ..#.###...
+#.####...# ##..#..... ..#.......
+#.##...##. ..##.#..#. ..#.###...
+
+#.##...##. ..##.#..#. ..#.###...
+##..#.##.. ..#..###.# ##.##....#
+##.####... .#.####.#. ..#.###..#
+####.#.#.. ...#.##### ###.#..###
+.#.####... ...##..##. .######.##
+.##..##.#. ....#...## #.#.#.#...
+....#..#.# #.#.#.##.# #.###.###.
+..#.#..... .#.##.#..# #.###.##..
+####.#.... .#..#.##.. .######...
+...#.#.#.# ###.##.#.. .##...####
+
+...#.#.#.# ###.##.#.. .##...####
+..#.#.###. ..##.##.## #..#.##..#
+..####.### ##.#...##. .#.#..#.##
+#..#.#..#. ...#.#.#.. .####.###.
+.#..####.# #..#.#.#.# ####.###..
+.#####..## #####...#. .##....##.
+##.##..#.. ..#...#... .####...#.
+#.#.###... .##..##... .####.##.#
+#...###... ..##...#.. ...#..####
+..#.#....# ##.#.#.... ...##.....
+
+

For reference, the IDs of the above tiles are:

+
1951    2311    3079
+2729    1427    2473
+2971    1489    1171
+
+

To check that you've assembled the image correctly, multiply the IDs of the four corner tiles together. If you do this with the assembled tiles from the example above, you get 1951 * 3079 * 2971 * 1171 = 20899048083289.

+

Assemble the tiles into an image. What do you get if you multiply together the IDs of the four corner tiles?

+
+

Your puzzle answer was 30425930368573.

--- Part Two ---

Now, you're ready to check the image for sea monsters.

+

The borders of each tile are not part of the actual image; start by removing them.

+

In the example above, the tiles become:

+
.#.#..#. ##...#.# #..#####
+###....# .#....#. .#......
+##.##.## #.#.#..# #####...
+###.#### #...#.## ###.#..#
+##.#.... #.##.### #...#.##
+...##### ###.#... .#####.#
+....#..# ...##..# .#.###..
+.####... #..#.... .#......
+
+#..#.##. .#..###. #.##....
+#.####.. #.####.# .#.###..
+###.#.#. ..#.#### ##.#..##
+#.####.. ..##..## ######.#
+##..##.# ...#...# .#.#.#..
+...#..#. .#.#.##. .###.###
+.#.#.... #.##.#.. .###.##.
+###.#... #..#.##. ######..
+
+.#.#.### .##.##.# ..#.##..
+.####.## #.#...## #.#..#.#
+..#.#..# ..#.#.#. ####.###
+#..####. ..#.#.#. ###.###.
+#####..# ####...# ##....##
+#.##..#. .#...#.. ####...#
+.#.###.. ##..##.. ####.##.
+...###.. .##...#. ..#..###
+
+

Remove the gaps to form the actual image:

+
.#.#..#.##...#.##..#####
+###....#.#....#..#......
+##.##.###.#.#..######...
+###.#####...#.#####.#..#
+##.#....#.##.####...#.##
+...########.#....#####.#
+....#..#...##..#.#.###..
+.####...#..#.....#......
+#..#.##..#..###.#.##....
+#.####..#.####.#.#.###..
+###.#.#...#.######.#..##
+#.####....##..########.#
+##..##.#...#...#.#.#.#..
+...#..#..#.#.##..###.###
+.#.#....#.##.#...###.##.
+###.#...#..#.##.######..
+.#.#.###.##.##.#..#.##..
+.####.###.#...###.#..#.#
+..#.#..#..#.#.#.####.###
+#..####...#.#.#.###.###.
+#####..#####...###....##
+#.##..#..#...#..####...#
+.#.###..##..##..####.##.
+...###...##...#...#..###
+
+

Now, you're ready to search for sea monsters! Because your image is monochrome, a sea monster will look like this:

+
                  # 
+#    ##    ##    ###
+ #  #  #  #  #  #   
+
+

When looking for this pattern in the image, the spaces can be anything; only the # need to match. Also, you might need to rotate or flip your image before it's oriented correctly to find sea monsters. In the above image, after flipping and rotating it to the appropriate orientation, there are two sea monsters (marked with O):

+
.####...#####..#...###..
+#####..#..#.#.####..#.#.
+.#.#...#.###...#.##.O#..
+#.O.##.OO#.#.OO.##.OOO##
+..#O.#O#.O##O..O.#O##.##
+...#.#..##.##...#..#..##
+#.##.#..#.#..#..##.#.#..
+.###.##.....#...###.#...
+#.####.#.#....##.#..#.#.
+##...#..#....#..#...####
+..#.##...###..#.#####..#
+....#.##.#.#####....#...
+..##.##.###.....#.##..#.
+#...#...###..####....##.
+.#.##...#.##.#.#.###...#
+#.###.#..####...##..#...
+#.###...#.##...#.##O###.
+.O##.#OO.###OO##..OOO##.
+..O#.O..O..O.#O##O##.###
+#.#..##.########..#..##.
+#.#####..#.#...##..#....
+#....##..#.#########..##
+#...#.....#..##...###.##
+#..###....##.#...##.##.#
+
+

Determine how rough the waters are in the sea monsters' habitat by counting the number of # that are not part of a sea monster. In the above example, the habitat's water roughness is 273.

+

How many # are not part of a sea monster?

+
+

Your puzzle answer was 2453.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index f6be361..40f3816 100644 --- a/stack.yaml +++ b/stack.yaml @@ -54,6 +54,7 @@ packages: - advent17 - advent18 - advent19 +- advent20 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From 6bf86d69309444f01dfe1c3c87b88766c783106e Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Fri, 1 Jan 2021 12:14:38 +0000 Subject: [PATCH 05/16] Now using foldM for creating the arrangement --- advent20/src/advent20.hs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/advent20/src/advent20.hs b/advent20/src/advent20.hs index 57a141d..01d997d 100644 --- a/advent20/src/advent20.hs +++ b/advent20/src/advent20.hs @@ -14,7 +14,7 @@ import Data.Array.Unboxed ((!)) import qualified Data.Map.Strict as M import Data.Bool (bool) import Data.List (delete) -import Control.Monad (guard) +import Control.Monad (guard, foldM) -- import Data.Either (fromRight) @@ -43,8 +43,8 @@ main = part1 rMax arrangement - = product $ M.elems - $ M.map tId + = product + $ M.elems $ M.map tId $ M.filterWithKey (isCorner rMax) arrangement part2 seaMonster image = minimum $ map (countRoughness seaMonster) transImages @@ -55,7 +55,6 @@ part2 seaMonster image = minimum $ map (countRoughness seaMonster) transImages readSeaMonster :: IO Pixels readSeaMonster = do text <- TIO.readFile "data/advent20seamonster.txt" - -- return $ fromRight (A.listArray ((0, 0), (1, 1)) []) $ parseOnly pixelsP text return $ case parseOnly pixelsP text of Left _err -> A.listArray ((0, 0), (1, 1)) [] Right seaMonster -> seaMonster @@ -67,23 +66,20 @@ isCorner l (r, 0) _ = r == l isCorner l (r, c) _ = r == l && c == l arrangeTiles :: Int -> [Tile] -> Arrangement -arrangeTiles rMax tiles = head $ arrange (0, 0) rMax M.empty tiles +arrangeTiles rMax tiles = fst $ head $ foldM arrange (M.empty, tiles) locations + where locations = init $ scanl nextLoc (0, 0) tiles + nextLoc (r, c) _ = if c == rMax then (r + 1, 0) else (r, c + 1) + -- (arrangement, _) = head $ foldM arrange (M.empty, tiles) locations -arrange :: Coord -> Int -> Arrangement -> [Tile] -> [Arrangement] --- arrange h _ g ts | trace (show h ++ " " ++ show (M.map tId g) ++ " > " ++ show (length ts)) False = undefined -arrange _ _ grid [] = return grid -arrange (r, c) cMax grid tiles = +arrange :: (Arrangement, [Tile]) -> Coord -> [(Arrangement, [Tile])] +arrange (grid, tiles) (r, c) = do tile <- tiles transTile <- transforms tile guard $ if r == 0 then True else matchVertical tileAbove transTile guard $ if c == 0 then True else matchHorizontal tileLeft transTile - arrange (r', c') - cMax - (M.insert (r, c) transTile grid) - (delete tile tiles) + return (M.insert (r, c) transTile grid, delete tile tiles) where tileAbove = grid M.! (r - 1 , c) tileLeft = grid M.! (r, c - 1) - (r', c') = if c == cMax then (r + 1, 0) else (r, c + 1) matchHorizontal tile1 tile2 = (rightBorder tile1) == (leftBorder tile2) -- 2.34.1 From c124d58aa7efa3f25f0a82993059f183e22ddd3f Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Fri, 1 Jan 2021 12:17:40 +0000 Subject: [PATCH 06/16] Tidying --- advent20/src/advent20.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/advent20/src/advent20.hs b/advent20/src/advent20.hs index 01d997d..92138c4 100644 --- a/advent20/src/advent20.hs +++ b/advent20/src/advent20.hs @@ -15,7 +15,6 @@ import qualified Data.Map.Strict as M import Data.Bool (bool) import Data.List (delete) import Control.Monad (guard, foldM) --- import Data.Either (fromRight) type Coord = (Int, Int) @@ -69,7 +68,6 @@ arrangeTiles :: Int -> [Tile] -> Arrangement arrangeTiles rMax tiles = fst $ head $ foldM arrange (M.empty, tiles) locations where locations = init $ scanl nextLoc (0, 0) tiles nextLoc (r, c) _ = if c == rMax then (r + 1, 0) else (r, c + 1) - -- (arrangement, _) = head $ foldM arrange (M.empty, tiles) locations arrange :: (Arrangement, [Tile]) -> Coord -> [(Arrangement, [Tile])] arrange (grid, tiles) (r, c) = -- 2.34.1 From fd1a5d57031cffaa3ed70935690e5cf8a4bc6061 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 3 Jan 2021 17:39:36 +0000 Subject: [PATCH 07/16] Done day 21 --- advent21/package.yaml | 62 +++++++++++++++++ advent21/src/advent21.hs | 81 ++++++++++++++++++++++ data/advent21.txt | 41 +++++++++++ data/advent21a.txt | 4 ++ problems/day21.html | 143 +++++++++++++++++++++++++++++++++++++++ stack.yaml | 1 + 6 files changed, 332 insertions(+) create mode 100644 advent21/package.yaml create mode 100644 advent21/src/advent21.hs create mode 100644 data/advent21.txt create mode 100644 data/advent21a.txt create mode 100644 problems/day21.html diff --git a/advent21/package.yaml b/advent21/package.yaml new file mode 100644 index 0000000..49b2786 --- /dev/null +++ b/advent21/package.yaml @@ -0,0 +1,62 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent21 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + +executables: + advent21: + main: advent21.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - attoparsec + - containers + - csp diff --git a/advent21/src/advent21.hs b/advent21/src/advent21.hs new file mode 100644 index 0000000..1b2f418 --- /dev/null +++ b/advent21/src/advent21.hs @@ -0,0 +1,81 @@ +-- import Debug.Trace + +-- import Data.Text (Text) +-- import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text hiding (take) +-- import Data.Attoparsec.Combinator +-- import Control.Applicative +-- import Control.Applicative.Combinators + +import qualified Data.Set as S +import qualified Data.Map.Strict as M +import Data.List +import Control.Monad.CSP + + +type Ingredient = String +type Allergen = String +data Food = Food + { ingredients :: S.Set Ingredient + , allergens :: S.Set Allergen + } deriving (Show, Eq) + +type CandidateIngredients = M.Map Allergen (S.Set Ingredient) + + + +main :: IO () +main = + do text <- TIO.readFile "data/advent21.txt" + let foods = successfulParse text + let candidates = M.unionsWith S.intersection $ map allergenMap foods + -- print candidates + print $ part1 candidates foods + putStrLn $ part2 candidates + + +part1 candidates foods = sum $ map countSafe foods + where possibleAllergens = S.unions $ M.elems candidates + countSafe food = S.size $ (ingredients food) `S.difference` possibleAllergens + +part2 candidates = intercalate "," $ map snd $ sortOn fst assignments + where assignments = knownAllergens candidates + + +allergenMap :: Food -> CandidateIngredients +allergenMap food = M.fromList $ S.toList $ S.map (, ingredients food) $ allergens food + +knownAllergens :: CandidateIngredients -> [(Allergen, Ingredient)] +knownAllergens candidates = zip allergens assignedIngredients + where + (allergens, possibleIngredients) = unzip $ M.toList candidates + assignedIngredients = solveAllergens $ map S.toList possibleIngredients + +solveAllergens :: [[Ingredient]] -> [Ingredient] +solveAllergens possibleIngredients = oneCSPSolution $ do + dvs <- mapM mkDV possibleIngredients + mapAllPairsM_ (constraint2 (/=)) dvs + return dvs + +mapAllPairsM_ :: Monad m => (a -> a -> m b) -> [a] -> m () +mapAllPairsM_ _f [] = return () +mapAllPairsM_ _f (_:[]) = return () +mapAllPairsM_ f (a:l) = mapM_ (f a) l >> mapAllPairsM_ f l + + +-- Parse the input file + +foodsP = foodP `sepBy` endOfLine +foodP = Food <$> ingredientsP <* " (contains " <*> allergensP <* ")" + +ingredientsP = S.fromList <$> (many1 letter) `sepBy` (many1 space) +allergensP = S.fromList <$> (many1 letter) `sepBy` (string ", ") + + +-- successfulParse :: Text -> (Integer, [Maybe Integer]) +successfulParse input = + case parseOnly foodsP input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right foods -> foods diff --git a/data/advent21.txt b/data/advent21.txt new file mode 100644 index 0000000..7c1175f --- /dev/null +++ b/data/advent21.txt @@ -0,0 +1,41 @@ +rhvbn qmsvv ljxg xstb kfdnn djvbx jfv vsvp jnnm fmhnz mmcpg htlcct tcdh dnbjj nsgxgt pqbqdf nlcs zjbbf rprxk lhtgpq trpsgj jgtb lpxpd jtnkgm czznp tnhxbg fvk lpdg hzdr zrb vmmzf vtvz jfzxh rjnfhjr zjtdlhx qjlnrd xpm zfxkdm dqqc ph lbmt thmn kjf cjdnjs lszkg dtgphg jkdxh tvfvbt zqtx jndhc tvmgpm jnxdf qzks (contains nuts, wheat) +jnnm dzss btfdjt lpdg dpzf jjttj xhxdcsbp qsbs ntlb xrsfms kdzfph lnjv rhvbn jkdxh vtrbv qmsvv fpxxp mrktkf ph csdm trpsgj cjdnjs thmn bbmd jnxdf pgrh kflqfz ccvrnj hcbdb cvlxbh ptzbsppb tcdh hrvcrn fvk tqkfz kjf zrb lbmt dnbjj htlcct hpzbmr czznp gggjklx vmczz dqqc kzqbp xpm nhnggd xsxqg cdxd btcz blvtr scz jztg mmcpg kfdnn chnz gjttzr zjtdlhx vncr kctgrh xstb lfd lkcdpq xntshr pqbqdf hckjb fnvhs qjblr brlnlxn xqhhzhm pmctk hnjj drtg (contains nuts, fish) +hcbdb zqtx zrb ptzbsppb lkcdpq xhxdcsbp bqsdns czznp ntlb gjxfhp kjf lpdg gglt lcmgk jgtb xvkt hnjj sft pmpzd kzqbp rhvbn szfjpqr tvmgpm fvk gggjklx pqbqdf btfdjt cmmzk xbcvfz zjrchqf dpzf brlnlxn pdhmbzv jmf qrdxd kpftvl mmcpg dqqc vhsfl jnxdf btcz bfmsp nskq hrfntmq cjdnjs zvrvcd jkdxh lsmm kflqfz fnvhs qsbs gttbj hlcpn cbsscr dgphkk (contains wheat) +hjqcsln rshbrd fjzpl hrvcrn tmcbg dtgphg hzdr dqqc vjbcvv gmgkzt qrdxd jgtb lbmt lcmgk pqbqdf zjbbf rhvbn lnjv fmhnz mmcpg dgphkk dpzf thmn pgrh hznmc zjrchqf dnbjj mtnpmq tqkfz cjdnjs fvk gtrbsg lszkg jfv tvmgpm gzlb hpzbmr scz hcjfd qvhsvb dzss hnjj xbcvfz nlcs kctgrh nhnggd ggjjh gglt czznp djvbx kjf trkmvj zrb ccvrnj pmpzd ncdkz drtg kzqbp cdxd crn ljxg pmctk dfxjkx fnvhs bfmsp btcz ntlb cftpt (contains fish, wheat, shellfish) +nlcs zqtx nhxqsg tdkg zktbh jkxhfh scz kjf ph chnz hbr zrb csdm rhvbn ntpz dzss jgtb ngmbqm blvtr drtg pmctk jfv qmsvv gjxfhp vmczz hnjj dqqc lsrbpp hcbdb krzfjbq fjzpl lbmt jfzxh dtgphg lnjv gzlb sft mmcpg jjttj (contains dairy) +qvhsvb hznmc chssff ph kjf kpftvl hcbdb hlcpn mmcpg gjxfhp btfdjt bfmsp gjttzr jztg nhxqsg htlcct vnxkjmn jkdxh lrtmj btcz hrvcrn bqsdns rhvbn fvk nsgxgt dpzf dddp zfxkdm nlcs dtgphg jgtb vsvp zrb qjlnrd cftpt lfd zvtdk vmmzf thmn zjtdlhx hckjb mfhtz jvmbjc lcmgk jndhc fnvhs lzsghj jkxhfh vhsfl (contains dairy, nuts, fish) +zrb vmczz hff jnxdf nhnggd vnxkjmn jndhc xbcvfz bfmsp xntshr pdhmbzv zjbbf plbhvfj vhsfl fzk vtrbv mfhtz ccvrnj tvmgpm hbr dddp jnnm lrtmj nsgxgt qzks lvgtf xstb kgktfrk kpftvl lkcdpq rpbddtn chssff gttbj rhvbn nskq hnjgghfl vsvp xpm dnbjj jgtb ncdkz dpfbzrv blvtr mtnpmq vmmzf lzsghj vtvz btcz tgvst hctzbr gj dpzf fzpgzs ljxg cdxd htlcct jmf krzfjbq mzsjc fvk thmn lbmt jkxhfh vznjkl bqsdns chnz hcbdb tmcbg xjjst zvrvcd ptzbsppb rshbrd kjf xqhhzhm hznmc qjblr sft nlcs dfxjkx ntlb qvhsvb xsxqg (contains shellfish, sesame) +fdxbq pgrh blvtr fpxxp mfhtz rpbddtn ttrb cftpt htlcct tcdh hnjj hrvcrn rhvbn zrb mfczrq tvfvbt vtvz hcjfd zqtx chssff vsvp pmpzd kjf jnxdf xpm cctf gggjklx mmcpg dpzf hnjgghfl thmn kzjrpl tvmgpm lbmt btcz jkdxh hlcpn jfzxh fmhnz vhsfl ccvrnj ncdkz hckjb lsrbpp xqhhzhm vznjkl ddmtvx fjzpl cbsscr cvlxbh hznmc ljxg pqbqdf kchz zvtdk mzsjc vmczz kgktfrk hcbdb hnjqd lnjv jztg mqmfbc lsmm kpftvl dpfbzrv fzpgzs zjtdlhx vnxkjmn mtxxxm djvbx jtktgz scz xsxqg gjxfhp czznp mtnpmq gjttzr cmmzk bbhxjj ph vtrbv xvkt zvrvcd dnbjj cjdnjs fvk (contains soy, dairy, fish) +rhvbn ccvrnj lcmgk gtnkm vznjkl hzdr jtnkgm ntlb zvrvcd mtxxxm blvtr vtvz lbmt hnjj xntshr qzks lpxpd dddp gkqzl djvbx krzfjbq zrb qjblr hvjql kzjrpl jgtb pgrh hctzbr mfczrq xbcvfz jnxdf hcjfd lnjv rprxk zjbbf gttbj jvmbjc zvtdk dtgphg dpfbzrv zfxkdm tgvst csdm xqhhzhm vnxkjmn fvk jfzxh mmcpg hnjqd xhxdcsbp hcbdb ph hckjb hpzbmr brlnlxn hjqcsln hnjgghfl (contains wheat, soy) +nhxqsg vjbcvv zqtx rhvbn bbhxjj tgvst kdzfph vmmzf lbmt htlcct hnjgghfl lszkg vsvp mfhtz hvjql gzlb kgktfrk qsbs qjblr fzpgzs pdtkd cmmzk bbmd jnnm jkdxh jtnkgm xpm hff qmsvv kchz xsxqg kzqbp hrvcrn hvgms fdxbq nsgxgt cftpt cctf dpzf xstb tdkg vhsfl hpzbmr dnbjj jfv szfjpqr tvmgpm kpftvl hctzbr ncdkz czznp vnxkjmn chssff fvk mmcpg fjzpl ttrb tnhxbg lfd jgtb zrb lvgtf xqhhzhm kfdnn jtktgz gjttzr lrtmj kdh djvbx kflqfz cjdnjs gglt qjlnrd jvmbjc mrktkf xjjst tmcbg kjf ngmbqm ptzbsppb jnxdf sft jmf tcdh tqkfz (contains sesame, eggs) +jfv qjlnrd krzfjbq gtnkm jgtb hbr zjbbf hrvcrn ccvrnj rprxk gjxfhp gtrbsg lbmt dnbjj fjzpl vtvz tqkfz pgrh jtnkgm hcbdb dzss bfmsp hctzbr kctgrh lpxpd kzqbp gggjklx jndhc zktbh vjbcvv dfxjkx tvmgpm ngmbqm csdm bqsdns nhnggd mtxxxm vncr zjtdlhx tgvst xstb fmhnz trpsgj djvbx vnxkjmn xqhhzhm mfhtz mtnpmq ttrb kzjrpl hrfntmq rhvbn jjttj dddp jkxhfh czznp zrb qjblr cftpt cbsscr kflqfz szfjpqr hckjb fvk mmcpg hnjqd cctf ncdkz jtktgz rpbddtn gj jvmbjc mqmfbc dpfbzrv vznjkl dgphkk mrktkf kdzfph blvtr tcdh kfdnn hznmc hnjj ntlb cvlxbh (contains soy) +ntlb cbsscr rhvbn gtrbsg bbhxjj zrb mfczrq fnvhs chnz vsvp kjf ptzbsppb qsbs lpdg scz kzjrpl xpm jgtb gjttzr zjrchqf zjbbf hcbdb vmczz drtg hnjqd xqhhzhm kgktfrk hbr jkdxh jztg zfxkdm jfzxh nskq xvkt lbmt kplm dnbjj cctf zvtdk tvmgpm hvjql hznmc fvk gggjklx vmmzf hff zjtdlhx ncdkz (contains fish) +jfzxh btfdjt hcjfd zjtdlhx lcmgk thmn ddmtvx zrb kjf mqmfbc pmctk hcbdb nlcs plbhvfj gttbj rhvbn jgtb fjzpl bbmd brlnlxn mtnpmq xrsfms hvgms chssff jmf pmpzd drtg hff kzqbp qjlnrd hrfntmq hckjb lnjv sft cctf lbmt tgvst gjttzr tvmgpm chnz kflqfz hctzbr fvk dpfbzrv tnhxbg dqqc jnnm zqtx xvkt bbhxjj rshbrd hbr vtvz htlcct (contains fish, dairy) +sft plbhvfj cdxd jztg hjqcsln hbr rshbrd ncdkz zjtdlhx tvfvbt btfdjt tqvv crn tgvst zjrchqf scz kpftvl xvkt krzfjbq jgtb tmcbg pmctk rhvbn hcbdb vnxkjmn cjdnjs vncr lbmt fzk xrsfms hvgms qsbs kjf hctzbr jnnm nskq fpxxp hrvcrn gttbj zrb nmn fvk lpxpd vtvz zjbbf gglt lrtmj lsmm jvmbjc fdxbq (contains nuts, sesame, dairy) +lpxpd lsmm kpftvl qjblr lrtmj jfzxh xstb zrb jfv rkdmz gjxfhp vmmzf ncdkz mzsjc hzdr kdzfph pmpzd xsxqg vmczz gj chnz vsvp ntlb hckjb tvfvbt fvk ddmtvx hff xvkt nhnggd mfhtz cjdnjs mmcpg rhvbn btfdjt gkqzl kgktfrk jnxdf nsgxgt gggjklx ntpz kjf tqvv tnhxbg bqsdns ph fpxxp qsbs zjtdlhx jjttj fzpgzs fdxbq tgvst vhsfl hcbdb lzsghj dpzf dgphkk zfxkdm cftpt bbmd rjnfhjr pdtkd qrdxd jgtb gzlb (contains soy, dairy, shellfish) +chssff btfdjt fzk lszkg jmf tqkfz jnnm vtvz vtrbv fmhnz fvk hrvcrn ptzbsppb xpm jfv cdxd kgktfrk gggjklx tnhxbg vznjkl qzks brlnlxn djvbx mrktkf tcdh kflqfz kctgrh gzlb cftpt hnjj hcbdb jgtb kdzfph tvmgpm gglt cjdnjs mmcpg jnxdf bqsdns tvfvbt dqqc tgvst lbmt crn zktbh trkmvj kfdnn xsxqg pmpzd scz hjqcsln lvgtf lpxpd zjtdlhx csdm krzfjbq mzsjc lsrbpp dpfbzrv fzpgzs zrb rhvbn hff xstb (contains dairy, nuts) +fmhnz mmcpg qvhsvb dpfbzrv hvjql gtrbsg mtxxxm rhvbn tvmgpm tqkfz kzqbp brlnlxn kjf tgvst rshbrd bbmd hcbdb trpsgj vznjkl dgphkk pmctk gttbj mqmfbc jjttj dzss tvfvbt zrb hlcpn kdzfph lpxpd fnvhs fvk szfjpqr hrfntmq zjrchqf thmn xjjst qvbbs bfmsp ccvrnj tqvv xstb cjdnjs kgktfrk tnhxbg qzks ph fpxxp djvbx qrdxd gjxfhp lcmgk hff htlcct xntshr tcdh qjblr qjlnrd kplm vhsfl jkdxh kchz trkmvj cvlxbh jmf rpbddtn pdtkd gj kflqfz ggjjh mzsjc nskq xqhhzhm kctgrh hctzbr fdxbq zfxkdm jnnm dddp gmgkzt tmcbg bqsdns hckjb gkqzl mrktkf lhtgpq jgtb xpm hcjfd xsxqg vjbcvv (contains shellfish, dairy, nuts) +lpdg xhxdcsbp gtnkm hpzbmr tgvst dtgphg lnjv cbsscr jtktgz dgphkk hznmc kzqbp xsxqg nskq kchz lbmt zvrvcd tvfvbt fjzpl jztg crn mrktkf jfzxh ntpz jgtb rshbrd trkmvj fvk hcbdb xbcvfz vsvp zvtdk kflqfz tvmgpm zjrchqf hnjj jkxhfh czznp qsbs rpbddtn hzdr zktbh gzlb dfxjkx lkcdpq vznjkl xstb gj plbhvfj cmmzk htlcct zrb qvhsvb mmcpg jnxdf nhnggd pdhmbzv ncdkz mzsjc zjtdlhx thmn lpxpd kjf lzsghj bfmsp hjqcsln gkqzl tcdh hckjb rprxk gmgkzt hctzbr tqkfz ccvrnj hvgms lcmgk gglt vtvz (contains soy, fish) +tmcbg pgrh gjxfhp jgtb ddmtvx dpfbzrv lnjv xpm mfhtz sft plbhvfj ncdkz gmgkzt hckjb dfxjkx lbmt qsbs rhvbn jnxdf xsxqg dpzf mrktkf jkxhfh kdzfph jnnm kdh vjbcvv kjf bfmsp dqqc lpdg ntpz fjzpl rpbddtn xjjst chssff dddp jndhc qvhsvb zrb btfdjt gtnkm hjqcsln hnjqd zvtdk vznjkl rshbrd kzjrpl brlnlxn lhtgpq vmmzf zjtdlhx fvk pqbqdf jmf hrfntmq nskq mtnpmq btcz hff jztg zktbh hnjgghfl hcbdb zjrchqf tdkg vsvp tgvst jtnkgm lzsghj djvbx blvtr fzpgzs czznp qrdxd (contains dairy, shellfish, wheat) +pgrh vsvp tdkg xntshr hzdr csdm jtnkgm qrdxd pdtkd vhsfl chssff tqvv hctzbr lfd ddmtvx tnhxbg hcbdb nsgxgt ccvrnj tcdh hjqcsln bbmd kzqbp pdhmbzv fpxxp kplm cvlxbh ttrb lsmm jjttj vmmzf jkxhfh xqhhzhm gzlb gtrbsg gttbj lbmt mzsjc fnvhs rhvbn bbhxjj kctgrh mqmfbc zrb jgtb rprxk crn mmcpg gj ntlb pmctk jkdxh kdzfph vznjkl cctf ntpz hbr hnjj mrktkf qjblr tgvst zjtdlhx xjjst fzk vmczz nskq jnxdf hckjb kjf czznp scz (contains fish, sesame) +nsgxgt hznmc jmf fmhnz btfdjt dtgphg lpxpd tqkfz ptzbsppb hnjj crn gjxfhp nskq cftpt fnvhs ntlb dpzf qsbs jgtb hzdr ddmtvx rhvbn qjblr ngmbqm nhxqsg zqtx kfdnn sft hctzbr hrfntmq dfxjkx gzlb cbsscr plbhvfj hnjgghfl zfxkdm gmgkzt lvgtf vhsfl tcdh xvkt tnhxbg qjlnrd lrtmj fpxxp xbcvfz hbr jtnkgm kjf gtnkm vmmzf kplm qmsvv tdkg pgrh chnz gggjklx cvlxbh vmczz lfd rpbddtn kzqbp mfczrq lszkg tgvst bbhxjj hcbdb lsrbpp lpdg fvk kctgrh mtxxxm szfjpqr brlnlxn hckjb jztg zrb jnnm xpm lbmt fzpgzs vjbcvv hnjqd jndhc jjttj (contains fish, wheat) +rkdmz lzsghj fzpgzs lsmm pmpzd fpxxp pqbqdf jjttj kdh mmcpg xbcvfz qrdxd fvk qjblr kjf dpfbzrv lsrbpp gtnkm trkmvj ptzbsppb hlcpn bfmsp jndhc lcmgk xpm xqhhzhm kplm ph fmhnz jgtb tnhxbg xjjst gmgkzt vmczz lpxpd jkxhfh jfzxh rpbddtn scz jtnkgm blvtr rprxk kgktfrk plbhvfj gtrbsg gttbj gkqzl zrb rhvbn hctzbr kflqfz hnjgghfl nsgxgt bbhxjj xsxqg btfdjt nhnggd tqkfz kdzfph hrfntmq ntlb lbmt tqvv tvfvbt vtrbv qmsvv qvhsvb hckjb hrvcrn tcdh xrsfms chssff pdhmbzv dpzf rjnfhjr kctgrh lkcdpq mtxxxm djvbx vhsfl zqtx gjxfhp ncdkz vznjkl gjttzr ntpz zvtdk dgphkk cdxd (contains dairy, shellfish) +lszkg chssff kdzfph drtg ntlb xhxdcsbp vsvp vncr mrktkf fmhnz lrtmj tqvv vnxkjmn fvk xstb xvkt jgtb lzsghj zjbbf hctzbr hcjfd xqhhzhm hznmc kctgrh rhvbn btfdjt jjttj jtktgz xrsfms tmcbg lsmm xpm gj lbmt tgvst sft plbhvfj zktbh hcbdb dzss fjzpl mtxxxm tdkg kpftvl zrb rpbddtn mmcpg hjqcsln (contains sesame, nuts, dairy) +lfd jgtb vnxkjmn gtnkm zqtx hvgms lszkg ggjjh dgphkk fvk lnjv tqkfz gglt krzfjbq ncdkz jfzxh rkdmz hcbdb pmpzd rjnfhjr qsbs hnjgghfl dpzf csdm crn mfczrq lrtmj sft tdkg lzsghj gzlb zrb ntpz rshbrd xbcvfz kdzfph bqsdns cvlxbh lbmt nlcs kflqfz tmcbg hznmc lvgtf scz hvjql jjttj rhvbn hbr hcjfd pgrh btcz jtnkgm jtktgz ph hrvcrn tvmgpm zjrchqf vtrbv mmcpg ntlb vncr hrfntmq fzpgzs ngmbqm thmn chnz fdxbq dfxjkx tgvst pdtkd hnjj qjlnrd jndhc (contains sesame, dairy, shellfish) +mfhtz trkmvj vhsfl zktbh mqmfbc hrfntmq vsvp ddmtvx fmhnz ngmbqm crn cmmzk rkdmz nlcs szfjpqr pqbqdf xstb mtnpmq rpbddtn cvlxbh kzqbp xqhhzhm lzsghj xsxqg fvk hcbdb pmpzd kzjrpl hlcpn qzks kdh jnxdf mmcpg jkxhfh fzpgzs djvbx lbmt cftpt dpfbzrv ljxg ntpz rprxk zqtx rjnfhjr cjdnjs lnjv lfd hckjb dgphkk jgtb qrdxd btcz gjxfhp qmsvv sft zjrchqf cctf zvtdk xvkt hrvcrn mfczrq blvtr hbr fjzpl rhvbn drtg vmmzf zrb (contains sesame, eggs, soy) +pmpzd jgtb jtktgz jvmbjc zrb gjxfhp tqkfz mmcpg vsvp pdhmbzv tgvst tdkg hpzbmr lbmt vtvz hnjj ljxg trkmvj hckjb mfczrq lcmgk vjbcvv qvhsvb cbsscr xvkt fmhnz lsrbpp hrfntmq kjf krzfjbq jndhc vtrbv xpm dgphkk jfv gtrbsg gj fvk tcdh trpsgj chnz ccvrnj nhxqsg xrsfms hlcpn rhvbn (contains sesame) +zvrvcd hrvcrn jgtb mmcpg cbsscr pgrh djvbx xhxdcsbp plbhvfj lszkg fvk szfjpqr jkdxh gtrbsg hrfntmq dpzf bfmsp jkxhfh jfv ngmbqm nsgxgt cctf kjf crn dpfbzrv hvgms jtnkgm gmgkzt nmn mfczrq ddmtvx trpsgj xntshr xvkt bbhxjj xstb dqqc qzks ph jvmbjc mtnpmq mqmfbc jmf hctzbr brlnlxn hpzbmr kdh hcjfd mrktkf gtnkm nlcs kchz rhvbn zjtdlhx fzk czznp zrb xsxqg kzjrpl htlcct sft hcbdb qjblr pqbqdf hzdr kflqfz kgktfrk vsvp cmmzk rjnfhjr dfxjkx xpm cftpt tqvv nhxqsg (contains eggs, shellfish) +hbr tqkfz lsmm gkqzl jtnkgm tvfvbt plbhvfj kzjrpl rkdmz zrb hjqcsln gggjklx nhnggd zvtdk kchz lcmgk hnjj tgvst gmgkzt vsvp pmctk fvk jtktgz xpm hvgms ntpz vmczz zjrchqf hvjql nhxqsg mmcpg tdkg dqqc zjbbf gjttzr crn gzlb mzsjc zqtx rhvbn dgphkk hnjqd hzdr dpfbzrv trpsgj kpftvl czznp mfhtz zktbh dddp mtxxxm lbmt jvmbjc qvhsvb xqhhzhm fjzpl xntshr vznjkl rjnfhjr fmhnz htlcct qrdxd nlcs gjxfhp qvbbs hrfntmq lfd nskq tnhxbg pgrh gtrbsg hff pdhmbzv ph fdxbq jgtb vmmzf cftpt kjf hcjfd (contains nuts, fish) +dddp ptzbsppb ljxg vjbcvv djvbx mfczrq hbr gzlb btcz gggjklx vhsfl kzqbp pgrh thmn gtrbsg jfv hpzbmr fvk csdm ccvrnj gkqzl tqkfz mtxxxm dzss bbhxjj lpxpd qvhsvb rkdmz pdhmbzv hcjfd vmczz hrvcrn jvmbjc kdzfph zvrvcd mqmfbc hcbdb zrb tqvv lsrbpp trpsgj lbmt gglt kdh szfjpqr drtg xvkt zjtdlhx czznp mmcpg kfdnn rshbrd nhxqsg brlnlxn ntpz kpftvl sft cdxd kjf fzk tnhxbg jztg fjzpl dtgphg vtvz jgtb hvgms (contains sesame) +jgtb hcbdb vnxkjmn ph pgrh zjtdlhx xntshr tvfvbt xjjst mmcpg hjqcsln xsxqg jmf brlnlxn jnxdf cjdnjs hctzbr hzdr ljxg ptzbsppb jndhc kchz ngmbqm krzfjbq fzpgzs mtxxxm kfdnn fmhnz bqsdns crn ntlb rhvbn qvbbs zvtdk plbhvfj fdxbq zjrchqf jfv szfjpqr kzqbp ddmtvx vmczz cmmzk fvk thmn qvhsvb nskq lpxpd hlcpn cbsscr fnvhs lbmt kjf zfxkdm xpm qzks rpbddtn tdkg gglt chssff gjttzr dpzf trpsgj lsmm mqmfbc (contains eggs, nuts, dairy) +xqhhzhm nlcs jgtb blvtr zfxkdm hvjql hff kflqfz jnxdf ntpz lkcdpq qsbs qvhsvb mfhtz kfdnn zrb gtrbsg lhtgpq tqkfz lbmt bbmd dgphkk vhsfl cftpt qrdxd pmctk jmf kpftvl qzks zjrchqf kzqbp kzjrpl crn qvbbs cmmzk rhvbn fmhnz dzss kjf vmczz hrfntmq pmpzd mmcpg pqbqdf lpxpd tdkg ph xntshr rpbddtn fvk zqtx vtrbv vjbcvv tgvst xhxdcsbp thmn vmmzf (contains wheat, eggs, fish) +kpftvl bfmsp kflqfz xhxdcsbp brlnlxn jfv gmgkzt xntshr hvjql hlcpn zjtdlhx kdh lbmt xvkt ccvrnj djvbx gkqzl cftpt pdtkd hcbdb fdxbq lpxpd cctf ljxg vmmzf cmmzk jkxhfh fvk tmcbg bbmd pmctk hnjj rshbrd jkdxh zjrchqf fzk lfd ntpz mmcpg lsrbpp vnxkjmn qsbs htlcct hff xbcvfz dpzf lnjv qvhsvb gttbj tnhxbg mtxxxm dzss mfhtz hnjqd ttrb xqhhzhm zqtx jnxdf hpzbmr jgtb kjf zrb qvbbs lsmm tqkfz tvfvbt dtgphg jtnkgm hjqcsln cvlxbh dddp dpfbzrv kzjrpl (contains soy, shellfish) +lcmgk ccvrnj hcbdb ttrb nmn lpxpd qmsvv xntshr zrb zjrchqf mtxxxm hcjfd trkmvj bfmsp zvtdk dtgphg fvk tqkfz lnjv scz xrsfms tmcbg kdh pqbqdf vtvz hznmc htlcct nskq tdkg lhtgpq vncr kjf tgvst cmmzk hnjj dnbjj bbhxjj xqhhzhm tcdh jgtb fdxbq jkxhfh ph qsbs tqvv lbmt kfdnn kchz tvmgpm jztg ntpz pdtkd ntlb hvjql hctzbr ljxg hff zktbh rhvbn hnjqd vtrbv gkqzl nsgxgt kplm cctf dpzf djvbx nlcs (contains shellfish, wheat, dairy) +thmn nlcs hpzbmr hvgms vncr cbsscr btcz pmpzd rpbddtn hzdr gmgkzt csdm rhvbn zvtdk lsmm lcmgk gjttzr blvtr gjxfhp fvk cctf lrtmj bfmsp dpfbzrv dgphkk kjf pqbqdf tqkfz btfdjt mmcpg tnhxbg zktbh hnjj zfxkdm tvmgpm jndhc kzqbp plbhvfj gzlb fzk lnjv scz ttrb xstb zqtx hcbdb pdtkd kdh jkdxh vhsfl jjttj jnxdf dddp vznjkl zrb lbmt gtrbsg fpxxp krzfjbq qjblr lzsghj kpftvl xvkt dnbjj jztg (contains wheat, soy, fish) +kflqfz vtrbv bbhxjj cbsscr tnhxbg tqvv jkxhfh chssff fnvhs zjtdlhx hnjj gtnkm hvgms dqqc dgphkk cftpt tvfvbt jfv lsrbpp lbmt lvgtf fpxxp bbmd mmcpg lpdg xhxdcsbp lhtgpq jndhc trkmvj qvbbs pgrh hckjb jmf htlcct zfxkdm gj nhxqsg mtxxxm dzss lrtmj xvkt xsxqg vncr hvjql xbcvfz fdxbq xstb zvtdk hcbdb qzks dtgphg jgtb gtrbsg rhvbn mzsjc rprxk kfdnn djvbx ljxg hzdr pdtkd hnjqd qmsvv mfhtz xpm qrdxd jtktgz jtnkgm brlnlxn kjf xrsfms fvk czznp ngmbqm kplm (contains soy, nuts, shellfish) +xjjst fvk hnjqd trkmvj ntlb ntpz lsmm bfmsp hznmc mrktkf tdkg jjttj kgktfrk vznjkl gglt lrtmj ggjjh dqqc hrfntmq dzss cvlxbh dpfbzrv zjtdlhx bbmd rhvbn ttrb gggjklx rpbddtn jkxhfh lszkg hlcpn cctf ptzbsppb kpftvl tmcbg dddp zqtx gtrbsg mmcpg vmczz pdtkd ljxg cjdnjs plbhvfj kfdnn vnxkjmn ngmbqm pqbqdf kflqfz lcmgk dpzf pmpzd hbr lpxpd qjblr gtnkm mzsjc ph qrdxd jgtb lbmt gkqzl qvhsvb zvtdk qsbs nhnggd zrb lhtgpq chssff hckjb djvbx kdh cmmzk hzdr lvgtf kjf rkdmz bbhxjj qjlnrd lnjv xbcvfz jmf xntshr tcdh jvmbjc btcz fpxxp lfd (contains sesame, wheat) +tqvv nsgxgt kjf lsrbpp zrb vncr dqqc qzks vmmzf dpzf hcjfd lszkg lzsghj rjnfhjr hznmc fvk djvbx chssff kfdnn zjbbf mmcpg vznjkl kpftvl vsvp xvkt kplm mqmfbc qmsvv gtrbsg pmctk xrsfms jfzxh hzdr hrvcrn crn xhxdcsbp xqhhzhm zjrchqf ptzbsppb xpm pmpzd hcbdb mrktkf kzqbp cdxd gjxfhp vtvz mfhtz jgtb mzsjc dfxjkx lbmt nskq jjttj jtktgz qsbs ddmtvx (contains soy, shellfish) +hnjj qsbs cdxd mfczrq dddp qmsvv kdzfph qjblr gjxfhp zfxkdm crn zjtdlhx dnbjj kjf jkdxh jztg lhtgpq lzsghj lcmgk htlcct qvhsvb ggjjh fzpgzs gmgkzt vmczz btcz qjlnrd cftpt rkdmz jnnm mrktkf lkcdpq hlcpn xbcvfz tqkfz tvmgpm rprxk hckjb dpzf drtg jtnkgm xrsfms qvbbs lsrbpp xsxqg hff czznp ddmtvx btfdjt cvlxbh lrtmj mmcpg xstb vtrbv fvk csdm xjjst rhvbn hpzbmr xntshr tvfvbt xvkt xqhhzhm rjnfhjr lbmt dpfbzrv gj hcbdb tqvv dqqc kchz dzss zqtx hrvcrn nsgxgt zrb kzjrpl cjdnjs vtvz nskq dfxjkx hvgms (contains fish, sesame) +hbr dpfbzrv kgktfrk tcdh trkmvj plbhvfj hcbdb lpdg kdzfph ttrb pdhmbzv tvfvbt mtnpmq zqtx kjf qjlnrd xntshr fmhnz cjdnjs dqqc dddp ptzbsppb hrvcrn lzsghj lfd vhsfl lsrbpp kpftvl rkdmz mmcpg mzsjc lpxpd rshbrd lnjv ngmbqm zjtdlhx xstb rpbddtn nskq lsmm tgvst mfczrq lkcdpq fvk mqmfbc ccvrnj gttbj lszkg gj dtgphg lcmgk drtg qsbs rhvbn pmctk zvtdk qmsvv pdtkd jnnm cctf kdh ddmtvx kplm trpsgj pmpzd nsgxgt ljxg zrb zjrchqf hnjqd ggjjh kchz hff jvmbjc tdkg dgphkk hctzbr fnvhs gtnkm fpxxp hjqcsln jfv hvgms tqkfz fzk jgtb (contains eggs) +gtrbsg vmczz vmmzf ddmtvx zvtdk zjbbf drtg dddp vjbcvv fnvhs chnz pqbqdf dfxjkx hctzbr jkxhfh jztg ljxg rprxk fvk qzks nhnggd mmcpg csdm xqhhzhm tvfvbt zrb xsxqg kfdnn zjrchqf hnjj jkdxh ngmbqm lrtmj jgtb kzjrpl cvlxbh dtgphg hnjgghfl vtrbv jtktgz ttrb hff rhvbn fzk jndhc dzss tdkg hcbdb lbmt ptzbsppb (contains dairy) +rjnfhjr cbsscr vtrbv kzqbp ttrb vmmzf vsvp blvtr dfxjkx nlcs chnz kpftvl lbmt htlcct rhvbn kflqfz gjxfhp ptzbsppb tmcbg tnhxbg mtnpmq lhtgpq dnbjj fzk lszkg kdzfph cvlxbh hpzbmr mmcpg djvbx jgtb krzfjbq kjf xpm fvk brlnlxn mfhtz vjbcvv qjlnrd ljxg kzjrpl jndhc qjblr jztg gggjklx nskq rprxk fmhnz mzsjc xntshr hckjb ccvrnj lrtmj vmczz trkmvj nhxqsg zvrvcd bfmsp btfdjt zrb tcdh zjbbf hvgms mrktkf chssff dqqc fpxxp rshbrd szfjpqr plbhvfj ntlb drtg hzdr qmsvv gkqzl (contains nuts) \ No newline at end of file diff --git a/data/advent21a.txt b/data/advent21a.txt new file mode 100644 index 0000000..6940ed2 --- /dev/null +++ b/data/advent21a.txt @@ -0,0 +1,4 @@ +mxmxvkd kfcds sqjhc nhms (contains dairy, fish) +trh fvjkl sbzzf mxmxvkd (contains dairy) +sqjhc fvjkl (contains soy) +sqjhc mxmxvkd sbzzf (contains fish) \ No newline at end of file diff --git a/problems/day21.html b/problems/day21.html new file mode 100644 index 0000000..dd0921e --- /dev/null +++ b/problems/day21.html @@ -0,0 +1,143 @@ + + + + +Day 21 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 21: Allergen Assessment ---

You reach the train's last stop and the closest you can get to your vacation island without getting wet. There aren't even any boats here, but nothing can stop you now: you build a raft. You just need a few days' worth of food for your journey.

+

You don't speak the local language, so you can't read any ingredients lists. However, sometimes, allergens are listed in a language you do understand. You should be able to use this information to determine which ingredient contains which allergen and work out which foods are safe to take with you on your trip.

+

You start by compiling a list of foods (your puzzle input), one food per line. Each line includes that food's ingredients list followed by some or all of the allergens the food contains.

+

Each allergen is found in exactly one ingredient. Each ingredient contains zero or one allergen. Allergens aren't always marked; when they're listed (as in (contains nuts, shellfish) after an ingredients list), the ingredient that contains each listed allergen will be somewhere in the corresponding ingredients list. However, even if an allergen isn't listed, the ingredient that contains that allergen could still be present: maybe they forgot to label it, or maybe it was labeled in a language you don't know.

+

For example, consider the following list of foods:

+
mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
+trh fvjkl sbzzf mxmxvkd (contains dairy)
+sqjhc fvjkl (contains soy)
+sqjhc mxmxvkd sbzzf (contains fish)
+
+

The first food in the list has four ingredients (written in a language you don't understand): mxmxvkd, kfcds, sqjhc, and nhms. While the food might contain other allergens, a few allergens the food definitely contains are listed afterward: dairy and fish.

+

The first step is to determine which ingredients can't possibly contain any of the allergens in any food in your list. In the above example, none of the ingredients kfcds, nhms, sbzzf, or trh can contain an allergen. Counting the number of times any of these ingredients appear in any ingredients list produces 5: they all appear once each except sbzzf, which appears twice.

+

Determine which ingredients cannot possibly contain any of the allergens in your list. How many times do any of those ingredients appear?

+
+

Your puzzle answer was 2517.

--- Part Two ---

Now that you've isolated the inert ingredients, you should have enough information to figure out which ingredient contains which allergen.

+

In the above example:

+
    +
  • mxmxvkd contains dairy.
  • +
  • sqjhc contains fish.
  • +
  • fvjkl contains soy.
  • +
+

Arrange the ingredients alphabetically by their allergen and separate them by commas to produce your canonical dangerous ingredient list. (There should not be any spaces in your canonical dangerous ingredient list.) In the above example, this would be mxmxvkd,sqjhc,fvjkl.

+

Time to stock your raft with supplies. What is your canonical dangerous ingredient list?

+
+

Your puzzle answer was rhvbn,mmcpg,kjf,fvk,lbmt,jgtb,hcbdb,zrb.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 40f3816..49a90a7 100644 --- a/stack.yaml +++ b/stack.yaml @@ -55,6 +55,7 @@ packages: - advent18 - advent19 - advent20 +- advent21 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From 7168e2f5a5c7cbdd65eabe3120bca10e9a383438 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Mon, 4 Jan 2021 23:05:24 +0000 Subject: [PATCH 08/16] Done day 22 --- advent22/package.yaml | 61 +++++ advent22/src/advent22.hs | 92 ++++++++ data/advent22.txt | 53 +++++ data/advent22a.txt | 13 ++ problems/day22.html | 478 +++++++++++++++++++++++++++++++++++++++ stack.yaml | 1 + 6 files changed, 698 insertions(+) create mode 100644 advent22/package.yaml create mode 100644 advent22/src/advent22.hs create mode 100644 data/advent22.txt create mode 100644 data/advent22a.txt create mode 100644 problems/day22.html diff --git a/advent22/package.yaml b/advent22/package.yaml new file mode 100644 index 0000000..fcd8854 --- /dev/null +++ b/advent22/package.yaml @@ -0,0 +1,61 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent22 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + +executables: + advent22: + main: advent22.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - attoparsec + - containers diff --git a/advent22/src/advent22.hs b/advent22/src/advent22.hs new file mode 100644 index 0000000..96ec70b --- /dev/null +++ b/advent22/src/advent22.hs @@ -0,0 +1,92 @@ +-- import Debug.Trace + +import Data.Text (Text) +-- import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text hiding (take) +-- import Data.Attoparsec.Combinator +import Control.Applicative +-- import Control.Applicative.Combinators + +import qualified Data.Set as S +import qualified Data.Sequence as Q +import Data.Sequence (Seq (Empty, (:<|), (:|>)), (<|), (|>)) + +type Deck = Q.Seq Int +type Game = (Deck, Deck) + +data Player = P1 | P2 deriving (Show, Eq) + + +main :: IO () +main = + do text <- TIO.readFile "data/advent22.txt" + let decks = successfulParse text + print decks + print $ play decks + print $ part1 decks + print $ part2 decks + +part1 decks = score $ winningDeck $ play decks +part2 decks = score $ snd $ playRecursive decks S.empty + +play = until finished playRound + +finished :: Game -> Bool +finished (Empty, _) = True +finished (_, Empty) = True +finished (_, _) = False + +playRound :: Game -> Game +playRound ((x :<| xs), (y :<| ys)) + | x < y = (xs, ys |> y |> x) + | otherwise = (xs |> x |> y, ys) + +winningDeck game = case (winner game) of + P1 -> fst game + P2 -> snd game + +winner :: Game -> Player +winner (Empty, ys) = P2 +winner (xs, _) = P1 + +score :: Deck -> Int +score = Q.foldrWithIndex (\i c s -> s + (i + 1) * c) 0 . Q.reverse + + +playRecursive :: Game -> (S.Set Game) -> (Player, Deck) +playRecursive (Empty, ys) _ = (P2, ys) +playRecursive (xs, Empty) _ = (P1, xs) +playRecursive g@(x :<| xs, y :<| ys) seen + | g `S.member` seen = (P1, x :<| xs) + | (lengthAtLeast x xs) && (lengthAtLeast y ys) = playRecursive subG seen' + | otherwise = playRecursive compareG seen' + where seen' = S.insert g seen + (subWinner, _) = playRecursive (Q.take x xs, Q.take y ys) seen' + subG = updateDecks subWinner g + compareWinner = if x < y then P2 else P1 + compareG = updateDecks compareWinner g + + +updateDecks P1 (x :<| xs, y :<| ys) = (xs |> x |> y, ys) +updateDecks P2 (x :<| xs, y :<| ys) = (xs, ys |> y |> x) + +lengthAtLeast n s = Q.length s >= n + + + + +-- Parse the input file + +decksP = (,) <$> deckP <* (many endOfLine) <*> deckP + +headerP = string "Player " *> decimal *> ":" *> endOfLine + +deckP = Q.fromList <$> (headerP *> (decimal `sepBy` endOfLine)) + +successfulParse :: Text -> Game +successfulParse input = + case parseOnly decksP input of + Left _err -> (Q.empty, Q.empty) -- TIO.putStr $ T.pack $ parseErrorPretty err + Right decks -> decks diff --git a/data/advent22.txt b/data/advent22.txt new file mode 100644 index 0000000..bdf290e --- /dev/null +++ b/data/advent22.txt @@ -0,0 +1,53 @@ +Player 1: +43 +21 +2 +20 +36 +31 +32 +37 +38 +26 +48 +47 +17 +16 +42 +12 +45 +19 +23 +14 +50 +44 +29 +34 +1 + +Player 2: +40 +24 +49 +10 +22 +35 +28 +46 +7 +41 +15 +5 +39 +33 +11 +8 +3 +18 +4 +13 +6 +25 +30 +27 +9 \ No newline at end of file diff --git a/data/advent22a.txt b/data/advent22a.txt new file mode 100644 index 0000000..391cd24 --- /dev/null +++ b/data/advent22a.txt @@ -0,0 +1,13 @@ +Player 1: +9 +2 +6 +3 +1 + +Player 2: +5 +8 +4 +7 +10 diff --git a/problems/day22.html b/problems/day22.html new file mode 100644 index 0000000..cec5a5a --- /dev/null +++ b/problems/day22.html @@ -0,0 +1,478 @@ + + + + +Day 22 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 22: Crab Combat ---

It only takes a few hours of sailing the ocean on a raft for boredom to sink in. Fortunately, you brought a small deck of space cards! You'd like to play a game of Combat, and there's even an opponent available: a small crab that climbed aboard your raft before you left.

+

Fortunately, it doesn't take long to teach the crab the rules.

+

Before the game starts, split the cards so each player has their own deck (your puzzle input). Then, the game consists of a series of rounds: both players draw their top card, and the player with the higher-valued card wins the round. The winner keeps both cards, placing them on the bottom of their own deck so that the winner's card is above the other card. If this causes a player to have all of the cards, they win, and the game ends.

+

For example, consider the following starting decks:

+
Player 1:
+9
+2
+6
+3
+1
+
+Player 2:
+5
+8
+4
+7
+10
+
+

This arrangement means that player 1's deck contains 5 cards, with 9 on top and 1 on the bottom; player 2's deck also contains 5 cards, with 5 on top and 10 on the bottom.

+

The first round begins with both players drawing the top card of their decks: 9 and 5. Player 1 has the higher card, so both cards move to the bottom of player 1's deck such that 9 is above 5. In total, it takes 29 rounds before a player has all of the cards:

+
-- Round 1 --
+Player 1's deck: 9, 2, 6, 3, 1
+Player 2's deck: 5, 8, 4, 7, 10
+Player 1 plays: 9
+Player 2 plays: 5
+Player 1 wins the round!
+
+-- Round 2 --
+Player 1's deck: 2, 6, 3, 1, 9, 5
+Player 2's deck: 8, 4, 7, 10
+Player 1 plays: 2
+Player 2 plays: 8
+Player 2 wins the round!
+
+-- Round 3 --
+Player 1's deck: 6, 3, 1, 9, 5
+Player 2's deck: 4, 7, 10, 8, 2
+Player 1 plays: 6
+Player 2 plays: 4
+Player 1 wins the round!
+
+-- Round 4 --
+Player 1's deck: 3, 1, 9, 5, 6, 4
+Player 2's deck: 7, 10, 8, 2
+Player 1 plays: 3
+Player 2 plays: 7
+Player 2 wins the round!
+
+-- Round 5 --
+Player 1's deck: 1, 9, 5, 6, 4
+Player 2's deck: 10, 8, 2, 7, 3
+Player 1 plays: 1
+Player 2 plays: 10
+Player 2 wins the round!
+
+...several more rounds pass...
+
+-- Round 27 --
+Player 1's deck: 5, 4, 1
+Player 2's deck: 8, 9, 7, 3, 2, 10, 6
+Player 1 plays: 5
+Player 2 plays: 8
+Player 2 wins the round!
+
+-- Round 28 --
+Player 1's deck: 4, 1
+Player 2's deck: 9, 7, 3, 2, 10, 6, 8, 5
+Player 1 plays: 4
+Player 2 plays: 9
+Player 2 wins the round!
+
+-- Round 29 --
+Player 1's deck: 1
+Player 2's deck: 7, 3, 2, 10, 6, 8, 5, 9, 4
+Player 1 plays: 1
+Player 2 plays: 7
+Player 2 wins the round!
+
+
+== Post-game results ==
+Player 1's deck: 
+Player 2's deck: 3, 2, 10, 6, 8, 5, 9, 4, 7, 1
+
+

Once the game ends, you can calculate the winning player's score. The bottom card in their deck is worth the value of the card multiplied by 1, the second-from-the-bottom card is worth the value of the card multiplied by 2, and so on. With 10 cards, the top card is worth the value on the card multiplied by 10. In this example, the winning player's score is:

+
   3 * 10
++  2 *  9
++ 10 *  8
++  6 *  7
++  8 *  6
++  5 *  5
++  9 *  4
++  4 *  3
++  7 *  2
++  1 *  1
+= 306
+
+

So, once the game ends, the winning player's score is 306.

+

Play the small crab in a game of Combat using the two decks you just dealt. What is the winning player's score?

+
+

Your puzzle answer was 33925.

--- Part Two ---

You lost to the small crab! Fortunately, crabs aren't very good at recursion. To defend your honor as a Raft Captain, you challenge the small crab to a game of Recursive Combat.

+

Recursive Combat still starts by splitting the cards into two decks (you offer to play with the same starting decks as before - it's only fair). Then, the game consists of a series of rounds with a few changes:

+
    +
  • Before either player deals a card, if there was a previous round in this game that had exactly the same cards in the same order in the same players' decks, the game instantly ends in a win for player 1. Previous rounds from other games are not considered. (This prevents infinite games of Recursive Combat, which everyone agrees is a bad idea.)
  • +
  • Otherwise, this round's cards must be in a new configuration; the players begin the round by each drawing the top card of their deck as normal.
  • +
  • If both players have at least as many cards remaining in their deck as the value of the card they just drew, the winner of the round is determined by playing a new game of Recursive Combat (see below).
  • +
  • Otherwise, at least one player must not have enough cards left in their deck to recurse; the winner of the round is the player with the higher-value card.
  • +
+

As in regular Combat, the winner of the round (even if they won the round by winning a sub-game) takes the two cards dealt at the beginning of the round and places them on the bottom of their own deck (again so that the winner's card is above the other card). Note that the winner's card might be the lower-valued of the two cards if they won the round due to winning a sub-game. If collecting cards by winning the round causes a player to have all of the cards, they win, and the game ends.

+

Here is an example of a small game that would loop forever without the infinite game prevention rule:

+
Player 1:
+43
+19
+
+Player 2:
+2
+29
+14
+
+

During a round of Recursive Combat, if both players have at least as many cards in their own decks as the number on the card they just dealt, the winner of the round is determined by recursing into a sub-game of Recursive Combat. (For example, if player 1 draws the 3 card, and player 2 draws the 7 card, this would occur if player 1 has at least 3 cards left and player 2 has at least 7 cards left, not counting the 3 and 7 cards that were drawn.)

+

To play a sub-game of Recursive Combat, each player creates a new deck by making a copy of the next cards in their deck (the quantity of cards copied is equal to the number on the card they drew to trigger the sub-game). During this sub-game, the game that triggered it is on hold and completely unaffected; no cards are removed from players' decks to form the sub-game. (For example, if player 1 drew the 3 card, their deck in the sub-game would be copies of the next three cards in their deck.)

+

Here is a complete example of gameplay, where Game 1 is the primary game of Recursive Combat:

+
=== Game 1 ===
+
+-- Round 1 (Game 1) --
+Player 1's deck: 9, 2, 6, 3, 1
+Player 2's deck: 5, 8, 4, 7, 10
+Player 1 plays: 9
+Player 2 plays: 5
+Player 1 wins round 1 of game 1!
+
+-- Round 2 (Game 1) --
+Player 1's deck: 2, 6, 3, 1, 9, 5
+Player 2's deck: 8, 4, 7, 10
+Player 1 plays: 2
+Player 2 plays: 8
+Player 2 wins round 2 of game 1!
+
+-- Round 3 (Game 1) --
+Player 1's deck: 6, 3, 1, 9, 5
+Player 2's deck: 4, 7, 10, 8, 2
+Player 1 plays: 6
+Player 2 plays: 4
+Player 1 wins round 3 of game 1!
+
+-- Round 4 (Game 1) --
+Player 1's deck: 3, 1, 9, 5, 6, 4
+Player 2's deck: 7, 10, 8, 2
+Player 1 plays: 3
+Player 2 plays: 7
+Player 2 wins round 4 of game 1!
+
+-- Round 5 (Game 1) --
+Player 1's deck: 1, 9, 5, 6, 4
+Player 2's deck: 10, 8, 2, 7, 3
+Player 1 plays: 1
+Player 2 plays: 10
+Player 2 wins round 5 of game 1!
+
+-- Round 6 (Game 1) --
+Player 1's deck: 9, 5, 6, 4
+Player 2's deck: 8, 2, 7, 3, 10, 1
+Player 1 plays: 9
+Player 2 plays: 8
+Player 1 wins round 6 of game 1!
+
+-- Round 7 (Game 1) --
+Player 1's deck: 5, 6, 4, 9, 8
+Player 2's deck: 2, 7, 3, 10, 1
+Player 1 plays: 5
+Player 2 plays: 2
+Player 1 wins round 7 of game 1!
+
+-- Round 8 (Game 1) --
+Player 1's deck: 6, 4, 9, 8, 5, 2
+Player 2's deck: 7, 3, 10, 1
+Player 1 plays: 6
+Player 2 plays: 7
+Player 2 wins round 8 of game 1!
+
+-- Round 9 (Game 1) --
+Player 1's deck: 4, 9, 8, 5, 2
+Player 2's deck: 3, 10, 1, 7, 6
+Player 1 plays: 4
+Player 2 plays: 3
+Playing a sub-game to determine the winner...
+
+=== Game 2 ===
+
+-- Round 1 (Game 2) --
+Player 1's deck: 9, 8, 5, 2
+Player 2's deck: 10, 1, 7
+Player 1 plays: 9
+Player 2 plays: 10
+Player 2 wins round 1 of game 2!
+
+-- Round 2 (Game 2) --
+Player 1's deck: 8, 5, 2
+Player 2's deck: 1, 7, 10, 9
+Player 1 plays: 8
+Player 2 plays: 1
+Player 1 wins round 2 of game 2!
+
+-- Round 3 (Game 2) --
+Player 1's deck: 5, 2, 8, 1
+Player 2's deck: 7, 10, 9
+Player 1 plays: 5
+Player 2 plays: 7
+Player 2 wins round 3 of game 2!
+
+-- Round 4 (Game 2) --
+Player 1's deck: 2, 8, 1
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 2
+Player 2 plays: 10
+Player 2 wins round 4 of game 2!
+
+-- Round 5 (Game 2) --
+Player 1's deck: 8, 1
+Player 2's deck: 9, 7, 5, 10, 2
+Player 1 plays: 8
+Player 2 plays: 9
+Player 2 wins round 5 of game 2!
+
+-- Round 6 (Game 2) --
+Player 1's deck: 1
+Player 2's deck: 7, 5, 10, 2, 9, 8
+Player 1 plays: 1
+Player 2 plays: 7
+Player 2 wins round 6 of game 2!
+The winner of game 2 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 9 of game 1!
+
+-- Round 10 (Game 1) --
+Player 1's deck: 9, 8, 5, 2
+Player 2's deck: 10, 1, 7, 6, 3, 4
+Player 1 plays: 9
+Player 2 plays: 10
+Player 2 wins round 10 of game 1!
+
+-- Round 11 (Game 1) --
+Player 1's deck: 8, 5, 2
+Player 2's deck: 1, 7, 6, 3, 4, 10, 9
+Player 1 plays: 8
+Player 2 plays: 1
+Player 1 wins round 11 of game 1!
+
+-- Round 12 (Game 1) --
+Player 1's deck: 5, 2, 8, 1
+Player 2's deck: 7, 6, 3, 4, 10, 9
+Player 1 plays: 5
+Player 2 plays: 7
+Player 2 wins round 12 of game 1!
+
+-- Round 13 (Game 1) --
+Player 1's deck: 2, 8, 1
+Player 2's deck: 6, 3, 4, 10, 9, 7, 5
+Player 1 plays: 2
+Player 2 plays: 6
+Playing a sub-game to determine the winner...
+
+=== Game 3 ===
+
+-- Round 1 (Game 3) --
+Player 1's deck: 8, 1
+Player 2's deck: 3, 4, 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 3
+Player 1 wins round 1 of game 3!
+
+-- Round 2 (Game 3) --
+Player 1's deck: 1, 8, 3
+Player 2's deck: 4, 10, 9, 7, 5
+Player 1 plays: 1
+Player 2 plays: 4
+Playing a sub-game to determine the winner...
+
+=== Game 4 ===
+
+-- Round 1 (Game 4) --
+Player 1's deck: 8
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 1 of game 4!
+The winner of game 4 is player 2!
+
+...anyway, back to game 3.
+Player 2 wins round 2 of game 3!
+
+-- Round 3 (Game 3) --
+Player 1's deck: 8, 3
+Player 2's deck: 10, 9, 7, 5, 4, 1
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 3 of game 3!
+
+-- Round 4 (Game 3) --
+Player 1's deck: 3
+Player 2's deck: 9, 7, 5, 4, 1, 10, 8
+Player 1 plays: 3
+Player 2 plays: 9
+Player 2 wins round 4 of game 3!
+The winner of game 3 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 13 of game 1!
+
+-- Round 14 (Game 1) --
+Player 1's deck: 8, 1
+Player 2's deck: 3, 4, 10, 9, 7, 5, 6, 2
+Player 1 plays: 8
+Player 2 plays: 3
+Player 1 wins round 14 of game 1!
+
+-- Round 15 (Game 1) --
+Player 1's deck: 1, 8, 3
+Player 2's deck: 4, 10, 9, 7, 5, 6, 2
+Player 1 plays: 1
+Player 2 plays: 4
+Playing a sub-game to determine the winner...
+
+=== Game 5 ===
+
+-- Round 1 (Game 5) --
+Player 1's deck: 8
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 1 of game 5!
+The winner of game 5 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 15 of game 1!
+
+-- Round 16 (Game 1) --
+Player 1's deck: 8, 3
+Player 2's deck: 10, 9, 7, 5, 6, 2, 4, 1
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 16 of game 1!
+
+-- Round 17 (Game 1) --
+Player 1's deck: 3
+Player 2's deck: 9, 7, 5, 6, 2, 4, 1, 10, 8
+Player 1 plays: 3
+Player 2 plays: 9
+Player 2 wins round 17 of game 1!
+The winner of game 1 is player 2!
+
+
+== Post-game results ==
+Player 1's deck: 
+Player 2's deck: 7, 5, 6, 2, 4, 1, 10, 8, 9, 3
+
+

After the game, the winning player's score is calculated from the cards they have in their original deck using the same rules as regular Combat. In the above game, the winning player's score is 291.

+

Defend your honor as Raft Captain by playing the small crab in a game of Recursive Combat using the same two decks as before. What is the winning player's score?

+
+

Your puzzle answer was 33441.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 49a90a7..86013c9 100644 --- a/stack.yaml +++ b/stack.yaml @@ -56,6 +56,7 @@ packages: - advent19 - advent20 - advent21 +- advent22 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From facb3213b69e61e75fbde2abcb1c4ba11297f2c9 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 5 Jan 2021 11:19:13 +0000 Subject: [PATCH 09/16] Now with hashes to speed up duplicate game detection --- advent22/package.yaml | 1 + advent22/src/advent22.hs | 45 +++++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/advent22/package.yaml b/advent22/package.yaml index fcd8854..e0d40a8 100644 --- a/advent22/package.yaml +++ b/advent22/package.yaml @@ -59,3 +59,4 @@ executables: - text - attoparsec - containers + - hashable diff --git a/advent22/src/advent22.hs b/advent22/src/advent22.hs index 96ec70b..ac5162d 100644 --- a/advent22/src/advent22.hs +++ b/advent22/src/advent22.hs @@ -10,26 +10,33 @@ import Control.Applicative -- import Control.Applicative.Combinators import qualified Data.Set as S +import qualified Data.IntMap.Strict as M import qualified Data.Sequence as Q import Data.Sequence (Seq (Empty, (:<|), (:|>)), (<|), (|>)) +import Data.Foldable (toList) +import Data.Hashable (hash) + + type Deck = Q.Seq Int type Game = (Deck, Deck) data Player = P1 | P2 deriving (Show, Eq) +type Cache = M.IntMap (S.Set Game) + main :: IO () main = do text <- TIO.readFile "data/advent22.txt" let decks = successfulParse text - print decks - print $ play decks + -- print decks + -- print $ play decks print $ part1 decks print $ part2 decks part1 decks = score $ winningDeck $ play decks -part2 decks = score $ snd $ playRecursive decks S.empty +part2 decks = score $ snd $ playRecursive decks M.empty play = until finished playRound @@ -43,26 +50,22 @@ playRound ((x :<| xs), (y :<| ys)) | x < y = (xs, ys |> y |> x) | otherwise = (xs |> x |> y, ys) -winningDeck game = case (winner game) of - P1 -> fst game - P2 -> snd game +winningDeck (Empty, ys) = ys +winningDeck (xs, _) = xs -winner :: Game -> Player -winner (Empty, ys) = P2 -winner (xs, _) = P1 score :: Deck -> Int score = Q.foldrWithIndex (\i c s -> s + (i + 1) * c) 0 . Q.reverse -playRecursive :: Game -> (S.Set Game) -> (Player, Deck) +playRecursive :: Game -> Cache -> (Player, Deck) playRecursive (Empty, ys) _ = (P2, ys) playRecursive (xs, Empty) _ = (P1, xs) playRecursive g@(x :<| xs, y :<| ys) seen - | g `S.member` seen = (P1, x :<| xs) + | g `inCache` seen = (P1, x :<| xs) | (lengthAtLeast x xs) && (lengthAtLeast y ys) = playRecursive subG seen' | otherwise = playRecursive compareG seen' - where seen' = S.insert g seen + where seen' = enCache g seen (subWinner, _) = playRecursive (Q.take x xs, Q.take y ys) seen' subG = updateDecks subWinner g compareWinner = if x < y then P2 else P1 @@ -75,6 +78,24 @@ updateDecks P2 (x :<| xs, y :<| ys) = (xs, ys |> y |> x) lengthAtLeast n s = Q.length s >= n +hashGame (xs, ys) = + hash ( toList $ Q.take 2 xs + , toList $ Q.take 2 ys + -- , Q.length xs + -- , Q.length ys + ) + +inCache :: Game -> Cache -> Bool +inCache game cache = case (M.lookup h cache) of + Just games -> game `S.member` games + Nothing -> False + where h = hashGame game + +enCache :: Game -> Cache -> Cache +enCache game cache = case (M.lookup h cache) of + Just games -> M.insert h (S.insert game games) cache + Nothing -> M.insert h (S.singleton game) cache + where h = hashGame game -- Parse the input file -- 2.34.1 From e76710c7c113925d6aafefb1a021832762151ffd Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 5 Jan 2021 11:31:41 +0000 Subject: [PATCH 10/16] Tweaking --- advent22/src/advent22.hs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/advent22/src/advent22.hs b/advent22/src/advent22.hs index ac5162d..f94bf80 100644 --- a/advent22/src/advent22.hs +++ b/advent22/src/advent22.hs @@ -35,8 +35,8 @@ main = print $ part1 decks print $ part2 decks -part1 decks = score $ winningDeck $ play decks -part2 decks = score $ snd $ playRecursive decks M.empty +part1 game = score $ winningDeck $ play game +part2 game = score $ snd $ playRecursive game M.empty play = until finished playRound @@ -50,13 +50,12 @@ playRound ((x :<| xs), (y :<| ys)) | x < y = (xs, ys |> y |> x) | otherwise = (xs |> x |> y, ys) +winningDeck :: Game -> Deck winningDeck (Empty, ys) = ys winningDeck (xs, _) = xs - score :: Deck -> Int -score = Q.foldrWithIndex (\i c s -> s + (i + 1) * c) 0 . Q.reverse - +score = sum . zipWith (*) [1..] . toList . Q.reverse playRecursive :: Game -> Cache -> (Player, Deck) playRecursive (Empty, ys) _ = (P2, ys) @@ -68,8 +67,8 @@ playRecursive g@(x :<| xs, y :<| ys) seen where seen' = enCache g seen (subWinner, _) = playRecursive (Q.take x xs, Q.take y ys) seen' subG = updateDecks subWinner g - compareWinner = if x < y then P2 else P1 - compareG = updateDecks compareWinner g + compareTops = if x < y then P2 else P1 + compareG = updateDecks compareTops g updateDecks P1 (x :<| xs, y :<| ys) = (xs |> x |> y, ys) -- 2.34.1 From ef99d985fed4bda29a94866fd60813e02861dec4 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Wed, 6 Jan 2021 16:46:14 +0000 Subject: [PATCH 11/16] Updated readme --- README.html | 21 ++++++++++++++++++++- README.md | 23 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/README.html b/README.html index 37f2b09..94691f2 100644 --- a/README.html +++ b/README.html @@ -57,7 +57,26 @@

Generate the profile graph with

stack exec hp2ps advent01.hp

Packages

-

Stack is using the 14.16-lts resolver for packages, so make sure you read the correct documentation for the packages included in it.

+

Stack is using the 14.16-lts resolver for packages, so make sure you read the correct documentation for the packages included in it.

+

Packages I used a lot:

+ +

There are somewhat decent tutorials on Megaparsec and Attoparsec.

+

Packages I didn’t use much, but need to remember:

+

Readme

Build this readme file wth

pandoc -s README.md > README.html
diff --git a/README.md b/README.md index 2903791..58ea0f2 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Code to solve the [Advent of Code](http://adventofcode.com/2020/) puzzles. This The [Stack documentation](https://docs.haskellstack.org/en/stable/README/) and [How I Start: Haskell](http://howistart.org/posts/haskell/1/) are good sources of using the tools. + # Toolchain I'm using the basic Haskell Platform installation, together with `stack` to manage the packages and dependencies (install with @@ -82,7 +83,27 @@ stack exec hp2ps advent01.hp # Packages -Stack is using the [14.16-lts resolver](https://www.stackage.org/lts-16.25) for packages, so make sure you read the [correct documentation for the packages included in it](https://www.stackage.org/lts-16.25/docs). +Stack is using the [14.16-lts resolver](https://www.stackage.org/lts-16.25) for packages, so make sure you read the [correct documentation for the packages included in it](https://www.stackage.org/lts-16.25/docs). + +Packages I used a lot: + +* [Containers](https://hackage.haskell.org/package/containers) (and some [better documentation](https://haskell-containers.readthedocs.io/en/latest/intro.html)); [Unordered containers](https://hackage.haskell.org/package/unordered-containers) is a mostly-equivalent alternative. +* [Attoparsec](https://hackage.haskell.org/package/attoparsec) (and [Megaparsec](https://hackage.haskell.org/package/megaparsec), and [ReadP](https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html) once). + +There are somewhat decent [tutorials on Megaparsec](https://markkarpov.com/tutorial/megaparsec.html) and [Attoparsec](https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec). + +Packages I didn't use much, but need to remember: + +* [Arithmoi](https://hackage.haskell.org/package/arithmoi) for number theory +* [Pointed List](https://hackage.haskell.org/package/pointedlist-0.6.1) for zipper lists (sometimes circular) +* [Vector](https://hackage.haskell.org/package/vector) for array-like things +* [Linear](https://hackage.haskell.org/package/linear) for coordinate-vector like things +* [Grid](https://hackage.haskell.org/package/grid) for 2-d grids +* [Graph-wrapper](https://hackage.haskell.org/package/graph-wrapper) for graphs +* [Lens](https://hackage.haskell.org/package/lens) (and a [summary of operators](https://github.com/ekmett/lens/wiki/Operators)). I didn't use these much this year, but did a lot last year. +* [RWS](https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html) (Reader-Writer-State monad stack); again, used a lot last year but not this year +* [Monad loops](https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html), and [a description](https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/) +* [Replace-Megaparsec](https://github.com/jamesdbrock/replace-megaparsec), for using Mpc for all sorts of things traditionally done with regex substitutions. # Readme -- 2.34.1 From 5072f95356c17607722dddb918805ea1c48b8332 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Thu, 7 Jan 2021 11:49:24 +0000 Subject: [PATCH 12/16] Done day 23 --- advent23/package.yaml | 61 ++++++++++++ advent23/src/advent23.hs | 119 ++++++++++++++++++++++++ problems/day23.html | 194 +++++++++++++++++++++++++++++++++++++++ stack.yaml | 1 + 4 files changed, 375 insertions(+) create mode 100644 advent23/package.yaml create mode 100644 advent23/src/advent23.hs create mode 100644 problems/day23.html diff --git a/advent23/package.yaml b/advent23/package.yaml new file mode 100644 index 0000000..955330e --- /dev/null +++ b/advent23/package.yaml @@ -0,0 +1,61 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent23 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + +executables: + advent23: + main: advent23.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - pointedlist + - lens + - vector diff --git a/advent23/src/advent23.hs b/advent23/src/advent23.hs new file mode 100644 index 0000000..47e0e33 --- /dev/null +++ b/advent23/src/advent23.hs @@ -0,0 +1,119 @@ +-- import Debug.Trace + +import qualified Data.List.PointedList.Circular as P +import Control.Lens +import Data.Maybe +import Data.Char (digitToInt) + +import Control.Monad +import Control.Monad.ST +import Data.STRef +import qualified Data.Vector.Unboxed.Mutable as V + + +puzzleInput :: [Int] +puzzleInput = map digitToInt "538914762" +-- puzzleInput = map digitToInt "389125467" -- example + +main :: IO () +main = + do putStrLn $ part1 puzzleInput + print $ part2 puzzleInput + + +part1 nums = label $ playN cups 100 + where cups = fromJust $ P.fromList nums + +part2 nums = a * b + where finalCups = runGame nums 1000000 10000000 + (a, b) = clockwiseOf1 finalCups + + +label cups = concatMap show $ tail $ takeRight (P.length cups) atOne + where atOne = fromJust $ P.find 1 cups + +playN cups n = (iterate playOne cups) !! n + +playOne cups = P.next replacedAtCurrent + where current = cups ^. P.focus + held = takeRight 3 $ P.next cups + shorter = fromJust $ dropRight 3 $ P.next cups + destination = validDestination (current - 1) 9 held + shorterAtDestination = fromJust $ P.find destination shorter + replaced = foldr P.insertRight shorterAtDestination $ reverse held + replacedAtCurrent = fromJust $ P.find current replaced + + +validDestination 0 max missing = validDestination max max missing +validDestination n max missing + | n `elem` missing = validDestination (n - 1) max missing + | otherwise = n + + +takeRight :: Int -> P.PointedList a -> [a] +takeRight 0 _ = [] +takeRight n xs = (xs ^. P.focus):(takeRight (n - 1) $ P.next xs) + +dropRight :: Int -> P.PointedList a -> Maybe (P.PointedList a) +dropRight 0 xs = Just xs +dropRight n xxs = case (P.deleteRight xxs) of + Just xs -> dropRight (n - 1) xs + Nothing -> Nothing + + +clockwiseOf1 cups = (a, b) + where a = cups!!1 + b = cups!!a + +runGame :: [Int] -> Int -> Int -> [Int] +runGame seed cupsNeeded roundsNeeded = + runST $ + do cups <- seedGame seed cupsNeeded + gameLoop roundsNeeded cupsNeeded cups + mapM (V.read cups) [0..cupsNeeded] + +seedGame :: [Int] -> Int -> ST s (V.MVector s Int) +seedGame seed cupsNeeded = + do cups <- V.new (cupsNeeded + 1) + let extended = seed ++ [10, 11..] + forM_ [0..cupsNeeded] $ \i -> V.write cups i (i + 1) + forM_ (zip seed $ tail extended) $ \(i, j) -> V.write cups i j + V.write cups 0 (head seed) + let end = if cupsNeeded > (length seed) + then cupsNeeded + else last seed + V.write cups end (head seed) + return cups + +gameLoop targetRound maxCups cups = + do forM_ [1..targetRound] + (\_ -> gameStep maxCups cups) + return () + +gameStep :: Int -> V.MVector s Int -> ST s () +gameStep maxCups cups = + do current <- V.read cups 0 + held1 <- V.read cups current + held2 <- V.read cups held1 + held3 <- V.read cups held2 + afterHeld <- V.read cups held3 + + -- close the loop, removing the held cups + V.write cups current afterHeld + + let destination = + validDestination (current - 1) maxCups [held1, held2, held3] + afterDestination <- V.read cups destination + + -- make the held come after the destination + V.write cups destination held1 + + -- make the end of the held point into the rest of the loop + V.write cups held3 afterDestination + + -- advance current + nextCup <- V.read cups current + -- and store it + V.write cups 0 nextCup + return () + diff --git a/problems/day23.html b/problems/day23.html new file mode 100644 index 0000000..18a99c3 --- /dev/null +++ b/problems/day23.html @@ -0,0 +1,194 @@ + + + + +Day 23 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 23: Crab Cups ---

The small crab challenges you to a game! The crab is going to mix up some cups, and you have to predict where they'll end up.

+

The cups will be arranged in a circle and labeled clockwise (your puzzle input). For example, if your labeling were 32415, there would be five cups in the circle; going clockwise around the circle from the first cup, the cups would be labeled 3, 2, 4, 1, 5, and then back to 3 again.

+

Before the crab starts, it will designate the first cup in your list as the current cup. The crab is then going to do 100 moves.

+

Each move, the crab does the following actions:

+
    +
  • The crab picks up the three cups that are immediately clockwise of the current cup. They are removed from the circle; cup spacing is adjusted as necessary to maintain the circle.
  • +
  • The crab selects a destination cup: the cup with a label equal to the current cup's label minus one. If this would select one of the cups that was just picked up, the crab will keep subtracting one until it finds a cup that wasn't just picked up. If at any point in this process the value goes below the lowest value on any cup's label, it wraps around to the highest value on any cup's label instead.
  • +
  • The crab places the cups it just picked up so that they are immediately clockwise of the destination cup. They keep the same order as when they were picked up.
  • +
  • The crab selects a new current cup: the cup which is immediately clockwise of the current cup.
  • +
+

For example, suppose your cup labeling were 389125467. If the crab were to do merely 10 moves, the following changes would occur:

+
-- move 1 --
+cups: (3) 8  9  1  2  5  4  6  7 
+pick up: 8, 9, 1
+destination: 2
+
+-- move 2 --
+cups:  3 (2) 8  9  1  5  4  6  7 
+pick up: 8, 9, 1
+destination: 7
+
+-- move 3 --
+cups:  3  2 (5) 4  6  7  8  9  1 
+pick up: 4, 6, 7
+destination: 3
+
+-- move 4 --
+cups:  7  2  5 (8) 9  1  3  4  6 
+pick up: 9, 1, 3
+destination: 7
+
+-- move 5 --
+cups:  3  2  5  8 (4) 6  7  9  1 
+pick up: 6, 7, 9
+destination: 3
+
+-- move 6 --
+cups:  9  2  5  8  4 (1) 3  6  7 
+pick up: 3, 6, 7
+destination: 9
+
+-- move 7 --
+cups:  7  2  5  8  4  1 (9) 3  6 
+pick up: 3, 6, 7
+destination: 8
+
+-- move 8 --
+cups:  8  3  6  7  4  1  9 (2) 5 
+pick up: 5, 8, 3
+destination: 1
+
+-- move 9 --
+cups:  7  4  1  5  8  3  9  2 (6)
+pick up: 7, 4, 1
+destination: 5
+
+-- move 10 --
+cups: (5) 7  4  1  8  3  9  2  6 
+pick up: 7, 4, 1
+destination: 3
+
+-- final --
+cups:  5 (8) 3  7  4  1  9  2  6 
+
+

In the above example, the cups' values are the labels as they appear moving clockwise around the circle; the current cup is marked with ( ).

+

After the crab is done, what order will the cups be in? Starting after the cup labeled 1, collect the other cups' labels clockwise into a single string with no extra characters; each number except 1 should appear exactly once. In the above example, after 10 moves, the cups clockwise from 1 are labeled 9, 2, 6, 5, and so on, producing 92658374. If the crab were to complete all 100 moves, the order after cup 1 would be 67384529.

+

Using your labeling, simulate 100 moves. What are the labels on the cups after cup 1?

+
+

Your puzzle answer was 54327968.

--- Part Two ---

Due to what you can only assume is a mistranslation (you're not exactly fluent in Crab), you are quite surprised when the crab starts arranging many cups in a circle on your raft - one million (1000000) in total.

+

Your labeling is still correct for the first few cups; after that, the remaining cups are just numbered in an increasing fashion starting from the number after the highest number in your list and proceeding one by one until one million is reached. (For example, if your labeling were 54321, the cups would be numbered 5, 4, 3, 2, 1, and then start counting up from 6 until one million is reached.) In this way, every number from one through one million is used exactly once.

+

After discovering where you made the mistake in translating Crab Numbers, you realize the small crab isn't going to do merely 100 moves; the crab is going to do ten million (10000000) moves!

+

The crab is going to hide your stars - one each - under the two cups that will end up immediately clockwise of cup 1. You can have them if you predict what the labels on those cups will be when the crab is finished.

+

In the above example (389125467), this would be 934001 and then 159792; multiplying these together produces 149245887792.

+

Determine which two cups will end up immediately clockwise of cup 1. What do you get if you multiply their labels together?

+
+

Your puzzle answer was 157410423276.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

Your puzzle input was 538914762.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 86013c9..021f4ba 100644 --- a/stack.yaml +++ b/stack.yaml @@ -57,6 +57,7 @@ packages: - advent20 - advent21 - advent22 +- advent23 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From d51325ae0b835dd8928bd136d625db22741b4e97 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sat, 9 Jan 2021 18:00:01 +0000 Subject: [PATCH 13/16] Done day 24 --- advent24/package.yaml | 63 +++++ advent24/src/advent24.hs | 100 +++++++ data/advent24.txt | 592 +++++++++++++++++++++++++++++++++++++++ data/advent24a.txt | 20 ++ problems/day24.html | 183 ++++++++++++ stack.yaml | 1 + 6 files changed, 959 insertions(+) create mode 100644 advent24/package.yaml create mode 100644 advent24/src/advent24.hs create mode 100644 data/advent24.txt create mode 100644 data/advent24a.txt create mode 100644 problems/day24.html diff --git a/advent24/package.yaml b/advent24/package.yaml new file mode 100644 index 0000000..39c7ae7 --- /dev/null +++ b/advent24/package.yaml @@ -0,0 +1,63 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent24 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + + +executables: + advent24: + main: advent24.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - containers + - linear + - text + - attoparsec diff --git a/advent24/src/advent24.hs b/advent24/src/advent24.hs new file mode 100644 index 0000000..d9bcc92 --- /dev/null +++ b/advent24/src/advent24.hs @@ -0,0 +1,100 @@ +-- import Debug.Trace + +import Data.Text (Text) +-- import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text hiding (take) +-- import Data.Attoparsec.Combinator +-- import Control.Applicative +-- import Control.Applicative.Combinators + +import qualified Data.Set as S +import Linear (V2(..), (^+^)) +-- import Data.Semigroup +-- import Data.Monoid + + +data Direction = NE | E | SE | SW | W | NW + deriving (Show, Eq, Enum, Bounded) + +type Tile = V2 Int -- x, y +type Grid = S.Set Tile + +instance Semigroup Int where + (<>) = (+) + +instance Monoid Int where + mempty = 0 + +main :: IO () +main = + do text <- TIO.readFile "data/advent24.txt" + let walks = successfulParse text + let grid0 = foldr flipTile S.empty walks + print $ part1 grid0 + print $ part2 grid0 + +part1 grid0 = S.size grid0 +part2 grid0 = S.size $ (iterate update grid0) !! 100 + +delta :: Direction -> Tile +delta NE = V2 1 0 +delta E = V2 0 1 +delta SE = V2 -1 1 +delta SW = V2 -1 0 +delta W = V2 0 -1 +delta NW = V2 1 -1 + + +flipTile :: Tile -> Grid -> Grid +flipTile tile tiles + | tile `S.member` tiles = S.delete tile tiles + | otherwise = S.insert tile tiles + + +neighbourSpaces :: Tile -> Grid +neighbourSpaces here = S.fromList $ map nbrSpace [minBound .. maxBound] -- [NE .. NW] + where nbrSpace d = here ^+^ (delta d) + +countOccupiedNeighbours :: Tile -> Grid -> Int +countOccupiedNeighbours cell grid = + S.size $ S.intersection grid $ neighbourSpaces cell + +tileBecomesWhite :: Grid -> Tile -> Bool +tileBecomesWhite grid cell = black && ((nNbrs == 0) || (nNbrs > 2)) + where black = cell `S.member` grid + nNbrs = countOccupiedNeighbours cell grid + +tileBecomesBlack :: Grid -> Tile -> Bool +tileBecomesBlack grid cell = white && (nNbrs == 2) + where white = cell `S.notMember` grid + nNbrs = countOccupiedNeighbours cell grid + +update :: Grid -> Grid +update grid = (grid `S.union` newBlacks) `S.difference` newWhites + where neighbours = (S.foldr mergeNeighbours S.empty grid) `S.difference` grid + mergeNeighbours cell acc = S.union acc $ neighbourSpaces cell + newWhites = S.filter (tileBecomesWhite grid) grid + newBlacks = S.filter (tileBecomesBlack grid) neighbours + + +-- Parse the input file + +tilesP = tileP `sepBy` endOfLine +tileP = foldMap delta <$> many1 stepP + +stepP = choice [neP, nwP, seP, swP, eP, wP] + +neP = "ne" *> pure NE +nwP = "nw" *> pure NW +seP = "se" *> pure SE +swP = "sw" *> pure SW +eP = "e" *> pure E +wP = "w" *> pure W + +-- successfulParse :: Text -> [Tile] +successfulParse input = + case parseOnly tilesP input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right tiles -> tiles diff --git a/data/advent24.txt b/data/advent24.txt new file mode 100644 index 0000000..408fa7b --- /dev/null +++ b/data/advent24.txt @@ -0,0 +1,592 @@ +wwwnwwswweswwwswwwwswwswwww +swnwwsesenesenenwwnewwwwnwwnwwnw +nenewnesenwnenenenenenene +neeeeewneneneneeeeneeeeeee +swwneswswseseneweseswnwnwseneswswsesenew +eneneneswneeneeeneneeneenenenenene +sesesweseseseenwseseseswsenwseswswswse +eeeeeweneeee +neesewweneewswneeneneseeeeeeee +swsenwswswswswseswseswswswsweswswswswsw +neswewswwsewwwnwsw +seswsenenwswswswseseneseswswswseseswseswse +sewweswneneeneneeeseseeseeneesww +seswsesesesenwnwseseneseseseeseewseee +nwnwnwwewnwwwwnwwwwww +wnwwswwwwwswsewwwweswne +swsesenenwnenwswseseneswseswe +nwwenwwnwwwwwwswwsenwnewnwnwwne +swwwwneswswwseswwswwneswwwswwew +nwneswnenwnenenwenwnwnenenwsenenwnenenw +neneneneneneeneneneneneeneneneenenwnesw +nesewnenwwenwnwwseseeseseneneswwsw +nwnwnwenwwnwnwneswnenenwnenenwnenenwnwne +wnewswwwwswswwswwseswwswswswswsw +nwweswnwswwwswswwnwwsewswswswenesw +neswneneneneneewnene +nwnwswnenwwnwnwnwnwnwnwwswswnewnenwwnw +nenenenewewneneenenewsenewneenesee +nwwnenwnenenenenwnenenwenwnenenenenene +nwsenenenwnwnenenwnesenwnwnwnwnwne +nwneseswwwwswsewwseswswswswswswnewsw +wwwwnwswwwenewnwwwwswwnwww +sesesesesesenwesesesesesesewsweseneseese +eeneneweeeneeseeee +wweswnwwnwnewnwwwswseenwwnwwnwnw +neenenwneneseewnenwnwnwnenenwnesweswsw +seswnwsesewwswwseswneswsweneeseswwe +nenewnwnwnenenenewnwswenwwnesenesenwne +nwenwneswswneeswsesewseww +neneeneneewswneenwneneeneswnenenenee +swseswseseswswseseseseswnwswseswswsw +swneneneswwwneswwsewseswswswswwww +nwneseswnwnwneswnewnwnwnenwnweseenwe +wwwseeenwwnwnwnewnwnwwwnwnwnww +sesesesesesesesewseseseseseseseesese +swswwswseneeswnwwesewswswweneswsw +wseewesenweneenewseneenenwswsee +enewseeseesesesenesesewsewsesesesesee +sewwwswswswwwwswwswswwwswneswsw +nwnwnenwnwwwnwnenwnwnwnwnwswnwwsenwnw +nwnwnwnenwnwnwnwneenenenew +neeneenenenwswwseeneeesenw +eseeeeseseweewseeseeeseeeee +nwsewswseseseseneseswseswseseswe +wwswswwswswnwwenwwwswswwseneew +wwwwewwwwwweewswwwwwww +swswswswswwswnweswwswswsweseswneswswsw +nwewwsenweseeeswneneseneeweewnw +nenewwnwsenwwwwswwsewewwenw +nwwnenwnenwnwnwnenwnenwnwswnwnwnenwnenese +seseneswseswswseswseswseswswseswseseswse +eeeeeeweeeeeeeeeeswenwe +eneswneneswnenenweneneneee +nwswseeneneneeeeeeeeeeenenwenee +swsenewwwwnwwwnewneeswwwnwwswnww +eeeeeeeeeeeeeeweeeee +eseeseseseeeseweneseeseeeeseese +wwwwwwswwnwwwwnwswwnwwneewe +eneseseeseseseneswneenwsewsenewswwswe +senweeeeeeneseneeeseeswnwenwwe +sewsweeneseswneswseswswwseswwswesenw +wwwwwwwwswnwwwwwswwweww +sewnwwwwwsewwwwnwnwenwenwnwswne +eeeeeenweeseeeeee +swsenwsweseswseswswswseswswsesesesesesese +sewswwnwseswswswnweeenwsesesenenesesw +nwnwseseewnenenewewwenwwnwsesenwne +sesesenweseseseneswseseewseeseseneew +swwswsewswsweswswswswseseswneswswswswnw +swseesenwseseweseeseseeseseseeenwe +wwnenwneenwnenenesenenenenwneweseswnwne +nwnwnwnwnwnwnwnwnwsewnwnwnwnwnwsenwnenw +seswsenwsesweswseseseseseswseswswsesene +seswwseseseseseseseseswswsenesesesesese +nwswswswswswneswswswswswsweswseswswswswsw +wwwswwwwwwnesewnwnwsewwwwnwe +seneneneeenewneeeeeenenweneswne +seneenwseseseswsenwwneswswsese +wswwswwwwwswnwsweenwswswwwswesw +eeseseseeeseeesenweeesewswese +nesewswswswnwswswswswwswsweswswswsww +eneswswneeeeenweeeewnwenenwseesw +seneswnwswenwnenenwwnew +seenweweesewewseseeeeeneeew +swnwnwnwnwnwnwenwwnwswenwnwnwnwnwnwnwnw +enwswswswwseseseswsenwseseeseeseswwsw +eeseseseswseseseswsenwwnwseseese +neeeeneswnenenenenenenenenenwnenenee +wnewwwwswewwwwwnwwswseswww +neneneneneneneswneneneneneneneswnenewnee +seeeseeseseseeseseeseswsenwseesesese +swwsewswswwwwswswswsenewseswswnenw +swneseseseswswseswswswseswwseseswswswse +wswweswwnewwnwwww +swswswsesewswswneswswswwsweneswswswsw +wnwwnwwwweswnenw +swseswsweswseswswswswswseswnwswseswswsese +neenesewseneeesewewneneneenenw +seneswseswswnwnwsweswswwswswswseswsenese +nwenwswswwnwwnwnwnwnwsewsenwwwnwnwenw +nenwnenenwnwnwnwnwewnwnwwnwwnwenee +wneseeswwwswsewwwswnww +nwnwnenwnwnenwnwnwneswnwwnwnwnwenwsenw +neeeeneneneneeesweeeenenwswneneee +senweseweseseseeseseseneseseeeswsese +wseseeeneseseneeeeesewseeeweese +seseseseeseseseseeeesewsesesenwsese +wseeseenwseseneeseseeeseseeseeeese +nwwesesesesenwnewwnwnesene +swwneneeeeseeeeeswseenweeeee +nenwseneneneeneeeee +nwwsewwnewwwwwwwww +neneseseenewewwnewnwnwesesenewsesee +neswswswneswnenwwewswneswwswneseswsw +seswswswseseseswseswnewseseswseswsw +wneswseseseenwnewseeswswswnwswsesenw +eneeweneneneeeneesenenenenenenenewse +neswswwwwwwwwwswsew +wneseswnewswwswew +swnwwneswnwewswwswewnwswwwsenwse +wnwnwwwwwnwnwsenwnwnwnwnwnwnwwsew +senwswnwnwnenwswsewneseesenwnwwneenwsw +nesesenenenenwnwneneswneneseenenenwnewnwnw +nenesenwneneneneneneneswneenenenenenenene +eweneesesesesewseeeseeeeeesesee +eeneeweneeneneneneeswnenwneeeswne +wswseswswnwswwswsweeseneswswseseswnw +swenwwnwwsenwnwnewnwwenewwwesw +senwseswswnewswswseswesweswswneswswse +neseneneneeswneneenenenenenenenewnewne +nesewsewwwewwwwwnwwnwnw +swneswwwnwswnewneswwwwwsewwswsesw +nenwwsewnwnwneswsesw +nwnwnwnweseswnenwenwnwnwnwnwswnwnenwnwnw +eswneneeneneneswnenenenenenewseneene +nenwswwwswwwswsweswwwsweswswsww +newneeeeneneneneneene +wnwswewneeewseeseenwswwesenenew +swswswseswswswswswswswswswswwswsweswsw +eeeeenweesweeeeeenweeesw +swswswswswswswswswswneswswswswswsw +eeeeswwwneseeneeeeenweeswee +wwwwwwwwwwwnenwwwwswwww +swwswwnwswwwsewsww +swnweesenwnwsenwswseswwweswswnw +nesenenwnenwnwnenwnwnenenwnenwseenwwnewne +nwsewwnwwnwwwwwwwwwnwnwnwww +eneenewenewneneeeneneeswswneneee +nenwnwnwnwwwnwsenwnwnwnwnwnwnwnwnwnwnwsw +nwnwnwnwnenwnwwnwnwnwnwwnwnwswnwnwnwsenenw +weseeeewneneseseeeeeseswesese +swseseseseeesesesesesesesesenw +nenwnesenwnewnenwnwnenenwnwnwnwnwnwnwnenw +nwnwnwnwswnenwnwnwnenenwnwnwnenwnwne +nwnenweswnenenwneenenewnenenenwnwnwnene +seseeeeseeseseswesenwseseenw +wnwnwnwnwneweswnwwwnwnenwnwwnwnwsew +seneeswwwswneseseswwswseswswswswswswnw +senwwnenwnwnwnenwnwnwnenwnwnwnwnwnwnenw +swnwnwsenwnenwnwnenwnewnwseswnwnenwswne +swswswswneswseswswswsw +seseseswseseseseesesesenwesesesenwnwsese +swswseswseswswswsesesesenesesenwsesesw +wwswwwswwwwswwsewwnewnewwsww +neswswwswseeswwswnenesesesesewswswsw +wwwwwwwswwswseswnewsewswnewwww +swwswswswwswwswwswswswswneswwwswsw +wenwseeeseeseeeseeeseseseneese +neneswnewswwwenwwwnwswsenwwwse +wneweeseeseeeeweenwwewseene +wswnwnweeswesweseenenwswwnenwwnwsenw +sesenesesewseenwsesweeseewesesese +eswseswsenwesenesesesesesewwswsese +nenwwswewwwweseenwsenwwwwnwesw +nwswweswswswswswswneswswwwwnweswse +nwseswseeneseeweesesewneeseeseesene +neeeswewewneseneswneneeneeneenenw +eneneneeeeeweeeneneneeeneee +seswseseswseswswseswseeswsesesewswsese +nwnwnwewwwnwwwwnwwwe +nenenenenwneneneneneswnenenenenenenenenee +wneswneswswswswwswwewswswwwswsesewnw +nenenwnenenesenwnwnenenwnenwwnwnenenenwnw +eneeseswewnwseeswseewweeneswew +ewenweeeeeesesesenweeseeee +nwsenwnwnenwwnwnwnwenwnwnwewnwnwnewne +wsweswswwswwswswwswswswswwswswnwwenw +wwsewwswnwwneeswwwwnwwwswwww +swsewswswswswswswswswswswswswswseseswne +swnwnwnwnwewswswweeenwwnewnwnwnew +seswswswswswneswswseswswswseswseswswswse +nwwwnenwwwnwsewwenwwwswwwwnwww +senwnwnwswneenweneseswnwneeswnwnweswne +wseeeeeeeeenweeeneeeeee +enweeweeenwenwseeneswseneneeeee +nenweeeneseneeeseeeeenesenewwne +nwnenenenwnenwswneswnenenwneneseene +nwnwsenwswnwnwnwnwnwnenwnwwnwnenwnwnwnwnw +ewnwsenwenwswneeseneneswnenewnenenese +wnwswwwwnwsewwnwnewwwwswwneesese +newwnwseswsenenwnwnwnenenw +nwsesesenwsenwseseseeswseswswseswsesese +sesesenwswseseswseseseeseswse +nwneneenwwnenwswnenwswsenwnenwswneneenw +enwswneneneseeeneeneneeewneswneee +wnenenwneneneneneneseswnese +neweeeneeeeeeeeeeeeeee +wswswseswswnwswswswwswswwneswseswswnene +swswseswwswseswsesweswseswseneseswnwswse +wnenweseeesewseseswseseseweswneene +enwswseseswswnwenesesewse +neseneneneneeneenenenenenewswnenenenenene +nwswsweeswseseswseswswnwwswseseswswsene +eeneseeseneeseseesenwseseeswsewsese +sesesenwesenwsweseseweneewseneneese +sesewnwnwwnwnwwwnenwwwewsweww +nwswwwewswwwnwwnwnwwnesewwwnww +enwswnwnwsesewwweneswewwwnwneew +wswswswneseswswwnwswswswswswnenwseswswse +nwnwnwnenwnwnenwnwnwnwnwswnwnwenwnwnwnwnw +nenenwnwnenenenenenesewnenenenenene +nenwnwsewswwnwseenwnesenenwnenenwse +wwwwwwwwwwwwwwswwwwwe +seswswswswswnwsweswenwswswsewswswsw +swswnwwswswwwswwneewwwswsw +ewsewwnwnewwwwnwnwsewwwnwwnwse +eseeseeseeeeeseeeneeeeseswe +sweswswswswswswswwswswnwswseswswseswe +wnenwswwnwnwnwnww +sweeeseneseseneseseewseesesew +seneeswneneenenwwswwseenwneneewene +swswswswswsesweswswswswseseeseswswwswnw +seeseeeesenwsweeseeeseese +nwnwnwnwnwnwenwnwenwnwwnwnwnewenww +wswswwswswweswswswwswnewsewswsw +nwnwnwwnwnwnwnwwwwnwwnwnweenwnwnwwsw +eneeeeneenenweneneneesweewesw +nwsenwswnwnwnwnwnenenwnwnenenewnwnwnwnee +swweswswswswneneswswswsesesewswsesesese +swswsenwswswswswswnwneswsweswsewsesesew +eneeeeeeneeneeneneeeeeswee +swwseseswseswswnenwnwseswenenesenwswswsee +seseseseseneswneseseswswsesewsesesesenesese +swwswwswswwwswewwwwswswneswswsw +esewwswwwwwwswwsewswswwnwnwswswne +nwnwwnenwewnwnwnwnwswnwnwwswnwnewnw +newswwswwswswswwseswwswnewwnwswswse +wwwsenwnwwnwnwsenewwwwnwnwsenwnwwne +seswwnwwwnwswsweenwwwwwee +swswwswswswswswswswswswesenewswswswsw +wwswswswswswswswswswswswswswesw +wnwnwwwsewwwwnwwnwwnwwsenenwsew +sewnwnenewwnesenwneeenwnwnenwnw +nenwsenewnenwnenenenwnenenenenenenenenwne +swswswswswswswswswswseneswswseswswswswsw +neewnenenwnenenewnwnenesenenenwnenene +swneeeneneeeeweneesenw +eseewneeneeeseeswnewneeeeeeee +senewsewneewswseswneswswseseswseswsw +nenwnwenenenesweweswneneneneseeenene +sesesesewsesewseseweseneswnesesesesese +nenwnwnenenwnwnwswsenwnwneneswnenwsene +swswswwneswswswneswswswswswswswwswwswsw +wwwswsewwwnewnwwwwwwwnwew +nwwnwwnwwnwnwwwwnwwwswwnewwew +eenwneenweeswseneneneswesweneenenwe +nwwnwenwewnwwnwnwswnwwnwnenwsewwesw +seswswwswswnwswswswswswswsenenwseenenesw +eeneswenweeneeneeeneneeneeee +wwswswswwswswswwswswswswwwswswneswne +nenwnwnenenwnwnenenwnenenwsenwnenenwnwnw +nenenenenenenenenenewneneneneseneenenene +eswnwswswsweswswswswswswswswswnwswswsw +ewwwnwwnwswwnwwwwwnwnwnwwwnwenw +swswseswswswswswseseseswseneswswsewswsw +nwnenenwnwnenwnesenwnenwnenenenwnwnw +sewnwwwwsewwwswwswwswswnwneswwsw +swswswswswseswsenwsw +wseswewneseswseseswneeseeesesewne +seeewsweswswwswsewnenwneewewwnw +seswenesesweseeesesenwweewnesenw +swswswnwenwswsesewneswswneswseseeswswnw +nwnwnwnwnwnwnwnwnwnwnwnwsenwnw +nwewneneswneneneneenwswnwwesesenesenene +eeneneweneneeneneeswnewenenene +swwswswnwwsesweswwsweswnewwswwnw +enenewneweneneneneeenenenenenenene +eseesweseenweeeenweeseeeeeesw +nwneeeneseseseseseseswsewsewsesewse +nenewnweeeeswseswsesenw +wnenenenenwnwneneswnwseeswsesenwnwnenenee +eeeweeneeneseeesweeeneeenee +swwnewswnewwnewseswsweswwswswwwsw +senwnwseswwneswseseseswnwseseseseseseseswse +nwnwneswnwenwnwnwnwnwnwnwnwnwnwnenenenw +wnewnewnwswnwnwwwnwnwwnwwnwnwwsew +eeeeeeseeenwneeeewesesweese +swswseswswswseswswsweseswswneswswwnwsw +senwnwsenwnwswenenenwwenwenwnewnwnwnw +eweseswewseseneneseswneewseenwee +sesesesenweseseseseseseseesesesesewsesw +nwsenwnwnwnenwnwenwnww +newwweeswwnewnwseswseenewwnwswnew +wwsewwwwwwwwwwwwwwwnww +wwenwswsweeenweeeeeseeswnwe +nwswsewwnwwsenwswnwwnwsenewwnwenw +seewseeeseeeeneeeeeeeeese +enwswwnwwwnewwwsewnwewsenewswww +senwnwswsenwnwnwnwnenenwnwswnenwnwnwnwsw +swswwwswwnewwwwwwwewswseww +seswseswseesewseseswseseneseseseswsese +eneesenenwwnwseseeeenwneeenwswese +nenwnesenenwnenenwnwnewnwnwnwnwnenenene +swseseseswnwseswswseswswseswswswseswswsw +newnwswwwnwwwwswnwnwewwwnwww +neswsweeeeeenenenwswnenw +senwwnwnwnwnwwnwwnwnwnwnwnwnwnwenwnwne +nwnwnwnwnwnwnwnwnwnwnwnwnwnwwnwnwnwenw +seswwsewswwesweseseswneswswnwswnesw +nenwnwswswneneswneneneneeneswneneenenene +neeswnenenwneneneneneneneene +nwnwnwnwnwnwnwnwnwwwwnwnwenwwnwnwsenw +wwwwseswwwwenwnwswswwwswswswwsw +wwwwwwwwwwwwewwwewww +swswswswseswswswswswwswswswneswneswswswswse +nwnwenwswnwsenenwnwnwnwwnwnwnwnwnwswnw +nwseeneneneneneneeeeseeenewnenenenew +swneswneseseewesweneseenenewewnenene +enesenwnwseeeenwwweeseeswnwese +swswswswswneswswswswswswswswswswswswswsw +eeeeeswnweeeneneneeneeeeenene +eeseeseseswwnweeeeseseeseewsee +nwnwnwnwwnwnwnwnwnwnwnwnenwnwsenwnenwnwnw +enwwseseeeseseeeneseeeseenewsenwse +swneseseswsesesesesesesesesesesesesesese +eswewsenenwseeenwseenenenweswswnwew +eseswesesesesesweseseswwsenwnesesesene +nwnwswnwnwneswnwswnwsenwnwnwnwnwneeswnwe +swseswwneswneswswseswwswswswwneswese +wwswswwsenewwsewsenewnenewnesew +wseswnwswseeenwneeeeneeswsesenwesee +swesesenesweseewseeneseneseeseese +swnenesesenwseeswwswnwwnenwneneseswse +senwseswnewseeseweseseeeewewse +seeswseswwswneswswseneswseswseswswsww +wswwswswwwwswwswwswswwesw +seseeseneseseseeeneseseesewseswseese +seneswnwewswsesenwsenwneswswnewwswse +sweseeseseseseseseesesesenwseswnwsesesese +swnwswnewswswseswnewwnwswnewswswee +seenewwsenwwwwwwwnewsenewwsww +neswneswnenenenwswwenenwnenenenwenenwne +neneeeneneneswnwneneneweneeneswnenenene +seseseeseseenwsesee +nenenenenwnenwnwnwnenenewsenenenenenene +wwwweneneswnwesweweswnwsenwswnew +swnenwnwwenewnwnwnweneneenewneswnee +senesesewenwsesesesesesesesesesesesee +wswwnewewswswnwsweweseswwswswne +esweenweneneswnenene +seseseseswseseswesesesesesesesesesewse +nwnwnwnwseenwnwnwnwnwnwwwnwnwnwnwnwse +neneeeenweneeneneeeeesenenenee +esesenenewwseseseeeseeseneseeeesw +ewwnewwnwwsenwwnwnwswnwnwnwnwnwnw +nwnwnwnwnwnwnwnwnwnwswnwnwnwwenwnwnw +swnwnenwswewnwwnwnw +neneenesenewnenenewnenenenenenenenenene +swswsewsesweseseswseneswnw +seneneneneneswneneneeeeenwnenenenene +nwnewsenwnwenwnenwnwnwenwnwnenwnwnww +seneswnwsesesweswsenwnwweseneseswswse +nwwsenwwwenwwsenwsewswnweenwsenww +sewsesweeseneswnewseseseseswesenenesw +seswseswseseswswseseswswseseswseswsene +wwwwwwwwwwnwwewewwwwww +seswnwseseseeseese +swnweeeeeeeewseneeenweesww +seswsesenwsesenwsewswswswseeseswseeswsese +nwnwnwwnwnwwenwwwwwnwwnwwwnww +nenenewseneneneneneneswnenenenwnewsenenenw +nwwnwwnwnwnenwnwnwnwnwnwnwsewwnwnwnww +eneeeeseswesewnenwnwseswsewnwwnenwse +wenwsenwnwnenwnwwsewnwnwnwnwwsenwnww +nwseenwwsenewwenwsewewneenwnwnwsw +seneeswnwnesenwnwnwwesweswswnwnesenwnw +wwswswswswswwswwswwswswswneswsw +nwneneswenwswneneneswwsenwnesenenwnwnwnwne +wwsesenenenwnewnenenenenwneneseeene +nwsewwnwwesenwnwwnewnwwnwnwwwnw +seneneewneeneeneeneneneeenenenenenew +neswswsweswswswswnewneswwswwnwswwsw +seseseeseeswnweesewsesesenewnwse +senwwwwnwwwwnwwnwnwwwwwnww +swswswwswswswswswswswneswswswswswswswsw +neswswwenwnesenwneswnenwnenesewnenwnenene +enenenenenenenesweenenenenwnwenese +nwwwwwnwsewwwwwwwwwwwnww +nenenesenenwneneneenenenenee +nwenwnewswsewseewwwnwwe +nwnwnwnwnwnwewnwnwnwnwswnwsenwwnenwnwnw +swswswwswswswswswwswswnwswswswswesweswsw +seseeseseseseseseswsesesenwsesenw +wwwwnwsenwwwwwsenewnwnwwwww +eeeeeneeeeeenesweeeeneene +nwnenwnwnwwnewsewnesenwnwwwswwwww +wswnwwewseswswwnenewwseswswnewse +swseswswswswswswswswswswseswswswnwswnese +nenwswwnenwseeswnwnweswwnwnwnwne +nenwnwnenwnwwneneswnesenwnenwnwnenenwnw +eeeeeeeeeeneweee +swseseseseswswseeseswswswsenwswsesesw +eneeeeeweeeeneeneeeeesee +wseenwswswwswwwswweswseswnwnwwne +seseswswsesenwseseseseseswweswswswsese +nwwnwswwwnwwnwwewnewwsenwswnwnw +swwswswswsweesenwswswswwneswwswwswnwe +ewnwwwwseneswesewwenwwswswesw +seseesesenwseswseseesewsesesesesesese +swswswswneswneswswwswseswseseseseswswsw +wswswswnwseswswswswwswswsweswswwsw +nwnwnwnwnenwnenwswenwwswenenwnwnenwnw +swswswswswswwseswswseseswswneswswswsese +swswswwneswsweswwsewswwnwswwswswsww +nenewneneneswnwnwene +enweeeeeeeneeeeeswneeeswne +enenwneeeeeneeneeneneeeeeswsw +seseseseseswseseseseseseseseseenwsesesese +nwnwswwwnwwsenwwenww +eseseeseneseseseseseeeseewsesenwse +seseseseseswseswsenwswseswsenw +nwswseseseeseeenweeeseseeeeseee +nwwwwwwwseeswswewnwswsw +eseseseeseeseneseseeeeeweeesee +seenwsewseeeseswswseseseesenweesesee +neseweneenenenenenenenenwnenenenenwsw +swseewneswswswswswseseswswswseswsenwsw +swwneswswswswswswswseswwswswswswswwsw +wswswwwswweswsweswwnwswswswwwwww +wwwwwwswwswwnwwseswwewwwwnew +nwnwnwnwwnwwweswnwnwnwnwnwnwnwwnwnw +nenenenwseneswesewenewenenenwseenw +eenweeeesweeeeeeeeeenee +newswwnwswnenwwnwe +senwseswseneeseeseseenwwsenesesesenesew +eeeeeweeeeeeenweeseeseswsese +neneneneneewneneneneneeswnenwneseeese +enwswnwwnwneenwwnwnwnwnwnenwnwswnwnese +swnwseenwwwseeseesesese +seswwnenwwwnweeswenewnwswswnesee +seswsweswseswswseeswnesewenwwnwsesesw +nwsenwwnwnenenwwnwenesenwne +neeenwneseewneswnwnwsewseswneswwse +eseswsenesesweseeenwneesweneeee +wnenwseweneeswswneswsesenwseswneesesw +nwnenwsenenwnwnwseneswenwneswnwwnewne +eeneeseeewsweew +swwswnwswwwwswswwsewwwsewnesww +eeeeneweseeeeseneseseseeeweese +swnenwnewwswseneseswe +swnwswsewswnwweseswswseseseseswneneswwe +eneeseseswesenwsweseeeseneseesesese +neenenwnwneseneswwneenenesw +wwswwwwswwswwswswwwseswswwnew +seseseseeeeeeseseneeseseeeesewse +swseseswsweswnwseseseswseswseswseswnwsesw +swneswswnwswswswewwswswseswswnewswse +newnwsenwnwwwswwsewwneewwwsew +weneneeeeeeeneseeeneswwnenenene +wswswwswwwsewneswswwswswwwswswww +neneneneneneneneeneneneseneneneneswnewnene +sesesewsenwseswseneweseseneswswsenwse +swnwnenwswnwesenwnwwnwsenwnwwewenw +nwsewnenwnwnwnwnwnwnwwnwnesenwnwnwwwnw +nesweswwswseneswswnwseenwnwswsweseswsw +swneswwnenewseseeneenenenweneneesw +eseseseeseseeeeseseenweeeswsese +wwswwswswwswnwwwswwwwswswswswesw +ewwnwswnwwwwwwwwwsewwwww +seswnwseeswseswswseswsewswswswswsesesese +eesenwseeeseseseeseseseseeswneee +enwwwswwseswwswswwwwnwswwwswwww +nwnwwnwwwnwnwsewnwnwnwnwnwnwnwnwwnw +eeesesweseeseeeswneeesewenene +eeeeeseweseeeeseeseee +seseseseseeseseseeseseenwsenwseswswse +nwsenwnwnwsenwnwsenenwnwwnwnenwnwnwnwnw +senenesweneneswnwenenenenwnenenewwnenene +neweeweeseeneeneeseseeneeeeenw +wsenwnwnenwneeneseenwswsenene +seeeneneeenweneneeeenee +seeneeewseswnwseeseenwneseeeee +wweswwnwseewseswewswswnwnenw +nwwnwnwnwwwnwwnesewnwnewswseswne +swswswswwswsenwswsww +swwwsewwwwwwwnweewwnwwwe +wsewwwwwwwswwnwwwswwwwww +eeneeenweewsesweeeeneeneneenee +neneneneneneneseneeneswneswnewnenenenene +nenewsenwnewsewwseesewseneneswesee +nwnwnwnwnwnwnwnwnwnwnwsewnenwnwnwwnwnwnw +swwsewnenesewsweeseseswnesesesenwnese +nwwwswwwwswnewwwwwwwwwsene +sweeswswswnenwswswswnwswswswswswswwswsw +esesenenewwseneneseneenwswnewwewww +eseseneeseeseseseweseneeswesesese +swswswswnenwsesweseseseswswseswseseswseswse +eeeneneswneswneneeswswewenw +sesewnesewseseseseseseseneesesesesesese +seswswnesesesewswswseswneswnesesewswsese +neesewnwwswneswwswsewswwnww +eseewwseneswnewseneseseenwewswse +nwwnwwnwnwwswseenwwnwnwwwnwnwnwnw +wnwswwswwwnwwwnweneenwwswsewwnw +nwseseseseneeseseeseseseswsesesesesesese +nenwseeswnwwnwsenweswswswseese +nenenwnenwnenenwnwnenenenwswnenwnenwnene +enesenwswenwsesesenwswsenwsesesesenw +neneeeeeneseeenenwnenenenenenenee +sesesenewwseseseseswe +swseswnwswsewswswnwneeswswseewseseswswse +nwwnwnwnwwnwnwnwwnwwwnenwsewsewnwse +swnewneswwwsewswwnenenenwwewswwsw +swnwwnwsweeneeneeneeseseeneeeene +eeseewneneeseeeeeeeeseeweee +swswswswneseneswswwswwswseswseseneswswsw +senwnwnenwnwwnwnwnwnwswnwnwnwenwswnwnw +eeseseewseswneseneeenewsesesesenwse +swseswswswswseseswswswseseswswnesw +wwsenwnwsenwnenwnene +swswswsweswswswwswswswnwnewswseswswww +neneewswnenesweneesenwenewsweneseenw +swswseswsweneswnwwsenwswswse +nwsewsewwseneswnwwwswswwwwnwwww +nesesewseeseseseeseswseesesesesenwse +enenesenwsewswswnwseneeeeeeeeene +nenweneesesweeneeeneeeeeneene +wwswwwwwswswswnewswewwwenwsw +wwwwwswnwsewswwsewwwswwwnwsww +nesenenenewneneneneswswnenenenenenenenene +eeneeweesweeeeeeenesweew +swswswswseswseseneseswswseseswswseswsese +newnwswswswsweseswsww +nwswwnwsweswneswnwsenwnwsenenwneneee +wnwewswneswswswneweswwswwswswnweswsw +neswswswswswswwswewswswwswwswswswsw +swsewswswseswswswswswsweseswswswswswsw +nwwnwnwsewnenweswewnwwnwwswnwnww +swenenenenenenenwneneneneeswneneneenenw +wweswwwwswwswww +enweneenesweneneeeneeneeneneene +sesenewsenwseseseseswswswseseswswsenenesese +nenewneeswnesenwswnwnenwenwnwnwnw +neneswswnenenwswenwneeneseneneneewnww +neneeeneneenweeneeneneswneenenene +wwwwnwwwwwwswwwnwnwnewwww +swswswswwwnewwswwwwswwswwwww +nesweweneeeeeeeneweeeeene +nwnwnewnwnwnwsewnwwnwwnwwnwwswwww +wnwnwnwwwwswnwwwwnwew +senwnwnenwnwnwnwnwwnwnwnenwnwnwnwnwnenw +nwsewnenwnwnwnwnwnwnwnwnwwwnwwnwnwnwse +neswneseeswsweswneneenweeene +nenenwnwnwnenwnenenwnenwnwnwnweswnwsenwne +nwnwnewwnwnwnwwwswwnwnwnwwwwnwnw +seswwswswwswwswswswwswswwswswnwswsw +nwnwnwwnwsenwsenwnwsenwenwwnw +enwnwnwswnwsenwnwnenwnwenwsw +seneseswwswwesesenwewneenweseeewnw +swseesewewneesesenwnewseseseswsenw +nenwnwnenwnenwneenwsenenwnwnwnwnwnwnwwne +nwnwnenwnwnwwwnwwnwswnwnwwnwnwwww +seseseseseseseseseseswswsesesesesenesenwse +wswnwseseweeswseeneseeeneesesee +senewsweswseseseswsesesesesesese +neneneeeneeeneneeeenenweeneesw +nwnenenenenenenenenwswnenenenenenenenw +seseseseseseswsesewseseswsesenesw +eseeeeseseseeseseseseseesesewene +nwnwnwwnwnwnwnwnwwnwenwnwnwwnwwnwnw +seswseseenwswswwsesenwseeeeneesenesese +neeswseeseeeeeseeeeeeeseee diff --git a/data/advent24a.txt b/data/advent24a.txt new file mode 100644 index 0000000..55460d5 --- /dev/null +++ b/data/advent24a.txt @@ -0,0 +1,20 @@ +sesenwnenenewseeswwswswwnenewsewsw +neeenesenwnwwswnenewnwwsewnenwseswesw +seswneswswsenwwnwse +nwnwneseeswswnenewneswwnewseswneseene +swweswneswnenwsewnwneneseenw +eesenwseswswnenwswnwnwsewwnwsene +sewnenenenesenwsewnenwwwse +wenwwweseeeweswwwnwwe +wsweesenenewnwwnwsenewsenwwsesesenwne +neeswseenwwswnwswswnw +nenwswwsewswnenenewsenwsenwnesesenew +enewnwewneswsewnwswenweswnenwsenwsw +sweneswneswneneenwnewenewwneswswnese +swwesenesewenwneswnwwneseswwne +enesenwswwswneneswsenwnewswseenwsese +wnwnesenesenenwwnenwsewesewsesesew +nenewswnwewswnenesenwnesewesw +eneswnwswnwsenenwnwnwwseeswneewsenese +neswnwewnwnwseenwseesewsenwsweewe +wseweeenwnesenwwwswnew \ No newline at end of file diff --git a/problems/day24.html b/problems/day24.html new file mode 100644 index 0000000..308e0c1 --- /dev/null +++ b/problems/day24.html @@ -0,0 +1,183 @@ + + + + +Day 24 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 24: Lobby Layout ---

Your raft makes it to the tropical island; it turns out that the small crab was an excellent navigator. You make your way to the resort.

+

As you enter the lobby, you discover a small problem: the floor is being renovated. You can't even reach the check-in desk until they've finished installing the new tile floor.

+

The tiles are all hexagonal; they need to be arranged in a hex grid with a very specific color pattern. Not in the mood to wait, you offer to help figure out the pattern.

+

The tiles are all white on one side and black on the other. They start with the white side facing up. The lobby is large enough to fit whatever pattern might need to appear there.

+

A member of the renovation crew gives you a list of the tiles that need to be flipped over (your puzzle input). Each line in the list identifies a single tile that needs to be flipped by giving a series of steps starting from a reference tile in the very center of the room. (Every line starts from the same reference tile.)

+

Because the tiles are hexagonal, every tile has six neighbors: east, southeast, southwest, west, northwest, and northeast. These directions are given in your list, respectively, as e, se, sw, w, nw, and ne. A tile is identified by a series of these directions with no delimiters; for example, esenee identifies the tile you land on if you start at the reference tile and then move one tile east, one tile southeast, one tile northeast, and one tile east.

+

Each time a tile is identified, it flips from white to black or from black to white. Tiles might be flipped more than once. For example, a line like esew flips a tile immediately adjacent to the reference tile, and a line like nwwswee flips the reference tile itself.

+

Here is a larger example:

+
sesenwnenenewseeswwswswwnenewsewsw
+neeenesenwnwwswnenewnwwsewnenwseswesw
+seswneswswsenwwnwse
+nwnwneseeswswnenewneswwnewseswneseene
+swweswneswnenwsewnwneneseenw
+eesenwseswswnenwswnwnwsewwnwsene
+sewnenenenesenwsewnenwwwse
+wenwwweseeeweswwwnwwe
+wsweesenenewnwwnwsenewsenwwsesesenwne
+neeswseenwwswnwswswnw
+nenwswwsewswnenenewsenwsenwnesesenew
+enewnwewneswsewnwswenweswnenwsenwsw
+sweneswneswneneenwnewenewwneswswnese
+swwesenesewenwneswnwwneseswwne
+enesenwswwswneneswsenwnewswseenwsese
+wnwnesenesenenwwnenwsewesewsesesew
+nenewswnwewswnenesenwnesewesw
+eneswnwswnwsenenwnwnwwseeswneewsenese
+neswnwewnwnwseenwseesewsenwsweewe
+wseweeenwnesenwwwswnew
+
+

In the above example, 10 tiles are flipped once (to black), and 5 more are flipped twice (to black, then back to white). After all of these instructions have been followed, a total of 10 tiles are black.

+

Go through the renovation crew's list and determine which tiles they need to flip. After all of the instructions have been followed, how many tiles are left with the black side up?

+
+

Your puzzle answer was 538.

--- Part Two ---

The tile floor in the lobby is meant to be a living art exhibit. Every day, the tiles are all flipped according to the following rules:

+
    +
  • Any black tile with zero or more than 2 black tiles immediately adjacent to it is flipped to white.
  • +
  • Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black.
  • +
+

Here, tiles immediately adjacent means the six tiles directly touching the tile in question.

+

The rules are applied simultaneously to every tile; put another way, it is first determined which tiles need to be flipped, then they are all flipped at the same time.

+

In the above example, the number of black tiles that are facing up after the given number of days has passed is as follows:

+
Day 1: 15
+Day 2: 12
+Day 3: 25
+Day 4: 14
+Day 5: 23
+Day 6: 28
+Day 7: 41
+Day 8: 37
+Day 9: 49
+Day 10: 37
+
+Day 20: 132
+Day 30: 259
+Day 40: 406
+Day 50: 566
+Day 60: 788
+Day 70: 1106
+Day 80: 1373
+Day 90: 1844
+Day 100: 2208
+
+

After executing this process a total of 100 times, there would be 2208 black tiles facing up.

+

How many tiles will be black after 100 days?

+
+

Your puzzle answer was 4259.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 021f4ba..0c9524d 100644 --- a/stack.yaml +++ b/stack.yaml @@ -58,6 +58,7 @@ packages: - advent21 - advent22 - advent23 +- advent24 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From 6cf726976e228ca8cf2aa4e2b9458add2cc62416 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 10 Jan 2021 14:20:48 +0000 Subject: [PATCH 14/16] Done day 25 --- advent25/package.yaml | 60 +++++++++++++++ advent25/src/advent25.hs | 43 +++++++++++ data/advent25.txt | 2 + problems/day25.html | 154 +++++++++++++++++++++++++++++++++++++++ stack.yaml | 1 + 5 files changed, 260 insertions(+) create mode 100644 advent25/package.yaml create mode 100644 advent25/src/advent25.hs create mode 100644 data/advent25.txt create mode 100644 problems/day25.html diff --git a/advent25/package.yaml b/advent25/package.yaml new file mode 100644 index 0000000..cb87dbb --- /dev/null +++ b/advent25/package.yaml @@ -0,0 +1,60 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent25 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NamedFieldPuns +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeFamilies +- TypeInType +- TypeOperators +- ViewPatterns + + +executables: + advent25: + main: advent25.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - arithmoi diff --git a/advent25/src/advent25.hs b/advent25/src/advent25.hs new file mode 100644 index 0000000..548f71e --- /dev/null +++ b/advent25/src/advent25.hs @@ -0,0 +1,43 @@ +-- import Debug.Trace + +-- import Math.NumberTheory.Moduli.DiscreteLogarithm +-- import Data.Finite (Finite, modulo, getFinite) +-- import GHC.TypeNats (KnownNat) +-- import Data.Maybe + +import Data.Semigroup + +newtype MExp = MExp Integer + deriving (Show, Eq) + +instance Semigroup MExp where + (MExp a) <> (MExp b) = MExp $ (a * b) `mod` modularBase + + +subject :: MExp +subject = MExp 7 + +modularBase :: Integer +modularBase = 20201227 + +main :: IO () +main = + do text <- readFile "data/advent25.txt" + let [cardKey, doorKey] = map read $ lines text + print $ part1 cardKey doorKey + +part1 cardKey doorKey = publicKey + where cardRounds = findRounds cardKey + MExp publicKey = stimes cardRounds (MExp doorKey) + +findRounds :: Integer -> Integer +findRounds target = fst $ until (foundRounds t) countingExponential (0, seed) + where t = MExp target + seed = MExp 1 + +foundRounds :: MExp -> (Integer, MExp) -> Bool +foundRounds target (_n, v) = v == target + +countingExponential :: (Integer, MExp) -> (Integer, MExp) +countingExponential (n, v) = (n + 1, v <> subject) + diff --git a/data/advent25.txt b/data/advent25.txt new file mode 100644 index 0000000..89d2212 --- /dev/null +++ b/data/advent25.txt @@ -0,0 +1,2 @@ +12578151 +5051300 \ No newline at end of file diff --git a/problems/day25.html b/problems/day25.html new file mode 100644 index 0000000..a43d9db --- /dev/null +++ b/problems/day25.html @@ -0,0 +1,154 @@ + + + + +Day 25 - Advent of Code 2020 + + + + + + + +
+ + + +
+ +

--- Day 25: Combo Breaker ---

You finally reach the check-in desk. Unfortunately, their registration systems are currently offline, and they cannot check you in. Noticing the look on your face, they quickly add that tech support is already on the way! They even created all the room keys this morning; you can take yours now and give them your room deposit once the registration system comes back online.

+

The room key is a small RFID card. Your room is on the 25th floor and the elevators are also temporarily out of service, so it takes what little energy you have left to even climb the stairs and navigate the halls. You finally reach the door to your room, swipe your card, and - beep - the light turns red.

+

Examining the card more closely, you discover a phone number for tech support.

+

"Hello! How can we help you today?" You explain the situation.

+

"Well, it sounds like the card isn't sending the right command to unlock the door. If you go back to the check-in desk, surely someone there can reset it for you." Still catching your breath, you describe the status of the elevator and the exact number of stairs you just had to climb.

+

"I see! Well, your only other option would be to reverse-engineer the cryptographic handshake the card does with the door and then inject your own commands into the data stream, but that's definitely impossible." You thank them for their time.

+

Unfortunately for the door, you know a thing or two about cryptographic handshakes.

+

The handshake used by the card and the door involves an operation that transforms a subject number. To transform a subject number, start with the value 1. Then, a number of times called the loop size, perform the following steps:

+
    +
  • Set the value to itself multiplied by the subject number.
  • +
  • Set the value to the remainder after dividing the value by 20201227.
  • +
+

The card always uses a specific, secret loop size when it transforms a subject number. The door always uses a different, secret loop size.

+

The cryptographic handshake works like this:

+
    +
  • The card transforms the subject number of 7 according to the card's secret loop size. The result is called the card's public key.
  • +
  • The door transforms the subject number of 7 according to the door's secret loop size. The result is called the door's public key.
  • +
  • The card and door use the wireless RFID signal to transmit the two public keys (your puzzle input) to the other device. Now, the card has the door's public key, and the door has the card's public key. Because you can eavesdrop on the signal, you have both public keys, but neither device's loop size.
  • +
  • The card transforms the subject number of the door's public key according to the card's loop size. The result is the encryption key.
  • +
  • The door transforms the subject number of the card's public key according to the door's loop size. The result is the same encryption key as the card calculated.
  • +
+

If you can use the two public keys to determine each device's loop size, you will have enough information to calculate the secret encryption key that the card and door use to communicate; this would let you send the unlock command directly to the door!

+

For example, suppose you know that the card's public key is 5764801. With a little trial and error, you can work out that the card's loop size must be 8, because transforming the initial subject number of 7 with a loop size of 8 produces 5764801.

+

Then, suppose you know that the door's public key is 17807724. By the same process, you can determine that the door's loop size is 11, because transforming the initial subject number of 7 with a loop size of 11 produces 17807724.

+

At this point, you can use either device's loop size with the other device's public key to calculate the encryption key. Transforming the subject number of 17807724 (the door's public key) with a loop size of 8 (the card's loop size) produces the encryption key, 14897079. (Transforming the subject number of 5764801 (the card's public key) with a loop size of 11 (the door's loop size) produces the same encryption key: 14897079.)

+

What encryption key is the handshake trying to establish?

+
+

Your puzzle answer was 296776.

--- Part Two ---

The light turns green and the door unlocks. As you collapse onto the bed in your room, your pager goes off!

+

"It's an emergency!" the Elf calling you explains. "The soft serve machine in the cafeteria on sub-basement 7 just failed and you're the only one that knows how to fix it! We've already dispatched a reindeer to your location to pick you up."

+

You hear the sound of hooves landing on your balcony.

+

The reindeer carefully explores the contents of your room while you figure out how you're going to pay the 50 stars you owe the resort before you leave. Noticing that you look concerned, the reindeer wanders over to you; you see that it's carrying a small pouch.

+

"Sorry for the trouble," a note in the pouch reads. Sitting at the bottom of the pouch is a gold coin with a little picture of a starfish on it.

+

Looks like you only needed 49 stars after all.

+
+

If you like, you can .

+

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, all that is left is for you to admire your Advent calendar.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 0c9524d..3c1855f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -59,6 +59,7 @@ packages: - advent22 - advent23 - advent24 +- advent25 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as -- 2.34.1 From bb87fe8d48a7debc85dcbff2c08a7d8267427a77 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Mon, 11 Jan 2021 16:54:51 +0000 Subject: [PATCH 15/16] Added some profiling/performance data --- profiling/performance.csv | 26 + profiling/performance.md | 27 + profiling/profiling.ipynb | 1971 ++++++++++++++++++++++++++++++ profiling/run_times_combined.png | Bin 0 -> 15887 bytes profiling/run_times_linear.png | Bin 0 -> 14843 bytes profiling/run_times_log.png | Bin 0 -> 14648 bytes profiling/time-results.csv | 27 + profiling/time-results.md | 27 + 8 files changed, 2078 insertions(+) create mode 100644 profiling/performance.csv create mode 100644 profiling/performance.md create mode 100644 profiling/profiling.ipynb create mode 100644 profiling/run_times_combined.png create mode 100644 profiling/run_times_linear.png create mode 100644 profiling/run_times_log.png create mode 100644 profiling/time-results.csv create mode 100644 profiling/time-results.md diff --git a/profiling/performance.csv b/profiling/performance.csv new file mode 100644 index 0000000..d45e34d --- /dev/null +++ b/profiling/performance.csv @@ -0,0 +1,26 @@ +program,total_alloc,Max memory,elapsed_adj +advent01,107029176,72440,0.040000000000000036 +advent02,35370072,72440,0.06 +advent03,4017640,72504,0.020000000000000018 +advent04,60820368,72504,0.08000000000000002 +advent05,27810256,72440,0.08000000000000002 +advent06,11624856,72504,0.06 +advent07,21605440,72444,0.040000000000000036 +advent08,74894192,72508,0.09000000000000002 +advent09,793279616,72508,0.31000000000000005 +advent10,924456,72444,0.010000000000000009 +advent11,35282262592,72504,16.4 +advent12,2206400,72508,0.030000000000000027 +advent13,542152,72436,0.010000000000000009 +advent14,259113488,72508,0.26 +advent15,6662932672,240372,1.7999999999999998 +advent16,17242880,72444,0.030000000000000027 +advent17,4808712520,72444,1.42 +advent18,21509984,72444,0.040000000000000036 +advent19,44456496,72504,0.11000000000000004 +advent20,3860804096,72436,3.77 +advent21,9561880,72508,0.040000000000000036 +advent22,3242847728,72500,1.67 +advent23,10263690000,95500,1.56 +advent24,4352105528,72504,3.13 +advent25,39231576,72504,0.06 diff --git a/profiling/performance.md b/profiling/performance.md new file mode 100644 index 0000000..d224b26 --- /dev/null +++ b/profiling/performance.md @@ -0,0 +1,27 @@ +| Program | Total allocations | Max memory | Time | +|----------|------------------:|-----------:|-----:| +| advent01 | 107029176 | 72440 | 0.04 | +| advent02 | 35370072 | 72440 | 0.06 | +| advent03 | 4017640 | 72504 | 0.02 | +| advent04 | 60820368 | 72504 | 0.08 | +| advent05 | 27810256 | 72440 | 0.08 | +| advent06 | 11624856 | 72504 | 0.06 | +| advent07 | 21605440 | 72444 | 0.04 | +| advent08 | 74894192 | 72508 | 0.09 | +| advent09 | 793279616 | 72508 | 0.31 | +| advent10 | 924456 | 72444 | 0.01 | +| advent11 | 35282262592 | 72504 | 16.4 | +| advent12 | 2206400 | 72508 | 0.03 | +| advent13 | 542152 | 72436 | 0.01 | +| advent14 | 259113488 | 72508 | 0.26 | +| advent15 | 6662932672 | 240372 | 1.80 | +| advent16 | 17242880 | 72444 | 0.03 | +| advent17 | 4808712520 | 72444 | 1.42 | +| advent18 | 21509984 | 72444 | 0.04 | +| advent19 | 44456496 | 72504 | 0.11 | +| advent20 | 3860804096 | 72436 | 3.77 | +| advent21 | 9561880 | 72508 | 0.04 | +| advent22 | 3242847728 | 72500 | 1.67 | +| advent23 | 10263690000 | 95500 | 1.56 | +| advent24 | 4352105528 | 72504 | 3.13 | +| advent25 | 39231576 | 72504 | 0.06 | diff --git a/profiling/profiling.ipynb b/profiling/profiling.ipynb new file mode 100644 index 0000000..d70223f --- /dev/null +++ b/profiling/profiling.ipynb @@ -0,0 +1,1971 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "Collapsed": "false" + }, + "outputs": [], + "source": [ + "import glob\n", + "import json\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "Collapsed": "false" + }, + "outputs": [], + "source": [ + "! for i in {01..25}; do stack build --executable-profiling --ghc-options=\"-O2 -threaded -fprof-auto -rtsopts\" advent${i} ; stack exec --profile -- advent${i} +RTS -pj ; done\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(glob.glob('*prof'))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "Collapsed": "false", + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'program': 'advent01',\n", + " 'total_time': 0.48,\n", + " 'total_alloc': 107029176,\n", + " 'total_ticks': 1644,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent16',\n", + " 'total_time': 0.15,\n", + " 'total_alloc': 17242880,\n", + " 'total_ticks': 528,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent23',\n", + " 'total_time': 72.61,\n", + " 'total_alloc': 10263690000,\n", + " 'total_ticks': 247608,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent15loop',\n", + " 'total_time': 42.69,\n", + " 'total_alloc': 8838275776,\n", + " 'total_ticks': 145584,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent24',\n", + " 'total_time': 26.45,\n", + " 'total_alloc': 4352105528,\n", + " 'total_ticks': 90180,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent21',\n", + " 'total_time': 0.15,\n", + " 'total_alloc': 9561880,\n", + " 'total_ticks': 528,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent19',\n", + " 'total_time': 0.24,\n", + " 'total_alloc': 44456496,\n", + " 'total_ticks': 816,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent08',\n", + " 'total_time': 0.4,\n", + " 'total_alloc': 74894192,\n", + " 'total_ticks': 1356,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent12',\n", + " 'total_time': 0.03,\n", + " 'total_alloc': 2206400,\n", + " 'total_ticks': 108,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent20',\n", + " 'total_time': 34.74,\n", + " 'total_alloc': 3860804096,\n", + " 'total_ticks': 118476,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent04',\n", + " 'total_time': 0.44,\n", + " 'total_alloc': 60820368,\n", + " 'total_ticks': 1512,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent09',\n", + " 'total_time': 3.5,\n", + " 'total_alloc': 793279616,\n", + " 'total_ticks': 11928,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent10',\n", + " 'total_time': 0.01,\n", + " 'total_alloc': 924456,\n", + " 'total_ticks': 36,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent13',\n", + " 'total_time': 0.01,\n", + " 'total_alloc': 542152,\n", + " 'total_ticks': 36,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent02',\n", + " 'total_time': 0.26,\n", + " 'total_alloc': 35370072,\n", + " 'total_ticks': 876,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent06',\n", + " 'total_time': 0.11,\n", + " 'total_alloc': 11624856,\n", + " 'total_ticks': 372,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent15',\n", + " 'total_time': 43.83,\n", + " 'total_alloc': 6662932672,\n", + " 'total_ticks': 149460,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent17',\n", + " 'total_time': 21.33,\n", + " 'total_alloc': 4808712520,\n", + " 'total_ticks': 72744,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent14',\n", + " 'total_time': 1.66,\n", + " 'total_alloc': 259113488,\n", + " 'total_ticks': 5676,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent18',\n", + " 'total_time': 0.51,\n", + " 'total_alloc': 21509984,\n", + " 'total_ticks': 1728,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent25',\n", + " 'total_time': 0.35,\n", + " 'total_alloc': 39231576,\n", + " 'total_ticks': 1200,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent11',\n", + " 'total_time': 112.58,\n", + " 'total_alloc': 35282262592,\n", + " 'total_ticks': 383916,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent07',\n", + " 'total_time': 0.33,\n", + " 'total_alloc': 21605440,\n", + " 'total_ticks': 1128,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent03',\n", + " 'total_time': 0.06,\n", + " 'total_alloc': 4017640,\n", + " 'total_ticks': 192,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent22',\n", + " 'total_time': 22.64,\n", + " 'total_alloc': 3242847728,\n", + " 'total_ticks': 77208,\n", + " 'initial_capabilities': 12},\n", + " {'program': 'advent05',\n", + " 'total_time': 0.09,\n", + " 'total_alloc': 27810256,\n", + " 'total_ticks': 312,\n", + " 'initial_capabilities': 12}]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "profs = []\n", + "for fn in glob.glob('*prof'):\n", + " with open(fn) as f:\n", + " j = json.load(f)\n", + " prof = {}\n", + " for n in 'program total_time total_alloc total_ticks initial_capabilities'.split():\n", + " prof[n] = j[n]\n", + " profs.append(prof)\n", + "profs" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
total_timetotal_alloctotal_ticksinitial_capabilities
program
advent010.48107029176164412
advent020.263537007287612
advent030.06401764019212
advent040.4460820368151212
advent050.092781025631212
advent060.111162485637212
advent070.3321605440112812
advent080.4074894192135612
advent093.507932796161192812
advent100.019244563612
advent11112.583528226259238391612
advent120.03220640010812
advent130.015421523612
advent141.66259113488567612
advent1543.83666293267214946012
advent15loop42.69883827577614558412
advent160.151724288052812
advent1721.3348087125207274412
advent180.5121509984172812
advent190.244445649681612
advent2034.74386080409611847612
advent210.15956188052812
advent2222.6432428477287720812
advent2372.611026369000024760812
advent2426.4543521055289018012
advent250.3539231576120012
\n", + "
" + ], + "text/plain": [ + " total_time total_alloc total_ticks initial_capabilities\n", + "program \n", + "advent01 0.48 107029176 1644 12\n", + "advent02 0.26 35370072 876 12\n", + "advent03 0.06 4017640 192 12\n", + "advent04 0.44 60820368 1512 12\n", + "advent05 0.09 27810256 312 12\n", + "advent06 0.11 11624856 372 12\n", + "advent07 0.33 21605440 1128 12\n", + "advent08 0.40 74894192 1356 12\n", + "advent09 3.50 793279616 11928 12\n", + "advent10 0.01 924456 36 12\n", + "advent11 112.58 35282262592 383916 12\n", + "advent12 0.03 2206400 108 12\n", + "advent13 0.01 542152 36 12\n", + "advent14 1.66 259113488 5676 12\n", + "advent15 43.83 6662932672 149460 12\n", + "advent15loop 42.69 8838275776 145584 12\n", + "advent16 0.15 17242880 528 12\n", + "advent17 21.33 4808712520 72744 12\n", + "advent18 0.51 21509984 1728 12\n", + "advent19 0.24 44456496 816 12\n", + "advent20 34.74 3860804096 118476 12\n", + "advent21 0.15 9561880 528 12\n", + "advent22 22.64 3242847728 77208 12\n", + "advent23 72.61 10263690000 247608 12\n", + "advent24 26.45 4352105528 90180 12\n", + "advent25 0.35 39231576 1200 12" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "performance = pd.DataFrame(profs).set_index('program').sort_index()\n", + "performance" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance.total_time.plot.bar()" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance.total_time.plot.bar(logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAFMCAYAAADbSkeTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAfIUlEQVR4nO3deZRdZZnv8e/PJIwJk6kLSAJRBHFYECAEEFpAEeMELYIXtBG4cLNUWNDd9l0X7XtB6W4XtktsFUWj0kI3KIKowUYFZFBQhiKEDAQlylTChWJKQAEJPPeP/UYOJ3ufIXWqzq63fp+19soe3mfv56R2PbXPuydFBGZmNv69ot8JmJlZb7igm5llwgXdzCwTLuhmZplwQTczy4QLuplZJvpa0CWdJ+kRScs6aPsWSYskrZF0RNOyYyXdnYZjRy9jM7P66vcR+reBeR22vR84DriocaakrYAzgL2BucAZkrbsXYpmZuNDXwt6RPwCeLxxnqQdJf1U0m2Sfilpl9T23ohYArzYtJp3AFdFxOMR8QRwFZ3/kTAzy8bkfidQYgHwkYi4W9LewFeBt7Zovx3wQMP0UJpnZjah1KqgS5oKvBm4RNLa2Ru2CyuZ5+cZmNmEU6uCTtEF9GREzO4iZgg4sGF6BnBdD3MyMxsX+n1S9GUiYjVwj6QjAVTYrU3Yz4BDJG2ZToYekuaZmU0o/b5s8TvAr4HXSRqSdALwIeAESXcAy4HDUtu9JA0BRwJfl7QcICIeB/4JuDUNZ6Z5ZmYTivz4XDOzPNSqy8XMzNafC7qZWSb6dpXL9OnTY9asWf3avJnZuHTbbbc9GhEDZcv6VtBnzZrF4OBgvzZvZjYuSbqvapm7XMzMMuGCbmaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmWhb0CVtJOkWSXdIWi7p0yVtjpM0LGlxGk4cnXTNzKxKJ9ehPwe8NSKeljQFuEHSTyLipqZ2F0fEyb1P0czMOtG2oEfx9K6n0+SUNPiJXtZTs077r8pl95717jHMxGz86qgPXdIkSYuBRyje33lzSbP3S1oi6VJJM3uapZmZtdVRQY+IF9JbhGYAcyW9qanJ5cCsiNgVuBo4v2w9kuZLGpQ0ODw8PJK8zcysSVdXuUTEkxSvd5vXNP+xiHguTX4D2LMifkFEzImIOQMDpc+WMTOz9dTJVS4DkrZI4xsDBwN3NbXZtmHyUGBFL5M0M7P2OrnKZVvgfEmTKP4AfC8ifizpTGAwIhYCp0g6FFgDPA4cN1oJm5lZuU6uclkC7F4y//SG8U8An+htamZm1g3fKWpmlgkXdDOzTLigm5llwgXdzCwTLuhmZplwQTczy4QLuplZJlzQzcwy4YJuZpYJF3Qzs0y4oJuZZcIF3cwsEy7oZmaZcEE3M8uEC7qZWSZc0M3MMuGCbmaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmWhb0CVtJOkWSXdIWi7p0yVtNpR0saSVkm6WNGs0kjUzs2qdHKE/B7w1InYDZgPzJO3T1OYE4ImIeC3wBeCzvU3TzMzaaVvQo/B0mpyShmhqdhhwfhq/FHibJPUsSzMza6ujPnRJkyQtBh4BroqIm5uabAc8ABARa4BVwCtL1jNf0qCkweHh4ZFlbmZmL9NRQY+IFyJiNjADmCvpTU1Nyo7Gm4/iiYgFETEnIuYMDAx0n62ZmVXq6iqXiHgSuA6Y17RoCJgJIGkysDnweA/yMzOzDnVylcuApC3S+MbAwcBdTc0WAsem8SOAayJinSN0MzMbPZM7aLMtcL6kSRR/AL4XET+WdCYwGBELgW8B/yFpJcWR+VGjlrGZmZVqW9AjYgmwe8n80xvGnwWO7G1qZmbWDd8pamaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmXBBNzPLhAu6mVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwTLuhmZplwQTczy4QLuplZJlzQzcwy4YJuZpYJF3Qzs0y4oJuZZcIF3cwsE20LuqSZkq6VtELSckmnlrQ5UNIqSYvTcHrZuszMbPRM7qDNGuDjEbFI0jTgNklXRcSdTe1+GRHv6X2KZmbWibZH6BHxUEQsSuNPASuA7UY7MTMz605XfeiSZgG7AzeXLN5X0h2SfiLpjRXx8yUNShocHh7uOlkzM6vWcUGXNBX4PvC3EbG6afEiYIeI2A34MvDDsnVExIKImBMRcwYGBtY3ZzMzK9FRQZc0haKYXxgRlzUvj4jVEfF0Gr8CmCJpek8zNTOzljq5ykXAt4AVEXF2RZttUjskzU3rfayXiZqZWWudXOWyH3AMsFTS4jTvk8D2ABHxNeAI4KOS1gDPAEdFRIxCvmZmVqFtQY+IGwC1aXMOcE6vkjIzs+75TlEzs0y4oJuZZcIF3cwsEy7oZmaZcEE3M8uEC7qZWSZc0M3MMuGCbmaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmXBBNzPLhAu6mVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwTLuhmZploW9AlzZR0raQVkpZLOrWkjSR9SdJKSUsk7TE66ZqZWZXJHbRZA3w8IhZJmgbcJumqiLizoc07gZ3SsDdwbvrXzMzGSNsj9Ih4KCIWpfGngBXAdk3NDgMuiMJNwBaStu15tmZmVqmrPnRJs4DdgZubFm0HPNAwPcS6Rd/MzEZRxwVd0lTg+8DfRsTq5sUlIVGyjvmSBiUNDg8Pd5epmZm11FFBlzSFophfGBGXlTQZAmY2TM8AHmxuFBELImJORMwZGBhYn3zNzKxCJ1e5CPgWsCIizq5othD4cLraZR9gVUQ81MM8zcysjU6uctkPOAZYKmlxmvdJYHuAiPgacAXwLmAl8Cfg+N6namZmrbQt6BFxA+V95I1tAjipV0mZmVn3fKeomVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwTLuhmZplwQTczy4QLuplZJlzQzcwy4YJuZpYJF3Qzs0y4oJuZZcIF3cwsEy7oZmaZcEE3M8uEC7qZWSZc0M3MMuGCbmaWCRd0M7NMuKCbmWWibUGXdJ6kRyQtq1h+oKRVkhan4fTep2lmZu1M7qDNt4FzgAtatPllRLynJxmZmdl6aXuEHhG/AB4fg1zMzGwEetWHvq+kOyT9RNIbqxpJmi9pUNLg8PBwjzZtZmbQm4K+CNghInYDvgz8sKphRCyIiDkRMWdgYKAHmzYzs7VGXNAjYnVEPJ3GrwCmSJo+4szMzKwrIy7okraRpDQ+N63zsZGu18zMutP2KhdJ3wEOBKZLGgLOAKYARMTXgCOAj0paAzwDHBURMWoZm5lZqbYFPSKObrP8HIrLGs3MrI98p6iZWSZc0M3MMuGCbmaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmXBBNzPLhAu6mVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwTLuhmZplwQTczy4QLuplZJlzQzcwy4YJuZpYJF3Qzs0y0LeiSzpP0iKRlFcsl6UuSVkpaImmP3qdpZmbtdHKE/m1gXovl7wR2SsN84NyRp2VmZt2a3K5BRPxC0qwWTQ4DLoiIAG6StIWkbSPioR7laGbWV7NO+6/S+fee9e4xzqS1XvShbwc80DA9lOatQ9J8SYOSBoeHh3uwaTMzW6sXBV0l86KsYUQsiIg5ETFnYGCgB5s2M7O1elHQh4CZDdMzgAd7sF4zM+tCLwr6QuDD6WqXfYBV7j83Mxt7bU+KSvoOcCAwXdIQcAYwBSAivgZcAbwLWAn8CTh+tJI1M7NqnVzlcnSb5QGc1LOMzMxsvfhOUTOzTLQ9QjezsTFernW2+vIRuplZJlzQzcwy4YJuZpYJF3Qzs0y4oJuZZcIF3cwsEy7oZmaZcEE3M8uEC7qZWSZc0M3MMuGCbmaWCRd0M7NM+OFcZqPAD9qyfvARuplZJlzQzcwy4YJuZpYJF3Qzs0y4oJuZZaKjgi5pnqTfSFop6bSS5cdJGpa0OA0n9j5VMzNrpe1li5ImAV8B3g4MAbdKWhgRdzY1vTgiTh6FHM3MrAOdHKHPBVZGxO8j4s/Ad4HDRjctMzPrVicFfTvggYbpoTSv2fslLZF0qaSZPcnOzMw61klBV8m8aJq+HJgVEbsCVwPnl65Imi9pUNLg8PBwd5mamVlLndz6PwQ0HnHPAB5sbBARjzVMfgP4bNmKImIBsABgzpw5zX8UzGyUVT2SAPxYghx0coR+K7CTpFdL2gA4CljY2EDStg2ThwIrepeimZl1ou0RekSskXQy8DNgEnBeRCyXdCYwGBELgVMkHQqsAR4HjhvFnM3MrERHT1uMiCuAK5rmnd4w/gngE71NzcxsfOpX15bvFDUzy4QLuplZJvyCCzOrBb8UZOR8hG5mlgkXdDOzTLjLxcwmlJy7dnyEbmaWCRd0M7NMuKCbmWXCBd3MLBMu6GZmmXBBNzPLhAu6mVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwTLuhmZplwQTczy4Qfn2st9etlt2bWvY6O0CXNk/QbSSslnVayfENJF6flN0ua1etEzcystbYFXdIk4CvAO4E3AEdLekNTsxOAJyLitcAXgM/2OlEzM2utky6XucDKiPg9gKTvAocBdza0OQz4VBq/FDhHkiIiepirWV/k/IYby4va1VxJRwDzIuLENH0MsHdEnNzQZllqM5Smf5faPNq0rvnA/DT5OuA3FZudDjxasaxKtzFjsQ3HrF9MXfNyTH3zmkgxO0TEQGlERLQcgCOBbzZMHwN8uanNcmBGw/TvgFe2W3eLbQ6OdsxYbMMx/tnkFlPXvBxTDJ2cFB0CZjZMzwAerGojaTKwOfB4B+s2M7Me6aSg3wrsJOnVkjYAjgIWNrVZCBybxo8Aron0J8bMzMZG25OiEbFG0snAz4BJwHkRsVzSmRRfCRYC3wL+Q9JKiiPzo0aY14IxiBmLbThm/WLqmpdj6puXY+jgpKiZmY0PvvXfzCwTLuhmZplwQTczy4QLulmNSNpM0rR+52HjU20LuqTjWyzbRdLbJE1tmj+vRcxcSXul8TdI+ntJ7+oypwu6bL9/2s4hLdrsLWmzNL6xpE9LulzSZyVtXhFziqSZZcsq2m8g6cOSDk7TH5R0jqSTJE1pEbejpH+Q9EVJn5f0kaqcGmLeIelcSQsl/SiNV/5c2qzr9DbbOaH5QXCS/kdFe0n6gKQj0/jbJH1J0sckdfx7IOmaNsunN03/TdrOfElqETdH0lJgCbBM0h2S9qxo+z5JW6XxAUkXSFqaHpA3oyLmbEn7tft8TTFbSTpd0onp/+wfJf1Y0uckbdki7qC0f/1I0vclnSXptW22Vbv9pu77TOm66nqVi6T7I2L7kvmnACcBK4DZwKkR8aO0bFFE7FEScwbFw8UmA1cBewPXAQcDP4uIfymJab7WXsBBwDUAEXFoScwtETE3jf/PlOcPgEOAyyPirJKY5cBu6fLQBcCfKJ6H87Y0//CSmFXAHynuyP0OcElEDDe3a2h/YfrsmwBPAlOBy9I2FBHHlsScArwXuB54F7AYeAJ4H/CxiLiuJObfgJ2BCyhuNoPiRrQPA3dHxKlVOVbkXbUPfAbYH1iUcvy3iPhyWla1D3wV+G/ABsBqYEPg8vTZHi7LTdKS5lnp8/0GICJ2LYn5y/Yl/R/gr4CLgPcAQxHxdxWfdQlwUkT8Mk3vD3y1Yht3RsQb0vjFwE3AJRT784ci4u0lMcPAfcAAcDHwnYi4vSyXhpgrgKXAZsDr0/j3gLdT7JuHlcScBWwN/Bz4a+Ae4LfAx4DPRMQlJTG13G/qvs+U6vbW0l4OFEcjZcNS4LmKmKXA1DQ+CxikKOoAt7eImURR0FYDm6X5GwNLKmIWAf8JHAgckP59KI0fUBFze8P4rcBAGt8UWFoRs6Jxm03LFldth+Lb1SEU9wAMAz+luLlrWtn/c/p3MvAwMClNq8XnX9rQbhPgujS+fYv/599WzBfFL2bZstUVw1PAmha5TU7jWwBXAF9otw+kf6cAjwEbNPyfVP1sFqZ9YBdgh7S/PZDGd+hgH1gEbNqw3dLtpOU3djIvzf9Nw/htne4z6d+dgP9L8biOu4AzgJ0rYhY3/Pz+0OF2ljaMT177GYAtgWXjab+p+z5TNvS7y2Vrir/C7y0ZHquImRQRTwNExL0Uhfadks6m2AHKrImIFyLiT8DvImJ1in8GeLEiZg5wG/CPwKoojkifiYjrI+L6iphXSNpS0ispjnyH03b+CKypiFmml7qX7pA0B0DSzsDzFTERES9GxJURcQLwKuCrwDzg9xV5bQBMoyjOa7tNNqTYaapMbmg3LW34/hYxz0qaWzJ/L+DZipgngZ0iYrOmYRrFH9DSvCJiTcrnSYr9ZTNJl1AcTZVZ2/554NaI+HOaXgO8UBYQxbew71Pc4LFb2t+ej4j7IuK+iu1sLGn31F0yKf3s1263dDvJLZK+LulASQeko8PrJO0hqfkbx3WSzpS0cRr/ayi6OoBVFeuPlMfdEfFPEfFG4APARhSFrcwrUtfKTGDq2m6KtH9X/T+/uLY7iGK/nJS2+wTVv5913W/qvs+UJtC3geLocv+KZRdVzL8GmN00bzLF17UXKmJuBjZJ469omL85TUfFJbEzKL7OfgW4v03beykK6j3p323S/KlUH9FsDnybovvkZooi/nuKro7dKmJKj0LTso1L5v1dWud9wCkUX4e/QXHEckbFek6l+La0gOJI7vg0fwD4RUXMHukz3AlcmYYVad6eFTH/DMytWPbZivk/puRbUlrXixUxPyF9s2uavw1wS5uf66bA2RRHX0Nt2l7bNGyb5r+SFg9bKolrHK5pajuF4nHV96fhRYoj04uA7bvdZ1rkdDTFN7qHgfcDV1N0Wf4BmF8R89/TfnZlyu3dDftN1e90Lfebuu8zZUNt+9CrpJM+ayLi/5Us2y8ibiyZv2FEPFcyfzrFf97SDrb7bmC/iPjkeuS8CbB1RNzTos004DUUf5yGIuLhFm13jojfdpnDqwAi4kFJW1D0t94fEbe0iHkjRd/psoi4q4ttbQNsR3FENlT2sxqJdGRKFN+wmpdtFxF/6GJdm1J8xX2kg7a7AftGxNe6yTfFTgI2jOJbYs+oOEk9OSKqvtGubTc10jfbLtc/ieLb5hoVD96bTdH9UnUUTDpCfw3FexSe7GJb42K/qfM+0/eCns7izqX4QQbFkxxviRaJOab7mLHKq8W6dunmj8JEi0mF+QzgLWnW9cCZEVHVhTImeY1ljKQpUXQzNM6bHk3vVRjrmLrmVaqbw/leDxQn9VZSfLX5Zhp+muYd4pjexIxVXm1+1i27qyZ6DEW/66cpjmxfQ1HcL+t3XmMRQ3H12BDFyf0rgVkNy0q7RMcipq55tRo6eQXdaPoicHAUJw7+QtKrKU7UvN4xPYkZk7wkfalkPVB8hd6idIFj1toxIt7fMP1pSYv7mdcYfv5/Bd4RxVNcjwCuknRMRNxE9YnUsYipa16V+l3QJ/PSdaeN/kD1lRSO6T5mrPI6Hvg4sM75CooTbI6p9oyk/SPiBijOBwHr9PWOcV5jFbNBRCwHiIhLJa0ALpN0GunqnD7F1DWvSv0u6OcBt6p48fQDad5Miuepn+eYnsWMVV63UpxA/VXzAkmfckxlDMBHgfNTX7oo3itwbJ/zGquY5yVtE+kkaDpSfRvFVSk79jGmrnlVqsNJ0dcDh9FwdhtYGBF3OqZ3MWO0ja2AZ6Obs/KOaY7fDCDSvRL9zGsMYw4GhiPijqb5mwMnR/md3KMeU9e8Wuqmw320BtKdnu3mOWZkMXXNyzEBxf0IZ1Pc+TwIfB7YvN95Oaa+eZWuo5vGozVQfoa55Y0Qjuk+pq55OWb9rnKp62fJLaaueZUNfe1Dl3Q08EHg1Xr5w7CmUXHrv2O6j6lrXo55mW6ucqntZ8kppq55tdLvk6K/onjuwnSKr5hrPUVx27ljehNT17wc85JurnKp82fJKaaueVXq+0lRMwNJs4HzKfrS117lclw0nSgza6mb/pnRGoDDgbspnhS39hGYqx3T25i65uWYl8VtRnq8s39v6hFT17xK19FN49EaKG4nf71jRjemrnlN5Bjg71sN4+mz5BpT17zKhn73oa/1cESscMyox9Q1r4kcM5L3h9bts+QaU9e81lGLPnRJX6R4xvAPabhlOCIuc0zvYuqal2PWT50/S04xdc2rTF2O0DejeJdm48uUg+K9l47pXUxd85qwMWp6PKqkv6F4ZPEy4BvR+oirVp8l45i65rWOWhyhm01U6uULgm3C6/c7RQGQtLOkn0talqZ3TTu3Y3oYU9e8JnhM4+NRDwcOj4jzKW40OXicfZYsY+qaV6mRnFHt1UDxdpa5vPzt16VvCHfM+sfUNa+JHEPxvtbdgT2BO5qWlb6Htq6fJdeYuuZVNtSlD32TiLhFetmz3Nc4pucxdc1rIsc8RPFQLoDHJW0bEQ9JemWf83JM/fNaR10K+qOSdiQ9zF3FWzsqX0LrmPWOqWteEzYmIg6qiH+Sl94vOuZ5OWZc5LWubg7nR2ugeLrc1RRneP8A3ADs4JjextQ1L8dUrmOXOuQ10WPqmlfZUIurXCRNiogXJG0KvCIinnJM72PqmpdjKtdxf0Rs3++8JnpMXfMqU4urXIB7JC0A9gGedsyoxdQ1rwkbI+lLFcOXaf1S6VHNyzHjIq91dXM4P1oDsDHwAYoL6O8FzgH2d0xvY+qa10SOoXgA03yK94c2D4+Op8+Sa0xd8ypdRzeNx2IAtgQuAF5wzOjF1DWviRYDXAO8uSLunvH0WSZCTF3zWjvUpcsFSQdI+iqwCNiI4i+VY3ocU9e8JnDMEUDpm4ki4tV9zMsx4yCvdXRT/UdrAO4BfgAcDWzqmNGJqWtejglYv5cK1/Kz5BZT17zKhrpc5bJZRKx2zOjG1DUvx4AanunSMO/2iNi9n3k5pr55la6jnwU9ncmvTCAiTnHMyGPqmpdjQC+9IHh/4JcNi6ZR9J+u8zyXun6W3GLqmlcr/e5DHwRuo+gr2oPi9Ut3A7OBFxzTs5i65uWY4gXBn6d4psvnG4aPA/PG2WfJLaaueVVbn36aXg/AtcCUhukpwLWO6W1MXfNyjH9v6hxT17zKhn4foa/1Kl7+Kq6paZ5jehtT17wmfIykwyXdLWmVpNWSnpLUrj+1lp8lw5i65rWOujyc6yzgdknXpukDgE85pucxdc3LMfCvwHuju3dK1vWz5BZT17zWUYurXAAkvQo4BlgBbAI8GBG/cExvY+qa10SPkXRjROzXan3j5bPkGFPXvNbRTf/MaA3AicBS4AmKfqRngGsc09uYuublmAD4InAxxTXIh/PS24vG3WfJLaaueZWuo5vGozWkD7ER6Q0twC7AxY7pbUxd83JMAPx7yXBev/NyTH3zKhvq0of+bEQ8KwlJG0bEXZJe55iex9Q1rwkfExHHt1lfX/JyTK3zWkddCvqQpC2AHwJXSXoCeNAxPY+pa14TPkbSzsC5wNYR8SZJuwKHRsQ/j7fPkmFMXfNaR21Oiq4l6QBgc+CnEfFnx4xOTF3zmqgxkq4H/hfw9Ui3+0taFhFv6mdejhkfef0lrm4F3WwiknRrROylhue3SFocEbP7nZuNH3W5schsohv5C4JtwvMRulkNSHoNsAB4M8Vla/cAH4qI+/qamI0rLuhmNaAevCDYzF0uZvUw8hcE24Tngm5WD68DrgZOoiju50jav8852TjjLhezmpG0JcWjAD4UEZP6nY+NHz5CN6sJjfQFwTbh+QjdrAYk3QMsBr4HLIyIP/Y5JRuHXNDNakA9eEGwmQu6WR+phy8INnMfull/9e4FwTbh+QjdrAZUvHbskIh4Pk1PAa6MiIP6m5mNJz5CN6uHEb8g2Kwuz0M3m+hG/IJgM3e5mNWERvqCYJvwfIRuVgOSTgROBWZQXI++D/Br4K39zMvGF/ehm9XDqcBewH3pROjuwHB/U7LxxgXdrB6ejYhngb+8IJjigV1mHXOXi1k9jPgFwWY+KWpWM+v7gmAzF3Qzs0y4D93MLBMu6GZmmXBBNzPLhAu6TQiSRvQqN0m+IsxqzwXdxj1JsyTdJel8SUskXSppE0n3Sjpd0g3AkZJmS7optflBencnkvZK834t6XOSlqX5x0m6RNLlwJWSpkr6uaRFkpZKOqxp+9+UtEzShZIOlnSjpLslze3f/45NJC7olovXAQsiYldgNfCxNP/ZiNg/Ir4LXAD879RmKXBGavPvwEciYl/WfQb5vsCxEfFW4FngfRGxB3AQ8HlJSu1eS/Fi512BXYAPAvsD/wB8suef1qyEC7rl4oGIuDGN/ydFMQW4GEDS5sAWEXF9mn8+8JZ0M8+0iPhVmn9R03qviojH07iAz0haAlwNbAdsnZbdExFLI+JFYDnw8yiuCV4KzOrVhzRrxf2ClovmGyrWTrd72bLaLG+M/xAwAOwZEc9LupfiTUMAzzW0e7Fh+kX8e2ZjxEfolovtJe2bxo8GbmhcGBGrgCck/VWadQxwfUQ8ATwlaZ80/6gW29gceCQV84OAHXqXvtnIuaBbLlYAx6bukK2Ac0vaHAt8LrWZDZyZ5p8ALJD0a4oj9lUV27gQmCNpkOJo/a4e5m82Yr7138Y9SbOAH0fEm9YzfmpEPJ3GTwO2jYhTe5eh2dhw354ZvFvSJyh+H+4DjutvOmbrx0foZmaZcB+6mVkmXNDNzDLhgm5mlgkXdDOzTLigm5llwgXdzCwT/x90wbK0onr53AAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance.total_alloc.plot.bar()" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance.total_alloc.plot.bar(logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAFECAYAAAAkzoUKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3dfbRU5Xn38e/PI4gvQCwSTEACWjUaRDRHfNeYRMUkamLaKKaJWvqwrLrMsq0r2PoEk9iUJm1sGjSWJoqmEfEtKbGkKjGoKG1AcxAQjUQhHskTERU1iopezx97HxiOM4czZ87M7D3791lrL2bu2de+r3nhOvfce8/eigjMzKz17dDsBMzMrDFc8M3MCsIF38ysIFzwzcwKwgXfzKwgXPDNzArCBd/MrCBc8M3MCqJuBV/S3pJ+IOm2ntrMzKwxVM0vbSVdB3wKeC4ixpW0TwK+A7QB34+IGSWP3RYRf9JtO+9qK2ePPfaIMWPG9Do/M7Oie/jhh5+PiOHlHtuxym3NBmYCN3Y1SGoDrgZOBDqBJZLmRcRjfUt3qzFjxrB06dJaN2NmVhiS1lZ6rKopnYi4H3ihW/NEYHVEPBURbwI3A6dXnWVK0lRJSyUtXb9+fV83Y2Zm3fTHHP5I4JmS+53ASEnDJF0LHCLpMoBybd1FxKyIaI+I9uHDy34rMTOzPqh2SqcclWmLiNgAnN+t8V1tZmbWGP1R8DuBvUrujwLW9cN2y3rrrbfo7Oxk06ZN9eqikAYNGsSoUaMYMGBAs1Mxszrpj4K/BNhX0ljgWeAs4Ox+2G5ZnZ2dDB48mDFjxiCV+3Jh1YoINmzYQGdnJ2PHjm12OmZWJ1XN4UuaAywG9pfUKWlKRGwGLgLuAlYBt0TEyv5PNbFp0yaGDRvmYt+PJDFs2DB/azJrcVWN8CNicoX2+cD8fsmoF1zs+59fU7PW51MrmJkVRH/M4TfVmGn/1a/bWzPjkz0+/tJLL3HTTTdxwQUXVN7GmjU89NBDnH12z7sy1qxZw6c+9SlWrFhR9vGOjg7WrVvHJz7xCQDmzZvHY489xrRp07bzLArgiqEltzc2Lw+zHPEIv0ovvfQS11xzTY/rrFmzhptuuqnmvjo6Opg/f+tM2WmnneZib2Z9lvsRfqNNmzaN3/zmN0yYMIETTzwRgJ/97GdI4vLLL+fMM89k2rRprFq1igkTJnDOOefwmc98hi984Qv84Q9/AGDmzJkcddRRPfbz5ptv8pWvfIXXX3+dRYsWcdlll/H666+zdOlSZs6cybnnnsvOO+/M448/ztq1a7n++uu54YYbWLx4MYcffjizZ88G4O6772b69Om88cYb7LPPPlx//fXstttudX2NzCybPMKv0owZM9hnn33o6OjgiCOOoKOjg2XLlrFgwQIuvfRSfve73zFjxgyOPfZYOjo6uOSSS3jve9/LPffcwyOPPMLcuXO5+OKLt9vPwIED+drXvsaZZ55JR0cHZ5555rvWefHFF7n33nu56qqrOPXUU7nkkktYuXIly5cvp6Ojg+eff54rr7ySBQsW8Mgjj9De3s63v/3terwsZpYDHuHXYNGiRUyePJm2tjZGjBjB8ccfz5IlSxgyZMg267311ltcdNFFdHR00NbWxq9//et+6f/UU09FEgcddBAjRozgoIMOAuBDH/oQa9asobOzk8cee4yjjz4aSL41HHnkkf3St5nljwt+DXp7aumrrrqKESNGsGzZMt555x0GDRrUL/3vtNNOAOywww5bbnfd37x5M21tbZx44onMmTOnX/ozs3zzlE6VBg8ezCuvvALAcccdx9y5c3n77bdZv349999/PxMnTtxmHYCNGzfyvve9jx122IEf/vCHvP3221X31RdHHHEEDz74IKtXrwbgtdde67dvF2aWP7kf4W/vMMr+NmzYMI4++mjGjRvHKaecwvjx4zn44IORxDe/+U323HNPhg0bxo477sjBBx/MueeeywUXXMBnP/tZbr31Vk444QR23XXXXvV1wgknMGPGDCZMmMBll5U9uWiPhg8fzuzZs5k8eTJvvPEGAFdeeSX77bdf1dsys/yr6opXjdbe3h7dL4CyatUqDjjggCZl1Npy9dr6OHzLqtLPJjT88ynp4YhoL/dY7kf4ZoXU5KJi+eSCnwF33XUXX/7yl7dpGzt2LD/+8Y+blJGZtSIX/Aw4+eSTOfnkk5udhjWLR+vWID5Kx8ysIDzCN7PKvHO8pbjgm5k1W4P+sLrgm1k++dtH1fJf8Lvv8Kp5ez1/cBp5PvzexC1cuJB/+qd/4s4776xqG2bWCy22Q907bavUyPPhm5n1Jxf8KpWeD//SSy/l0ksvZdy4cRx00EHMnTt3yzoPPPAAEyZM4Kqr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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance[['total_time', 'total_alloc']].plot.bar(logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Elapsed time (s)Max memory
Program
advent010.3972440
advent020.4172440
advent030.3772504
advent040.4372504
advent050.4372440
advent060.4172504
advent070.3972444
advent080.4472508
advent090.6672508
advent100.3672444
advent1116.7572504
advent120.3872508
advent130.3672436
advent140.6172508
advent152.15240372
advent15loop1.88240444
advent160.3872444
advent171.7772444
advent180.3972444
advent190.4672504
advent204.1272436
advent210.3972508
advent222.0272500
advent231.9195500
advent243.4872504
advent250.4172504
\n", + "
" + ], + "text/plain": [ + " Elapsed time (s) Max memory\n", + "Program \n", + "advent01 0.39 72440\n", + "advent02 0.41 72440\n", + "advent03 0.37 72504\n", + "advent04 0.43 72504\n", + "advent05 0.43 72440\n", + "advent06 0.41 72504\n", + "advent07 0.39 72444\n", + "advent08 0.44 72508\n", + "advent09 0.66 72508\n", + "advent10 0.36 72444\n", + "advent11 16.75 72504\n", + "advent12 0.38 72508\n", + "advent13 0.36 72436\n", + "advent14 0.61 72508\n", + "advent15 2.15 240372\n", + "advent15loop 1.88 240444\n", + "advent16 0.38 72444\n", + "advent17 1.77 72444\n", + "advent18 0.39 72444\n", + "advent19 0.46 72504\n", + "advent20 4.12 72436\n", + "advent21 0.39 72508\n", + "advent22 2.02 72500\n", + "advent23 1.91 95500\n", + "advent24 3.48 72504\n", + "advent25 0.41 72504" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "times = pd.read_csv('time-results.csv').set_index('Program').sort_index()\n", + "times" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Elapsed time (s)Max memory
count26.00000026.000000
mean1.60576986280.615385
std3.25579545597.232922
min0.36000072436.000000
25%0.39000072444.000000
50%0.43000072504.000000
75%1.85250072508.000000
max16.750000240444.000000
\n", + "
" + ], + "text/plain": [ + " Elapsed time (s) Max memory\n", + "count 26.000000 26.000000\n", + "mean 1.605769 86280.615385\n", + "std 3.255795 45597.232922\n", + "min 0.360000 72436.000000\n", + "25% 0.390000 72444.000000\n", + "50% 0.430000 72504.000000\n", + "75% 1.852500 72508.000000\n", + "max 16.750000 240444.000000" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "times.describe()" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
total_timetotal_alloctotal_ticksinitial_capabilitiesElapsed time (s)Max memory
program
advent010.481070291761644120.3972440
advent020.2635370072876120.4172440
advent030.064017640192120.3772504
advent040.44608203681512120.4372504
advent050.0927810256312120.4372440
advent060.1111624856372120.4172504
advent070.33216054401128120.3972444
advent080.40748941921356120.4472508
advent093.5079327961611928120.6672508
advent100.0192445636120.3672444
advent11112.58352822625923839161216.7572504
advent120.032206400108120.3872508
advent130.0154215236120.3672436
advent141.662591134885676120.6172508
advent1543.836662932672149460122.15240372
advent160.1517242880528120.3872444
advent1721.33480871252072744121.7772444
advent180.51215099841728120.3972444
advent190.2444456496816120.4672504
advent2034.743860804096118476124.1272436
advent210.159561880528120.3972508
advent2222.64324284772877208122.0272500
advent2372.6110263690000247608121.9195500
advent2426.45435210552890180123.4872504
advent250.35392315761200120.4172504
\n", + "
" + ], + "text/plain": [ + " total_time total_alloc total_ticks initial_capabilities \\\n", + "program \n", + "advent01 0.48 107029176 1644 12 \n", + "advent02 0.26 35370072 876 12 \n", + "advent03 0.06 4017640 192 12 \n", + "advent04 0.44 60820368 1512 12 \n", + "advent05 0.09 27810256 312 12 \n", + "advent06 0.11 11624856 372 12 \n", + "advent07 0.33 21605440 1128 12 \n", + "advent08 0.40 74894192 1356 12 \n", + "advent09 3.50 793279616 11928 12 \n", + "advent10 0.01 924456 36 12 \n", + "advent11 112.58 35282262592 383916 12 \n", + "advent12 0.03 2206400 108 12 \n", + "advent13 0.01 542152 36 12 \n", + "advent14 1.66 259113488 5676 12 \n", + "advent15 43.83 6662932672 149460 12 \n", + "advent16 0.15 17242880 528 12 \n", + "advent17 21.33 4808712520 72744 12 \n", + "advent18 0.51 21509984 1728 12 \n", + "advent19 0.24 44456496 816 12 \n", + "advent20 34.74 3860804096 118476 12 \n", + "advent21 0.15 9561880 528 12 \n", + "advent22 22.64 3242847728 77208 12 \n", + "advent23 72.61 10263690000 247608 12 \n", + "advent24 26.45 4352105528 90180 12 \n", + "advent25 0.35 39231576 1200 12 \n", + "\n", + " Elapsed time (s) Max memory \n", + "program \n", + "advent01 0.39 72440 \n", + "advent02 0.41 72440 \n", + "advent03 0.37 72504 \n", + "advent04 0.43 72504 \n", + "advent05 0.43 72440 \n", + "advent06 0.41 72504 \n", + "advent07 0.39 72444 \n", + "advent08 0.44 72508 \n", + "advent09 0.66 72508 \n", + "advent10 0.36 72444 \n", + "advent11 16.75 72504 \n", + "advent12 0.38 72508 \n", + "advent13 0.36 72436 \n", + "advent14 0.61 72508 \n", + "advent15 2.15 240372 \n", + "advent16 0.38 72444 \n", + "advent17 1.77 72444 \n", + "advent18 0.39 72444 \n", + "advent19 0.46 72504 \n", + "advent20 4.12 72436 \n", + "advent21 0.39 72508 \n", + "advent22 2.02 72500 \n", + "advent23 1.91 95500 \n", + "advent24 3.48 72504 \n", + "advent25 0.41 72504 " + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "performance = performance.merge(times, left_index=True, right_index=True)\n", + "performance.drop(index='advent15loop', inplace=True)\n", + "performance" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['total_time', 'total_alloc', 'total_ticks', 'initial_capabilities',\n", + " 'Elapsed time (s)', 'Max memory'],\n", + " dtype='object')" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "performance.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance[['total_time', 'Elapsed time (s)']].plot.bar(logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
total_timetotal_alloctotal_ticksinitial_capabilitiesElapsed time (s)Max memoryelapsed_adj
program
advent010.481070291761644120.39724400.04
advent020.2635370072876120.41724400.06
advent030.064017640192120.37725040.02
advent040.44608203681512120.43725040.08
advent050.0927810256312120.43724400.08
advent060.1111624856372120.41725040.06
advent070.33216054401128120.39724440.04
advent080.40748941921356120.44725080.09
advent093.5079327961611928120.66725080.31
advent100.0192445636120.36724440.01
advent11112.58352822625923839161216.757250416.40
advent120.032206400108120.38725080.03
advent130.0154215236120.36724360.01
advent141.662591134885676120.61725080.26
advent1543.836662932672149460122.152403721.80
advent160.1517242880528120.38724440.03
advent1721.33480871252072744121.77724441.42
advent180.51215099841728120.39724440.04
advent190.2444456496816120.46725040.11
advent2034.743860804096118476124.12724363.77
advent210.159561880528120.39725080.04
advent2222.64324284772877208122.02725001.67
advent2372.6110263690000247608121.91955001.56
advent2426.45435210552890180123.48725043.13
advent250.35392315761200120.41725040.06
\n", + "
" + ], + "text/plain": [ + " total_time total_alloc total_ticks initial_capabilities \\\n", + "program \n", + "advent01 0.48 107029176 1644 12 \n", + "advent02 0.26 35370072 876 12 \n", + "advent03 0.06 4017640 192 12 \n", + "advent04 0.44 60820368 1512 12 \n", + "advent05 0.09 27810256 312 12 \n", + "advent06 0.11 11624856 372 12 \n", + "advent07 0.33 21605440 1128 12 \n", + "advent08 0.40 74894192 1356 12 \n", + "advent09 3.50 793279616 11928 12 \n", + "advent10 0.01 924456 36 12 \n", + "advent11 112.58 35282262592 383916 12 \n", + "advent12 0.03 2206400 108 12 \n", + "advent13 0.01 542152 36 12 \n", + "advent14 1.66 259113488 5676 12 \n", + "advent15 43.83 6662932672 149460 12 \n", + "advent16 0.15 17242880 528 12 \n", + "advent17 21.33 4808712520 72744 12 \n", + "advent18 0.51 21509984 1728 12 \n", + "advent19 0.24 44456496 816 12 \n", + "advent20 34.74 3860804096 118476 12 \n", + "advent21 0.15 9561880 528 12 \n", + "advent22 22.64 3242847728 77208 12 \n", + "advent23 72.61 10263690000 247608 12 \n", + "advent24 26.45 4352105528 90180 12 \n", + "advent25 0.35 39231576 1200 12 \n", + "\n", + " Elapsed time (s) Max memory elapsed_adj \n", + "program \n", + "advent01 0.39 72440 0.04 \n", + "advent02 0.41 72440 0.06 \n", + "advent03 0.37 72504 0.02 \n", + "advent04 0.43 72504 0.08 \n", + "advent05 0.43 72440 0.08 \n", + "advent06 0.41 72504 0.06 \n", + "advent07 0.39 72444 0.04 \n", + "advent08 0.44 72508 0.09 \n", + "advent09 0.66 72508 0.31 \n", + "advent10 0.36 72444 0.01 \n", + "advent11 16.75 72504 16.40 \n", + "advent12 0.38 72508 0.03 \n", + "advent13 0.36 72436 0.01 \n", + "advent14 0.61 72508 0.26 \n", + "advent15 2.15 240372 1.80 \n", + "advent16 0.38 72444 0.03 \n", + "advent17 1.77 72444 1.42 \n", + "advent18 0.39 72444 0.04 \n", + "advent19 0.46 72504 0.11 \n", + "advent20 4.12 72436 3.77 \n", + "advent21 0.39 72508 0.04 \n", + "advent22 2.02 72500 1.67 \n", + "advent23 1.91 95500 1.56 \n", + "advent24 3.48 72504 3.13 \n", + "advent25 0.41 72504 0.06 " + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "performance['elapsed_adj'] = performance['Elapsed time (s)'] - 0.35\n", + "performance" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEsCAYAAADAaQg9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3de5gU9ZX/8fcBQeQiKiAmohkUr8QBcUBdSZTgNYqi7gYwuqKuBlnWxF82T3DXRDQaiUHdGDRmskGiEUWNRlC8oTE8KiYgjly9oKCMuIIooARU4Pz+qGJohu65dNd0V3V9Xs9TD91V9a1zpqY48+1vVVeZuyMiIuWvVakTEBGR4lDBFxFJCRV8EZGUUMEXEUkJFXwRkZRQwRcRSYldSp1AQ7p27eoVFRWlTkNEJDFeeeWVj9y9W7ZlsS74FRUVzJ07t9RpiIgkhpm9m2uZhnRERFJCBV9EJCVU8EVEUiLWY/jZfPnll9TW1rJp06ZSp5Iq7dq1o0ePHrRp06bUqYhInhJX8Gtra+nUqRMVFRWYWanTSQV3Z82aNdTW1tKzZ89SpyMieUrckM6mTZvo0qWLin0RmRldunTRpyqRhCtawTezoWb2OzN71MxOLnBbUaUlTaR9LpJ8BRV8M5tkZqvMbGG9+aea2RtmttTMxgK4+5/d/VJgJDCskLgiItJ8hY7hTwYmAndvm2FmrYHbgZOAWmCOmU1z98XhKleHyyNRMfbxqDYFwPLxpze4fO3atUyZMoXRo0fn3sby5bz00kucd955DcdavpwzzjiDhQsXZl1eU1PDypUr+fa3vw3AtGnTWLx4MWPHjm3kp0iPzN9/Y787kbQrqIfv7rOAj+vNHgAsdfd33P0L4H7gLAv8AnjC3ecVEreU1q5dyx133NHgOsuXL2fKlCkFx6qpqWHGjBl1788880wVexHJW0tcpbMvsCLjfS1wNPAfwIlAZzPr5e53ZmtsZpcBlwHsv//+LZBeYcaOHcvbb79N3759OemkkwB44oknMDOuvvpqhg0bxtixY1myZAl9+/blwgsv5Oyzz+aCCy5gw4YNAEycOJF/+qd/ajDOF198wU9/+lM2btzICy+8wFVXXcXGjRuZO3cuEydOZOTIkey22268/vrrvPvuu9x111384Q9/YPbs2Rx99NFMnjwZgKeffpprrrmGzz//nAMPPJC77rqLjh07tug+EpF4aomTttnO7rm73+buR7n7qFzFPlyx2t2r3L2qW7es9/8pqfHjx3PggQdSU1PDMcccQ01NDa+99hozZ87kRz/6ER988AHjx4/nG9/4BjU1NVx55ZXsvffePPPMM8ybN4+pU6dyxRVXNBqnbdu2XHfddQwbNoyamhqGDdv5tMcnn3zCc889x6233sqQIUO48sorWbRoEQsWLKCmpoaPPvqI66+/npkzZzJv3jyqqqq45ZZbWmK3iEgCtEQPvxbYL+N9D2BlczZgZkOAIb169Yoyr8i98MILjBgxgtatW9O9e3eOP/545syZw+67777Del9++SVjxoyhpqaG1q1b8+abb0YSf8iQIZgZRxxxBN27d+eII44AoHfv3ixfvpza2loWL17McccdBwSfGo499thIYotI8rREwZ8DHGRmPYH3geFAw2cv63H36cD0qqqqS1sgv8i4e5PWu/XWW+nevTuvvfYaW7dupV27dpHE33XXXQFo1apV3ett7zdv3kzr1q056aSTuO+++yKJJyLJVuhlmfcBs4FDzKzWzC5x983AGOApYAnwgLsvKjzVeOjUqROffvopAN/85jeZOnUqW7ZsYfXq1cyaNYsBAwbssA7AunXr+MpXvkKrVq2455572LJlS7Nj5eOYY47hxRdfZOnSpQD84x//iOzThYgkT0E9fHcfkWP+DGBGtmVN0ZwhnWJfitelSxeOO+44vv71r3PaaadRWVlJnz59MDNuuukm9tlnH7p06cIuu+xCnz59GDlyJKNHj+bcc8/lwQcfZNCgQXTo0KFJsQYNGsT48ePp27cvV111VbNz7datG5MnT2bEiBF8/vnnAFx//fUcfPDBzd6WiCSfNXVYohSqqqq8/gNQlixZwmGHHVaijNItjvte1+GL7MjMXnH3qmzLEnfzNBGROElSpyOWBT8pV+lE5amnnuLHP/7xDvN69uzJI488UqKMRKQcxbLgJ+UqnaiccsopnHLKKaVOQ0TKXOJujywiIvmJZcE3syFmVr1u3bpSpyIiUjZiWfDdfbq7X9a5c+dSpyIiUjZiWfBFRCR6sTxp2yzjIv4UMC6/YaSKigrmzp1L165do82nESeccAITJkygqirrZbdN8vzzzzNhwgQee+wx3XNfpIzFsuCn7bLMODnzzDM588wzS52GiLSAWA7pxH0M/49//CMDBgygb9++fO9739vp3jhDhw7lqKOOonfv3lRXV9fN79ixIz/84Q/p168fgwcPZvXq1QDcdtttHH744VRWVjJ8+HAANmzYwMUXX0z//v058sgjefTRRwHYuHEjw4cPp7KykmHDhrFx48YGc7388supqqqid+/eXHPNNXXzn3zySQ499FAGDhzIww8/XDd/8uTJjBkzprAdJCKxFMsefpwtWbKEqVOn8uKLL9KmTRtGjx7Nvffeu8M6kyZNYq+99mLjxo3079+fc889ly5durBhwwb69evHzTffzHXXXce1117LxIkTGT9+PMuWLWPXXXdl7dq1ANxwww1861vfYtKkSaxdu5YBAwZw4okn8tvf/pb27dszf/585s+fT79+/RrM94YbbmCvvfZiy5YtDB48mPnz53PwwQdz6aWX8txzz9GrV6+s99oXkfKjgt9Mzz77LK+88gr9+/cHgh733nvvvcM6t912W923ZFesWMFbb71Fly5daNWqVV1xPf/88znnnHMAqKys5Lvf/S5Dhw5l6NChQPCkqmnTpjFhwgQANm3axHvvvcesWbPqHqBSWVlJZWVlg/k+8MADVFdXs3nzZj744AMWL17M1q1b6dmzJwcddFBdLpmfRKT0kvR1fUkOFfxmcncuvPBCbrzxxh3mb3uk4PPPP8/MmTOZPXs27du354QTTmDTpk1Zt2UWPBzs8ccfZ9asWUybNo2f/exnLFq0CHfnT3/6E4ccckjOdo1ZtmwZEyZMYM6cOey5556MHDmyLpembkNEykcsx/Dj/MWrwYMH89BDD7Fq1SoAPv74Y95999265evWrWPPPfekffv2vP7667z88st1y7Zu3cpDDz0EwJQpUxg4cCBbt25lxYoVDBo0iJtuuom1a9fy2Wefccopp/DrX/+67iErr776KhDcg3/bENLChQuZP39+zlzXr19Phw4d6Ny5Mx9++CFPPPEEAIceeijLli3j7bffBtADUkRSIpY9/GbdSyfPyyjzdfjhh3P99ddz8skns3XrVtq0acPtt99et/zUU0/lzjvvpLKykkMOOYRjjjmmblmHDh1YtGgRRx11FJ07d657eMr555/PunXrcHeuvPJK9thjD37yk5/wgx/8gMrKStydiooKHnvsMS6//HIuuugiKisr6du3LwMGDMiZa58+fTjy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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance[['total_time', 'elapsed_adj']].plot.bar(logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(ncols=2, figsize=(12,5))\n", + "\n", + "performance['elapsed_adj'].plot.bar(ax=ax[0],\n", + " logy=True, \n", + " title=\"Run times (wall clock), log scale\",\n", + "# figsize=(10,8)\n", + " )\n", + "ax[0].set_xlabel('Program')\n", + "\n", + "performance['elapsed_adj'].plot.bar(ax=ax[1],\n", + " logy=False, \n", + " title=\"Run times (wall clock), linear scale\",\n", + "# figsize=(10,8)\n", + " )\n", + "ax[1].set_xlabel('Program')\n", + "\n", + "plt.savefig('run_times_combined.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "ax = performance['elapsed_adj'].plot.bar(logy=False, \n", + " title=\"Run times (wall clock), linear scale\",\n", + " figsize=(10,8))\n", + "ax.set_xlabel('Program')\n", + "plt.savefig('run_times_linear.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['total_time', 'total_alloc', 'total_ticks', 'initial_capabilities',\n", + " 'Elapsed time (s)', 'Max memory', 'elapsed_adj'],\n", + " dtype='object')" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "performance.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance['Max memory'].plot.bar()" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": { + "Collapsed": "false" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "performance.plot.scatter('elapsed_adj', 'total_alloc', logx=True, logy=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "Collapsed": "false" + }, + "outputs": [], + "source": [ + "performance[['total_alloc', 'Max memory', 'elapsed_adj']].to_csv('performance.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "Collapsed": "false" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/profiling/run_times_combined.png b/profiling/run_times_combined.png new file mode 100644 index 0000000000000000000000000000000000000000..494c7531e9a3c06a8effc80e95250377df529d0b GIT binary patch literal 15887 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 Ut4B8S5u085sO*u1L)zE>A45vNUH||9 literal 0 HcmV?d00001 diff --git a/profiling/run_times_linear.png b/profiling/run_times_linear.png new file mode 100644 index 0000000000000000000000000000000000000000..7cde6788725d61cf529ba8b57385dc662728bc22 GIT binary patch literal 14843 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 literal 0 HcmV?d00001 diff --git a/profiling/time-results.csv b/profiling/time-results.csv new file mode 100644 index 0000000..04e90b6 --- /dev/null +++ b/profiling/time-results.csv @@ -0,0 +1,27 @@ +Program,Elapsed time (s),Max memory +advent01, 00.39, 72440 +advent02, 00.41, 72440 +advent03, 00.37, 72504 +advent04, 00.43, 72504 +advent05, 00.43, 72440 +advent06, 00.41, 72504 +advent07, 00.39, 72444 +advent08, 00.44, 72508 +advent09, 00.66, 72508 +advent10, 00.36, 72444 +advent11, 16.75, 72504 +advent12, 00.38, 72508 +advent13, 00.36, 72436 +advent14, 00.61, 72508 +advent15, 02.15, 240372 +advent15loop, 01.88, 240444 +advent16, 00.38, 72444 +advent17, 01.77, 72444 +advent18, 00.39, 72444 +advent19, 00.46, 72504 +advent20, 04.12, 72436 +advent21, 00.39, 72508 +advent22, 02.02, 72500 +advent23, 01.91, 95500 +advent24, 03.48, 72504 +advent25, 00.41, 72504 diff --git a/profiling/time-results.md b/profiling/time-results.md new file mode 100644 index 0000000..70c50c0 --- /dev/null +++ b/profiling/time-results.md @@ -0,0 +1,27 @@ +| Program | Elapsed time (mm:ss) | Max memory | +| advent01 | 0:00.39 | 72440 | +| advent02 | 0:00.41 | 72440 | +| advent03 | 0:00.37 | 72504 | +| advent04 | 0:00.43 | 72504 | +| advent05 | 0:00.43 | 72440 | +| advent06 | 0:00.41 | 72504 | +| advent07 | 0:00.39 | 72444 | +| advent08 | 0:00.44 | 72508 | +| advent09 | 0:00.66 | 72508 | +| advent10 | 0:00.36 | 72444 | +| advent11 | 0:16.75 | 72504 | +| advent12 | 0:00.38 | 72508 | +| advent13 | 0:00.36 | 72436 | +| advent14 | 0:00.61 | 72508 | +| advent15 | 0:02.15 | 240372 | +| advent15loop | 0:01.88 | 240444 | +| advent16 | 0:00.38 | 72444 | +| advent17 | 0:01.77 | 72444 | +| advent18 | 0:00.39 | 72444 | +| advent19 | 0:00.46 | 72504 | +| advent20 | 0:04.12 | 72436 | +| advent21 | 0:00.39 | 72508 | +| advent22 | 0:02.02 | 72500 | +| advent23 | 0:01.91 | 95500 | +| advent24 | 0:03.48 | 72504 | +| advent25 | 0:00.41 | 72504 | -- 2.34.1 From 072b9c66fc1e67fb78106ada274a6e6b0137c50f Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 12 Jan 2021 12:50:33 +0000 Subject: [PATCH 16/16] Redone day 7 with the Graphite graph library --- advent07/package.yaml | 12 ++++- advent07/src/advent07graph.hs | 97 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 advent07/src/advent07graph.hs diff --git a/advent07/package.yaml b/advent07/package.yaml index 88422cf..75a8507 100644 --- a/advent07/package.yaml +++ b/advent07/package.yaml @@ -58,4 +58,14 @@ executables: - base >= 2 && < 6 - text - attoparsec - - containers \ No newline at end of file + - containers + + advent07graph: + main: advent07graph.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - attoparsec + - containers + - graphite diff --git a/advent07/src/advent07graph.hs b/advent07/src/advent07graph.hs new file mode 100644 index 0000000..ee31c81 --- /dev/null +++ b/advent07/src/advent07graph.hs @@ -0,0 +1,97 @@ +-- import Debug.Trace + +import Data.Text (Text) +-- import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Attoparsec.Text +-- import Data.Attoparsec.Combinator +import Control.Applicative + +import qualified Data.Graph.DGraph as D +import qualified Data.Graph.Types as G +import qualified Data.Graph.Traversal as T + +import qualified Data.Set as S +import qualified Data.Map.Strict as M + +data QuantifiedBag = QuantifiedBag Int String + deriving (Show, Eq, Ord) + +type QBags = S.Set QuantifiedBag +type BagRules = M.Map String QBags +type BagGraph = D.DGraph String Int + + +main :: IO () +main = + do text <- TIO.readFile "data/advent07.txt" + let bags = successfulParse text + let graph = buildGraph bags + -- print graph + -- dumpBagDot bags + print $ part1 graph + print $ part2 graph + +part1 graph = length (T.bfsVertices (D.transpose graph) "shiny gold") - 1 + +part2 graph = (bfsCount graph "shiny gold") - 1 + +bfsCount :: BagGraph -> String -> Int +bfsCount graph thisBag = 1 + (sum $ map subCount others) + where others = D.outboundingArcs graph thisBag + subCount a = (G.attribute a) * (bfsCount graph $ G.destinationVertex a) + + +buildGraph :: BagRules -> BagGraph +buildGraph rules = M.foldrWithKey addRule G.empty rules + +addRule :: String -> QBags -> BagGraph -> BagGraph +addRule source dests graph = S.foldr (addArc source) graph dests + +addArc :: String -> QuantifiedBag -> BagGraph -> BagGraph +addArc source (QuantifiedBag quantity destination) graph = D.insertArc arc graph + where arc = G.Arc source destination quantity + + +-- dumpBagDot bags = +-- do writeFile "a07dump.dot" "digraph {\n" +-- mapM_ dumpABag (M.assocs bags) +-- appendFile "a07dump.dot" "shiny_gold [fillcolor = gold1 ]\n" +-- appendFile "a07dump.dot" "}\n" + +-- dumpABag (bag, contents) = +-- mapM_ (dumpALink bag) (S.toList contents) + +-- dumpALink bag (QuantifiedBag n name) = +-- do let name' = squashName name +-- let bag' = squashName bag +-- let txt = bag' ++ " -> " ++ name' ++ "\n" +-- appendFile "a07dump.dot" txt + +-- squashName :: String -> String +-- squashName name = [if c == ' ' then '_' else c | c <- name] + + +-- -- Parse the input file + +bagNameP = manyTill anyChar ((string " bags") <|> (string " bag")) + +quantifiedBagP = QuantifiedBag <$> decimal <* space <*> bagNameP + +emptyBagListP = "no other bags" *> pure S.empty + +bagListP = S.fromList <$> sepBy quantifiedBagP (string ", ") + +bagContentsP = emptyBagListP <|> bagListP + +ruleP = (,) <$> bagNameP <* " contain " <*> bagContentsP <* "." + +rulesP = M.fromList <$> sepBy ruleP endOfLine + + +successfulParse :: Text -> BagRules +successfulParse input = + case parseOnly rulesP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right bags -> bags -- 2.34.1