#include #include #include #include #include #include std::vector read_input_file() { std::ifstream file("input"); std::vector data; std::string line; while(std::getline(file, line)) data.push_back(line); return data; } std::vector split(const std::string &s) { std::vector tokens; std::string token; std::istringstream token_stream(s); while(std::getline(token_stream, token, ' ')) tokens.push_back(token); return tokens; } typedef std::unordered_map passport; std::vector parse_passports(const std::vector &data) { std::vector passports; passport current; for(auto &line : data) { if(line != ""){ for(auto &field : split(line)) { current[field.substr(0,3)] = field.substr(4, field.size()); } } else { passports.push_back(current); current.clear(); } } passports.push_back(current); return passports; } bool has_fields(const passport &passport) { return passport.find("byr") != passport.end() && passport.find("iyr") != passport.end() && passport.find("eyr") != passport.end() && passport.find("hgt") != passport.end() && passport.find("hcl") != passport.end() && passport.find("ecl") != passport.end() && passport.find("pid") != passport.end(); } bool validate_birth(const passport &passport) { return stoi(passport.at("byr")) >= 1920 && stoi(passport.at("byr")) <= 2002; } bool validate_issue(const passport &passport) { return stoi(passport.at("iyr")) >= 2010 && stoi(passport.at("iyr")) <= 2020; } bool validate_expire(const passport &passport) { return stoi(passport.at("eyr")) >= 2020 && stoi(passport.at("eyr")) <= 2030; } bool validate_eye(const passport &passport) { std::string color = passport.at("ecl"); return color == "amb" || color == "blu" || color == "brn" || color == "gry" || color == "grn" || color == "hzl" || color == "oth"; } bool validate_hair(const passport &passport) { return std::regex_match(passport.at("hcl"), std::regex("^#[0-9a-f]{6}$")); } bool validate_pid(const passport &passport) { return std::regex_match(passport.at("pid"), std::regex("^[0-9]{9}$")); } bool validate_height(const passport &passport) { std::string hgt = passport.at("hgt"); std::string unit = hgt.substr(hgt.size() - 2, 2); int height = stoi(hgt); if (unit == "cm" && height >= 150 && height <= 193) return true; else if(unit == "in" && height >= 59 && height <= 76) return true; else return false; } bool full_validation(const passport &passport) { return has_fields(passport) && validate_birth(passport) && validate_issue(passport) && validate_expire(passport) && validate_hair(passport) && validate_pid(passport) && validate_eye(passport) && validate_height(passport); } void print_passport(const passport &passport) { std::cout << "---------------------------" << std::endl; for(auto &pair: passport) { std::cout << "[" << pair.first << "] = " << pair.second << std::endl; } std::cout << "---------------------------" << std::endl; } int solve_a(const std::vector &passports) { int count = 0; for(auto &passport: passports) if(has_fields(passport)) count++; return count; } int solve_b(const std::vector &passports) { int count = 0; for(auto &passport: passports) { if(full_validation(passport)) count++; } return count; } int main() { auto data = read_input_file(); auto passports = parse_passports(data); std::cout << solve_a(passports) << ' ' << solve_b(passports) << std::endl; return 0; }