Skip to content

Instantly share code, notes, and snippets.

@mjgpy3
Last active December 4, 2020 17:41
Show Gist options
  • Select an option

  • Save mjgpy3/5912813d5b2e17ebf53b933205702683 to your computer and use it in GitHub Desktop.

Select an option

Save mjgpy3/5912813d5b2e17ebf53b933205702683 to your computer and use it in GitHub Desktop.
aoc-2020-day4
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.Text.IO as TIO
import qualified Data.Text as T
passportTexts = T.splitOn "\n\n"
required =
[ "byr:",
"iyr:",
"eyr:",
"hgt:",
"hcl:",
"ecl:",
"pid:"
]
isValid p = all (`T.isInfixOf` p) required
main = do
text <- TIO.readFile "./d4.txt"
print $ length $ filter isValid $ passportTexts text
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.Text.IO as TIO
import qualified Data.Text as T
import qualified Text.Read as TR
import qualified Data.Char as C
required =
[
"byr:",
"iyr:",
"eyr:",
"hgt:",
"hcl:",
"ecl:",
"pid:"
]
isValid p = all (`T.isInfixOf` p) required
passportTexts =
map (T.split (`elem` ['\n', ' '])) .
filter isValid .
T.splitOn "\n\n"
validateIntBetween s e = (== (Just True)) . fmap (\v -> s <= v && v <= e) . TR.readMaybe . T.unpack
isValidField fld =
case T.splitAt 4 $ T.strip fld of
("byr:", v) -> validateIntBetween 1920 2002 v
("iyr:", v) -> validateIntBetween 2010 2020 v
("eyr:", v) -> validateIntBetween 2020 2030 v
("hgt:", v) ->
case (T.dropEnd 2 v, T.takeEnd 2 v) of
(n, "cm") -> validateIntBetween 150 193 n
(n, "in") -> validateIntBetween 59 76 n
_ -> False
("hcl:", v) ->
T.take 1 v == "#" && (T.length v, T.length (T.filter (`elem` ("0123456789abcdef"::String)) (T.drop 1 v))) == (7, 6)
("ecl:", v) -> v `elem` (T.splitOn " " "amb blu brn gry grn hzl oth")
("pid:", v) -> (T.length v, T.length (T.filter C.isDigit v)) == (9, 9)
_ -> True
main = do
text <- TIO.readFile "./d4.txt"
print $ length $ filter (all isValidField) $ passportTexts text
const Joi = require('joi');
const validateHeight = (value, helpers) => {
if (!value.constructor || value.constructor !== String || !(value.endsWith('in') || value.endsWith('cm'))) {
return helpers.error('Expected string ending in cm or in');
}
const v = value.slice(0, -2);
let min = 150, max = 193;
if (value.endsWith('in')) {
min = 59;
max = 76;
}
const { error } = Joi.number().integer().min(min).max(max).validate(v);
if (error) {
return helpers.error(error);
}
return value;
};
const gregYearStrBetween = (start, end) =>
Joi.number()
.integer()
.min(start)
.max(end)
.required();
const schema = Joi.object({
byr: gregYearStrBetween(1920, 2002),
iyr: gregYearStrBetween(2010, 2020),
eyr: gregYearStrBetween(2020, 2030),
hgt: Joi.any()
.custom(validateHeight, 'height')
.required(),
hcl: Joi.string()
.pattern(/^#[0-9a-f]{6}$/)
.required(),
ecl: Joi.any()
.allow('amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth')
.only()
.required(),
pid: Joi.string()
.pattern(/^[0-9]{9}$/)
.required(),
cid: Joi.any()
});
const passports = require('./d4.json');
console.log(passports.filter((p, i) => !schema.validate(p).error).length);
@mjgpy3
Copy link
Author

mjgpy3 commented Dec 4, 2020

https://gist.github.com/mjgpy3/5912813d5b2e17ebf53b933205702683#file-p2-js-L20 had a horrible error to debug! If you don't call helpers.error just returning error makes the validator pass. I missed strong types there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment