DEV Community

Cover image for Passport Processing
Robert Mion
Robert Mion

Posted on

Passport Processing

Advent of Code 2020 Day 4

Task: Solve for X where...

X = the number of valid passports
Enter fullscreen mode Exit fullscreen mode
  1. All required keys are present
  2. All values associated with required keys are correct

Example input

ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm

iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929

hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm

hcl:#cfa07d eyr:2025 pid:166559648
iyr:2011 ecl:brn hgt:59in
Enter fullscreen mode Exit fullscreen mode

It represents:

  • A list of passport data
  • Each passport contains up to 8 key:value pairs

Part 1

  1. Considering three algorithmic ingredients
  2. Writing the algorithm

Considering three algorithmic ingredients

  1. Regular expression
  2. Length
  3. Includes

Regular expression

  • For each passport, identify each of the eight keys
/(ecl|pid|eyr|hcl|byr|iyr|cid|hgt)/g
Enter fullscreen mode Exit fullscreen mode

Length

  • From the list of matches, check the count
  • If it's 8, the passport must be valid
  • If it's 6 or less, the passport must be invalid

Includes

  • If it's 7, check for inclusion of cid as a key.
  • If it is, that means we're missing a required key, so it must be invalid
  • If it isn't, then we must have all required keys, so the passport must be valid

Writing the algorithm

Split the input at each double-new-line character into an array of strings

For each item in the array of strings
  Change the item to an array of matched keys found using the regular expression above

Filter the array of matched keys to only include 'true' values where:
    1. The array's length is 8
    2. The array's length is 7 and it doesn't include 'cid'

Return the length of the filtered array
Enter fullscreen mode Exit fullscreen mode

Part 2

  1. A litany of utility functions and regular expressions
  2. Storing the functions as methods on an object
  3. Small addition to the root regular expression
  4. Writing a working algorithm

A litany of utility functions and regular expressions

  • Beyond identifying passports with required keys present, I must now ensure their values are valid
  • It seems I'll need utility functions and regular expressions to check each key's value

byr iyr eyr are similar:

Return true if:
  String length is 4
  Value is within a range
Enter fullscreen mode Exit fullscreen mode

hgt is a regular expression, then a few checks:

Regular expression:
/(\d+)(\w+)/

Return true if:
  String matches the regular expression
  Depending on 'cm' or 'in', the value is within a range
Enter fullscreen mode Exit fullscreen mode

hcl is a regular expression:

/#([0-9a-f]{6})/
Enter fullscreen mode Exit fullscreen mode

ecl is a regular expression:

/(amb|blu|brn|gry|grn|hzl|oth){1}/
Enter fullscreen mode Exit fullscreen mode

pid is a regular expression:

/^\d{9}$/
Enter fullscreen mode Exit fullscreen mode

cid is always true.

Storing the functions as methods on an object

rules = {
  byr()...,
  hgt()...,
  ...
}
Enter fullscreen mode Exit fullscreen mode

Each key:value pair match has this structure

['byr', '2000']
Enter fullscreen mode Exit fullscreen mode

So I can run the test using:

rules[key](value)
Enter fullscreen mode Exit fullscreen mode

Small addition to the root regular expression

Part 1 featured a regular expression to capture each key:

  • Where each key could be one of eight 3-letter combinations
/(ecl|pid|eyr|hcl|byr|iyr|cid|hgt)/g
Enter fullscreen mode Exit fullscreen mode

Part 2 requires a regular expression that captures key and value:

  • Where value could be one or more letters, one or more digits, or a single hashtag
/(ecl|pid|eyr|hcl|byr|iyr|cid|hgt):([\w|\d|#]+)/g
Enter fullscreen mode Exit fullscreen mode

Writing a working algorithm

Split the input at each double-new-line character into an array of strings

For each item in the array of strings
  Change the item to an array of matched keys found using the updated regular expression above

Filter the array of matched keys to only include 'true' values where:
  1. The array's length is 8
  2. The array's length is 7 and it doesn't include 'cid'

Filter the array of valid - in that all required keys are present - passports to only include 'true' values where:
  Every value for each key returns 'true' for the appropriate test found in the 'rules' object for that key

Return the length of the filtered array
Enter fullscreen mode Exit fullscreen mode

I recall skipping this puzzle the first time I read it because I knew it would require regular expressions.

This time around, I felt delightfully comfortable building each RegEx.

It continues to feel rewarding when these early-day puzzles feel easier than anticipated.

Top comments (0)