22
[aoc20.git] / 2 / one.icl
1 module one
2
3 import StdEnv
4 import Data.Functor
5 import Data.Either
6 import Control.Applicative
7 import Text.Parsers.Simple.ParserCombinators
8
9 read :: *File -> [Char]
10 read f
11 # (ok, l, f) = freadc f
12 | not ok = []
13 = [l:read f]
14
15 Start w
16 # (io, w) = stdio w
17 = case parse (many lineparser) (read io) of
18 Left e = Left e
19 Right a = Right (length (filter validone a), length (filter validtwo a))
20
21 validone :: (Int, Int, Char, String) -> Bool
22 validone (fro, to, a, s) = isMember (length [c\\c<-:s | c == a]) [fro..to]
23
24 validtwo :: (Int, Int, Char, String) -> Bool
25 validtwo (fro, to, a, s) = (s.[fro-1] == a || s.[to-1] == a) && s.[fro-1] <> s.[to-1]
26
27 lineparser :: Parser Char (Int, Int, Char, String)
28 lineparser = (\a b c d->(a, b, c, d)) <$> pInt <* pToken '-' <*> pInt <* pSpace <*> pAlpha <* pToken ':' <* pSpace <*> (toString <$> many pAlpha) <* pToken '\n'
29 where pInt = toInt o toString <$> some pDigit