module day4.part1 copy.main; import std; void main() { readText("input").parsePassports.countValidPassports.writeln; } alias Passport = string[string]; auto parsePassports(string input) { return input.splitter("\n\n").map!(passport => passport.splitter().map!((entry) { auto keyAndValue = entry.split(':'); return tuple(keyAndValue[0], keyAndValue[1]); }).assocArray); } enum requiredFields = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]; bool isValidPassport(Passport passport) { return requiredFields.all!(field => field in passport); } auto countValidPassports(R)(R r) if (isInputRange!R && is(ElementType!R == Passport)) { return r.filter!isValidPassport.count; } unittest { auto 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`; auto passPorts = input.parsePassports; assert(passPorts.countValidPassports == 2); }