@@ -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