|  |  |  | @ -5,27 +5,28 @@ module Day4 (day4) where | 
			
		
	
		
			
				
					|  |  |  |  | import Control.Applicative ((<|>)) | 
			
		
	
		
			
				
					|  |  |  |  | import Control.Monad (void) | 
			
		
	
		
			
				
					|  |  |  |  | import qualified Data.Attoparsec.Text as P | 
			
		
	
		
			
				
					|  |  |  |  | import qualified Data.Map as M | 
			
		
	
		
			
				
					|  |  |  |  | import Data.Maybe (catMaybes) | 
			
		
	
		
			
				
					|  |  |  |  | import qualified Data.Text as T | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type BYR = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | -- import qualified Data.Text as T | 
			
		
	
		
			
				
					|  |  |  |  | -- import qualified Data.Vector as V | 
			
		
	
		
			
				
					|  |  |  |  | -- import Numeric.Natural (Natural) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type IYR = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type BYR = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type EYR = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type IYR = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type HGT = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type EYR = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type HCL = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type HGT = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type ECL = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type HCL = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type PID = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type ECL = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | type CID = T.Text | 
			
		
	
		
			
				
					|  |  |  |  | type PID = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | data Passport = ValidPassport | 
			
		
	
		
			
				
					|  |  |  |  | type CID = String | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | data Passport = Passport | 
			
		
	
		
			
				
					|  |  |  |  |   { byr :: BYR, | 
			
		
	
		
			
				
					|  |  |  |  |     iyr :: IYR, | 
			
		
	
		
			
				
					|  |  |  |  |     eyr :: EYR, | 
			
		
	
	
		
			
				
					|  |  |  | @ -37,39 +38,18 @@ data Passport = ValidPassport | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   deriving (Eq, Show) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | parserPair :: P.Parser (T.Text, T.Text) | 
			
		
	
		
			
				
					|  |  |  |  | parserPair = do | 
			
		
	
		
			
				
					|  |  |  |  | parsePassport :: P.Parser Passport | 
			
		
	
		
			
				
					|  |  |  |  | parsePassport = do | 
			
		
	
		
			
				
					|  |  |  |  |   -- parse pairs | 
			
		
	
		
			
				
					|  |  |  |  |   pairs <- parsePair `P.sepBy` (void P.space <|> P.endOfLine) | 
			
		
	
		
			
				
					|  |  |  |  |   undefined | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | parsePair :: P.Parser (String, String) | 
			
		
	
		
			
				
					|  |  |  |  | parsePair = do | 
			
		
	
		
			
				
					|  |  |  |  |   key <- P.count 3 P.letter | 
			
		
	
		
			
				
					|  |  |  |  |   _ <- P.char ':' | 
			
		
	
		
			
				
					|  |  |  |  |   value <- P.takeWhile1 (P.inClass "a-zA-Z0-9#") | 
			
		
	
		
			
				
					|  |  |  |  |   return (T.pack key, value) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | parserEntry :: P.Parser (M.Map T.Text T.Text) | 
			
		
	
		
			
				
					|  |  |  |  | parserEntry = M.fromList <$> parserPair `P.sepBy` (void P.space <|> P.endOfLine) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fromMap :: M.Map T.Text T.Text -> Maybe Passport | 
			
		
	
		
			
				
					|  |  |  |  | fromMap m = do | 
			
		
	
		
			
				
					|  |  |  |  |   byr <- m M.!? "byr" | 
			
		
	
		
			
				
					|  |  |  |  |   iyr <- m M.!? "iyr" | 
			
		
	
		
			
				
					|  |  |  |  |   eyr <- m M.!? "eyr" | 
			
		
	
		
			
				
					|  |  |  |  |   hgt <- m M.!? "hgt" | 
			
		
	
		
			
				
					|  |  |  |  |   hcl <- m M.!? "hcl" | 
			
		
	
		
			
				
					|  |  |  |  |   ecl <- m M.!? "ecl" | 
			
		
	
		
			
				
					|  |  |  |  |   pid <- m M.!? "pid" | 
			
		
	
		
			
				
					|  |  |  |  |   return $ ValidPassport byr iyr eyr hgt hcl ecl pid (m M.!? "cid") | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | parserPassport :: P.Parser (Maybe Passport) | 
			
		
	
		
			
				
					|  |  |  |  | parserPassport = fromMap <$> parserEntry | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | parseList :: String -> [Maybe Passport] | 
			
		
	
		
			
				
					|  |  |  |  | parseList s = | 
			
		
	
		
			
				
					|  |  |  |  |   let p = parserPassport `P.sepBy` P.endOfLine | 
			
		
	
		
			
				
					|  |  |  |  |    in case P.parseOnly p (T.pack s) of | 
			
		
	
		
			
				
					|  |  |  |  |         Left s -> error (show s) | 
			
		
	
		
			
				
					|  |  |  |  |         Right r -> r | 
			
		
	
		
			
				
					|  |  |  |  |   value <- P.many1 P.anyChar | 
			
		
	
		
			
				
					|  |  |  |  |   return (key, value) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | day4 :: IO () | 
			
		
	
		
			
				
					|  |  |  |  | day4 = do | 
			
		
	
		
			
				
					|  |  |  |  |   r <- readFile "./input/day4" | 
			
		
	
		
			
				
					|  |  |  |  |   putStr "[Day 4-1] # trees: " | 
			
		
	
		
			
				
					|  |  |  |  |   print . length . catMaybes . parseList $ r | 
			
		
	
		
			
				
					|  |  |  |  | day4 = putStrLn "Day 4" |