bss03 icon

Advent of Code 2020 Day 4

bss03 | PRO | 12/04/20 07:20:00 AM UTC | 0 ⭐ | 13483 👁️ | Never ⏰ | []
Haskell |

2.16 KB

|

None

|

0 👍

/

0 👎

import Data.Char (isDigit)
import Data.List (intercalate)
 
import Data.Set (Set)
import qualified Data.Set as S
import Data.Map (Map)
import qualified Data.Map as M
 
key :: String -> String
key = fst . kv
 
kv :: String -> (String, String)
kv s = (key, drop 1 value)
 where (key, value) = break (':' ==) s
 
paras :: [String] -> [String]
paras ls = if null pls then [] else intercalate " " pls : paras (drop 1 remain)
 where
  (pls, remain) = break (null . words) ls
 
reqKeys :: Set String
reqKeys = S.fromList [ "byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid" ]
 
validations :: Map String (String -> Bool)
validations = M.fromList
  [ ("byr", validByr)
  , ("iyr", validIyr)
  , ("eyr", validEyr)
  , ("hgt", validHgt)
  , ("hcl", validHcl)
  , ("ecl", validEcl)
  , ("pid", validPid)
  ]
 
keys :: String -> Set String
keys = S.fromList . map key . words
 
kvs :: String -> Map String String
kvs = M.fromList . map kv . words
 
hasReqKeys :: Set String -> Bool
hasReqKeys x = S.size reqKeys == S.size (S.intersection reqKeys x)
 
validates :: Map String String -> Bool
validates x = M.size results == M.size validations && and results
 where results = M.intersectionWith ($) validations x
 
count :: (a -> Bool) -> [a] -> Int
count pred = length . filter pred
 
validByr :: String -> Bool
validByr byr = 1920 <= v && v <= 2002
 where v = read byr
 
validIyr :: String -> Bool
validIyr iyr = 2010 <= v && v <= 2020
 where v = read iyr
 
validEyr :: String -> Bool
validEyr eyr = 2020 <= v && v <= 2030
 where v = read eyr
 
validHgt :: String -> Bool
validHgt hgt =
  case units of
   "cm" -> 150 <= v && v <= 193
   "in" -> 59 <= v && v <= 76
   _ -> False
 where
  (n, units) = span isDigit hgt
  v = read n
 
lcHexDigits :: Set Char
lcHexDigits = S.fromList "0123456789abcdef"
 
validHcl :: String -> Bool
validHcl ('#':hex@(_:_:_:_:_:_:[])) = all (flip S.member lcHexDigits) hex
validHcl _ = False
 
eyeColors :: Set String
eyeColors = S.fromList [ "amb", "blu", "brn", "gry", "grn", "hzl", "oth" ]
 
validEcl :: String -> Bool
validEcl = flip S.member eyeColors
 
validPid :: String -> Bool
validPid pid = length pid == 9 && all isDigit pid
 
main = interact ((++"\n") . show . count (validates . kvs). paras . lines)
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎