#!/bin/node const fs = require('fs'); fs.readFile('input.txt', (err, data) => { const passports = []; data.toString() .split('\n\n') .map(line => line.replaceAll('\n', ' ')) .map((line, index) => line.split(' ').map(f => { if (!passports[index]) passports[index] = {}; const [key, value] = f.split(':'); passports[index][key] = value; })); const requiredFields = [ ['byr', v => { const number = Number(v); return v.length === 4 && number >= 1920 && number <= 2002; }], ['iyr', v => { const number = Number(v); return v.length === 4 && number >= 2010 && number <= 2020; }], ['eyr', v => { const number = Number(v); return v.length === 4 && number >= 2020 && number <= 2030; }], ['hgt', v => { const n = Number(v.substring(0, v.length - 2)); if (v.endsWith('cm')) return n >= 150 && n <= 193; else if (v.endsWith('in')) return n >= 59 && n <= 76; else return false; }], ['hcl', v => /^#[0-9a-f]{6}$/.test(v)], ['ecl', v => /^(amb|blu|brn|gry|grn|hzl|oth)$/.test(v)], ['pid', v => /^[0-9]{9}$/.test(v)], ]; let q1 = 0, q2 = 0; for (const passport of passports) { console.log(passport); let q1Fields = 0, q2Fields = 0; for (const [fieldName, validator] of requiredFields) { if (Object.keys(passport).indexOf(fieldName) >= 0) { q1Fields++; if (validator(passport[fieldName])) q2Fields++; console.log('>', fieldName, passport[fieldName], validator(passport[fieldName])); } } console.log('>', q1Fields + '/' + requiredFields.length, q2Fields + '/' + requiredFields.length); if (q1Fields === requiredFields.length) q1++; if (q2Fields === requiredFields.length) q2++; } console.log(q1 + '/' + passports.length, q2 + '/' + passports.length); });