mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 05:49:52 +01:00
Add 2020 day 04
This commit is contained in:
1023
haskellAoC/inputs/2020/04
Normal file
1023
haskellAoC/inputs/2020/04
Normal file
File diff suppressed because it is too large
Load Diff
57
haskellAoC/src/Y2020/Day04.hs
Normal file
57
haskellAoC/src/Y2020/Day04.hs
Normal file
@@ -0,0 +1,57 @@
|
||||
module Y2020.Day04 (y20day04) where
|
||||
|
||||
import Data.Char
|
||||
import Data.Maybe
|
||||
import Data.List.Split
|
||||
import qualified Data.Map as M
|
||||
|
||||
data RawPassport = RawPassport {
|
||||
birth_year :: String
|
||||
, issue_year :: String
|
||||
, expir_year :: String
|
||||
, height :: String
|
||||
, hair_color :: String
|
||||
, eye_color :: String
|
||||
, passport_id :: String
|
||||
} deriving (Show)
|
||||
|
||||
parsePassport :: String -> Maybe RawPassport
|
||||
parsePassport input = do
|
||||
byr <- M.lookup "byr" mapped
|
||||
iyr <- M.lookup "iyr" mapped
|
||||
eyr <- M.lookup "eyr" mapped
|
||||
hgt <- M.lookup "hgt" mapped
|
||||
hcl <- M.lookup "hcl" mapped
|
||||
ecl <- M.lookup "ecl" mapped
|
||||
pid <- M.lookup "pid" mapped
|
||||
return (RawPassport byr iyr eyr hgt hcl ecl pid)
|
||||
where mapped = M.fromList $ map (\a -> (a !! 0, a !! 1)) $ map (splitOn ":") $ splitOn " " input
|
||||
|
||||
allTrue :: [Bool] -> Bool
|
||||
allTrue = all (== True)
|
||||
|
||||
checkDigitInRange :: Int -> Int -> String -> Bool
|
||||
checkDigitInRange mini maxi input = allTrue $ map ($ input) [(all (isDigit)), ((>= mini) . read), ((<= maxi) . read)]
|
||||
|
||||
validatePassport :: RawPassport -> Bool
|
||||
validatePassport pass = allTrue [validatePassID, validateBirth, validateIssued, validateExpiration, validateHeight, validateHairColor, validateEyeColor]
|
||||
where validateBirth = checkDigitInRange 1920 2002 $ birth_year pass
|
||||
validateIssued = checkDigitInRange 2010 2020 $ issue_year pass
|
||||
validateExpiration = checkDigitInRange 2020 2030 $ expir_year pass
|
||||
validateHeight = not unitAvailable && (correctHeightCm || correctHeightIn)
|
||||
where correctHeightCm = checkDigitInRange 150 193 $ (splitOn "cm" (height pass)) !! 0
|
||||
correctHeightIn = checkDigitInRange 59 76 $ (splitOn "in" (height pass)) !! 0
|
||||
unitAvailable = all (isDigit) (height pass)
|
||||
validateHairColor = allTrue $ map ($ hair_color pass) [((== '#') . head), (all (`elem` "0123456789abcdef") . tail), ((== 7) . length)]
|
||||
validateEyeColor = (eye_color pass) `elem` ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]
|
||||
validatePassID = allTrue $ map ($ passport_id pass) [((== 9) . length), (all (isDigit))]
|
||||
|
||||
y20day04 :: [String] -> (String, String)
|
||||
y20day04 input = (part1, part2)
|
||||
where part1 = show $ length $ passports
|
||||
part2 = show $ length $ validPassports
|
||||
passports = concatMap maybeToList $ map parsePassport $ map replaceNL $ splitOn "\n\n" $ unlines input
|
||||
replaceNL = map repl
|
||||
repl '\n' = ' '
|
||||
repl c = c
|
||||
validPassports = filter validatePassport passports
|
||||
@@ -3,9 +3,11 @@ module Y2020.Days (year2020) where
|
||||
import Y2020.Day01
|
||||
import Y2020.Day02
|
||||
import Y2020.Day03
|
||||
import Y2020.Day04
|
||||
|
||||
|
||||
year2020 :: String -> [String] -> (String, String)
|
||||
year2020 "01" = y20day01
|
||||
year2020 "02" = y20day02
|
||||
year2020 "03" = y20day03
|
||||
year2020 "04" = y20day04
|
||||
|
||||
Reference in New Issue
Block a user