with regexes
authorMart Lubbers <mart@martlubbers.net>
Fri, 4 Dec 2020 08:57:21 +0000 (09:57 +0100)
committerMart Lubbers <mart@martlubbers.net>
Fri, 4 Dec 2020 08:57:21 +0000 (09:57 +0100)
4/one.icl

index 5e7f5f0..a4aa7a3 100644 (file)
--- a/4/one.icl
+++ b/4/one.icl
@@ -2,7 +2,6 @@ module one
 
 import StdEnv
 import Text
-import Data.Functor
 import Data.Maybe
 import Data.List
 import Regex
@@ -18,27 +17,21 @@ group acc [] = [acc]
 group acc ["":xs] = [acc:group [] xs]
 group acc [s:xs] = group (acc ++ [(k, v)\\[k,v]<-map (split ":") (split " " s)]) xs
 
-valid :: [(String, String -> Bool)] [(String, String)] -> Bool
-valid req fs = all (\(f, p)->fromMaybe False (p <$> lookup f fs)) req
+valid :: [(String, String)] [(String, String)] -> Bool
+valid req fs = all (\(f, p)->maybe False (not o isEmpty o match p) (lookup f fs)) req
 
 Start w
        # (io, w) = stdio w
        # passports = group [] (read io)
        = (one passports, two passports)
 
-one = length o filter (valid [(n, const True)\\n<-["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]])
+one = length o filter (valid [(n, ".*")\\n<-["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]])
 two = length o filter (valid
-       [ ("byr", fourDigit 1920 2002)
-       , ("iyr", fourDigit 2010 2020)
-       , ("eyr", fourDigit 2020 2030)
-       , ("hgt", \x->case x % (size x - 2, size x - 1) of
-                       "cm" = between 150 193 (toInt (x % (0, size x - 3)))
-                       "in" = between 59 76 (toInt (x % (0, size x - 3)))
-                       _ = False)
-       , ("hcl", reg "#[0-9a-f]{6}")
-       , ("ecl", flip isMember ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"])
-       , ("pid", reg "\\d{9}")
+       [ ("byr", "^(19[2-9]\\d|200[0-2])$")
+       , ("iyr", "^20(1\\d|20)$")
+       , ("eyr", "^20(2\\d|30)$")
+       , ("hgt", "^(1([5-8]\\d|9[0-3])cm|(59|6\\d|7[0-6])in)$")
+       , ("hcl", "^#[0-9a-f]{6}$")
+       , ("ecl", "^(amb|blu|brn|gry|grn|hzl|oth)$")
+       , ("pid", "^\\d{9}$")
        ])
-fourDigit lo hi x = reg "\\d{4}" x && between lo hi (toInt x)
-reg p = not o isEmpty o match ("^"+++p+++"$")
-between lo hi x = x >= lo && x <= hi