@@ -10,9 +10,9 @@ common common
|
|||||||
ghc-options: -Wall -O3
|
ghc-options: -Wall -O3
|
||||||
default-extensions:
|
default-extensions:
|
||||||
LambdaCase
|
LambdaCase
|
||||||
|
MultiWayIf
|
||||||
TupleSections
|
TupleSections
|
||||||
ViewPatterns
|
ViewPatterns
|
||||||
MultiWayIf
|
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, base >=4.14 && <5
|
, base >=4.14 && <5
|
||||||
@@ -140,4 +140,15 @@ executable day18
|
|||||||
import: common
|
import: common
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
main-is: Day18.hs
|
main-is: Day18.hs
|
||||||
build-depends: libaoc, containers
|
build-depends:
|
||||||
|
, containers
|
||||||
|
, libaoc
|
||||||
|
|
||||||
|
executable day19
|
||||||
|
import: common
|
||||||
|
hs-source-dirs: src
|
||||||
|
main-is: Day19.hs
|
||||||
|
build-depends:
|
||||||
|
, array
|
||||||
|
, containers
|
||||||
|
, libaoc
|
||||||
|
48
src/Day19.hs
Normal file
48
src/Day19.hs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import qualified AoC as A
|
||||||
|
import Data.Array as A (listArray, (!))
|
||||||
|
import Data.List (tails)
|
||||||
|
import qualified Data.Map as M
|
||||||
|
import Text.Parsec (letter, many1, parse, sepBy1, string)
|
||||||
|
import Text.Parsec.String (Parser)
|
||||||
|
|
||||||
|
data Trie = Trie Bool !(M.Map Char Trie) deriving (Show)
|
||||||
|
|
||||||
|
parseTowels :: Parser [String]
|
||||||
|
parseTowels = many1 letter `sepBy1` string ", "
|
||||||
|
|
||||||
|
fromWord :: String -> Trie
|
||||||
|
fromWord = foldr (\x xs -> Trie False (M.singleton x xs)) (Trie True M.empty)
|
||||||
|
|
||||||
|
insertTrie :: String -> Trie -> Trie
|
||||||
|
insertTrie [] (Trie _ t) = Trie True t
|
||||||
|
insertTrie (x : xs) (Trie b t) =
|
||||||
|
Trie b $ M.alter (Just . maybe (fromWord xs) (insertTrie xs)) x t
|
||||||
|
|
||||||
|
possible :: Trie -> String -> Int
|
||||||
|
possible trie ys = dp ! 0
|
||||||
|
where
|
||||||
|
l = length ys
|
||||||
|
|
||||||
|
dp =
|
||||||
|
A.listArray
|
||||||
|
(0, l)
|
||||||
|
[combos s i trie | (i, s) <- zip [0 .. l] $ tails ys]
|
||||||
|
|
||||||
|
combos :: String -> Int -> Trie -> Int
|
||||||
|
combos "" _ (Trie b _) = fromEnum b
|
||||||
|
combos (y : ys) i (Trie b t) =
|
||||||
|
maybe 0 (combos ys $ i + 1) (M.lookup y t)
|
||||||
|
+ if b then dp ! i else 0
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main =
|
||||||
|
do
|
||||||
|
(rawTowels : _ : designs) <- lines <$> readFile "./inputs/day19.in"
|
||||||
|
let towels = A.extract $ parse parseTowels "" rawTowels
|
||||||
|
trie = foldr insertTrie (Trie False M.empty) towels
|
||||||
|
combinations = map (possible trie) designs
|
||||||
|
|
||||||
|
putStr "Part 1: " >> print (length . filter (> 0) $ combinations)
|
||||||
|
putStr "Part 2: " >> print (sum combinations)
|
Reference in New Issue
Block a user