Skip to content

Commit 7504e82

Browse files
committed
simplifying
1 parent aaaed88 commit 7504e82

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

2020/folivetti/day19/src/Main.hs

+19-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module Main where
22

3+
import Data.Either (fromRight)
4+
import Data.Bifunctor (first)
35
import Data.Map.Strict (Map(..),fromList, (!), insert)
46
import Text.Parsec
57

@@ -8,42 +10,33 @@ data Rule = Single Int | And Rule Rule | Or Rule Rule | Token Char
810

911
-- * Parsing stuff
1012
getToken :: Parsec String () Rule
11-
getToken = do
12-
char '\"'
13-
val <- letter
14-
char '\"'
15-
return (Token val)
13+
getToken = Token <$> between (char '\"') (char '\"') letter
1614

1715
getSingle :: Parsec String () Rule
1816
getSingle = Single . read <$> many digit
1917

2018
getAnd :: Parsec String () Rule
21-
getAnd = do
22-
rule1 <- getSingle
23-
char ' '
24-
And rule1 <$> getSingle
19+
getAnd = And <$> getSingle <*> (char ' ' >> getSingle)
2520

2621
getOr :: Parsec String () Rule
27-
getOr = try (Or <$> getSingle <*> (string " | " >> getSingle)) <|> (Or <$> getAnd <*> (string " | " >> getAnd))
22+
getOr = try (Or <$> getSingle <*> (string " | " >> getSingle))
23+
<|> (Or <$> getAnd <*> (string " | " >> getAnd))
2824

25+
getKey :: Parsec String () Int
26+
getKey = read <$> between (string "") (string ": ") (many digit)
27+
28+
getRule :: Parsec String () Rule
29+
getRule = try getToken <|> try getOr <|> try getAnd <|> getSingle
2930

3031
getData :: Parsec String () (Int, Rule)
31-
getData = do
32-
key <- read <$> many digit
33-
string ": "
34-
rule <- try getToken <|> try getOr <|> try getAnd <|> getSingle
35-
return (key, rule)
32+
getData = (,) <$> getKey <*> getRule
3633

3734
parseMap :: [String] -> Map Int Rule
38-
parseMap css = fromList $ map (fromEither . parse getData "") css
39-
40-
fromEither :: Show a => Either a b -> b
41-
fromEither (Right x) = x
42-
fromEither (Left x) = error $ show x
35+
parseMap = fromList . map (fromRight (0, Single 0) . parse getData "")
4336

4437
-- * Non-deterministic finite automata
4538
runNDFA :: Map Int Rule -> Int -> String -> Bool
46-
runNDFA rules k = elem "" . go (Single k)
39+
runNDFA rules k = elem "" . go (rules ! k)
4740
where
4841
go _ "" = []
4942
go (Token c) (c':cs) = [cs | c==c']
@@ -57,11 +50,8 @@ r11 = Or (And (Single 42) (Single 31)) (And (And (Single 42) (Single 11)) (Singl
5750
main :: IO ()
5851
main = do
5952
dat <- lines <$> readFile "day19.txt"
60-
let rulesStr = takeWhile (/="") dat
61-
strings = tail $ dropWhile (/="") dat
62-
rules = parseMap rulesStr
63-
part1 = map (runNDFA rules 0) strings
64-
rules' = insert 8 r8 $ insert 11 r11 rules
65-
part2 = map (runNDFA rules' 0) strings
66-
print $ length $ filter id part1
67-
print $ length $ filter id part2
53+
let (rules, strings) = first parseMap . span (/="") $ dat
54+
rules' = insert 8 r8 . insert 11 r11 $ rules
55+
countWith r = length . filter (runNDFA r 0) $ strings
56+
print $ countWith rules
57+
print $ countWith rules'

0 commit comments

Comments
 (0)