mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +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.Day01
|
||||||
import Y2020.Day02
|
import Y2020.Day02
|
||||||
import Y2020.Day03
|
import Y2020.Day03
|
||||||
|
import Y2020.Day04
|
||||||
|
|
||||||
|
|
||||||
year2020 :: String -> [String] -> (String, String)
|
year2020 :: String -> [String] -> (String, String)
|
||||||
year2020 "01" = y20day01
|
year2020 "01" = y20day01
|
||||||
year2020 "02" = y20day02
|
year2020 "02" = y20day02
|
||||||
year2020 "03" = y20day03
|
year2020 "03" = y20day03
|
||||||
|
year2020 "04" = y20day04
|
||||||
|
|||||||
Reference in New Issue
Block a user