Advent of Code — Day 4 — Javascript

Vincent Yang
3 min readJan 11, 2021

Advent of Code’s Day 4 problem is going to be pure data validation with the second part being able to be done through regex. The input will be a string that looks something like this:

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

This sequence represents a passport which needs to be verified if valid or invalid. There are eight fields in total.

byr = Birth Year
iyr = Issue Year
eyr = Expiration Year
hgt = Height
hcl = Hair Color
ecl = Eye Color
pid = Passport ID
cid = Country ID

For the first part of the problem, a valid passport is represented through having all eight fields present or seven fields present where the Country ID field (cid) is missing.

Let’s look at the sample data now.

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

Looking through the sample data, each passport is separated with a line between them.

function day4(input){
const arr = input.split('\n\n')
}
//arr[0] = "ecl:gry pid:860033327 eyr:2020 hcl:#fffffd byr:1937 iyr:2017 cid:147 hgt:183cm"
//arr[1] = "iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929"
//arr[2] = "hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm"

Now that we have each passport separated, we can parse through each and do a count on each valid case.

function day4(input){
const passport = input.split('\n\n')
let counter = 0
for(let i = 0; i < passport.length; i++){
let fields = passport[i].split(/\s+/);
}
}

If you are confused at the syntax following the second .split(), that’s because it is regex. Regex is short for Regular Expressions and is used to pattern match, strip, or format strings, numbers, and other data types. Instead of using .split(‘ ‘) which only works on single whitespace characters, the .split(/\s+/) matches any type of space including tabs (‘\t’) and newline characters (‘\n’).

Our data should now look like this.

arr[0] = "ecl:gry pid:860033327 eyr:2020 hcl:#fffffd byr:1937 iyr:2017 cid:147 hgt:183cm"
arr[0][0] = "ecl:gry"
arr[0][1] = "pid:860033327"
arr[1] = "iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929"
arr[1][0] = "iyr:2013"
arr[1][1] = "ecl:amb"
arr[2] = "hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm"
arr[2][0] = "hcl:#ae17e1"
arr[2][1] = "iyr:2013"
arr[2][2] = "eyr:2024"

Take a look at arr[2] in our data above. If .split(‘ ‘) was used instead of .split(/\s+/), the data would look like this:

arr[2][0] = "hcl:#ae17e1"
arr[2][1] = "iyr:2013
eyr:2024
ecl:brn"
arr[2][2] = "pid:760753108"

The reason is because when we split on whitespace, it will not separate on a newline character. This will cause parts of the data to not function correctly as we need to count the number of fields. Since the .split() method turns the string into an array, now we can check the length for validity.

function day4(input){
const passport = input.split('\n\n')
let counter = 0
for(let i = 0; i < passport.length; i++){
let fields = passport[i].split(/\s+/);
if(fields.length === 8)
counter++
}
return counter
}

This will check for the cases where all eight fields are present but we must also account for the instances where country code is absent. In that case, we are checking the length of the array to be 7 and is cid is present anywhere in the string.

function day4(input){
const passport = input.split('\n\n')
let counter = 0
for(let i = 0; i < passport.length; i++){
let fields = passport[i].split(/\s+/);
if(fields.length === 8)
counter++
else if(fields.length === 7) && passports[i].includes('cid')
counter++
}
return counter
}

The answer to the sample data is 2 as passports 1 and 3 are valid, while 2 is missing the height field and 4 is missing two fields.

--

--