#include #include #include #include #include #include #include #include "solutions.hpp" using namespace std; bool is_digit(char c) { return isdigit((int) c); } bool is_hex_digit(char c) { return isdigit((int) c) || (c >= 'a' && c <= 'f'); } template <> pair solve<4>(istream& input) { cerr << boolalpha; stringstream current_passport{string()}; uint64_t part1 = 0, part2 = 0; unordered_map> valid_funcs; valid_funcs["byr"] = [](string &value) { int int_value = stoi(value); return value.length() == 4 && all_of(value.begin(), value.end(), is_digit) && int_value >= 1920 && int_value <= 2002; }; valid_funcs["iyr"] = [](string &value) { int int_value = stoi(value); return value.length() == 4 && all_of(value.begin(), value.end(), is_digit) && int_value >= 2010 && int_value <= 2020; }; valid_funcs["eyr"] = [](string &value) { int int_value = stoi(value); return value.length() == 4 && all_of(value.begin(), value.end(), is_digit) && int_value >= 2020 && int_value <= 2030; }; valid_funcs["hgt"] = [](string &value) { int int_value = stoi(value); return (value.length() == to_string(int_value).length() + 2) && ( (value.ends_with("in") && int_value >= 59 && int_value <= 76) || (value.ends_with("cm") && int_value >= 150 && int_value <= 193) ); }; valid_funcs["hcl"] = [](string &value) { auto it = value.begin(); return value.length() == 7 && *it == '#' && all_of(next(it), value.end(), is_hex_digit); }; valid_funcs["ecl"] = [](string &value) { unordered_set valid_eye_colors = { { "amb"s, "blu"s, "brn"s, "gry"s, "grn"s, "hzl"s, "oth"s } }; return valid_eye_colors.contains(value); }; valid_funcs["pid"] = [](string &value) { return value.length() == 9 && all_of(value.begin(), value.end(), is_digit); }; for (string line; getline(input, line); ) { if (!line.empty()) { // append to existing passport if (!current_passport.eof()) { current_passport << ' '; } current_passport << line; } if (line.empty() || input.peek() == EOF) { // no input; parse current passport unordered_set mandatory_fields = { { "byr"s, "iyr"s, "eyr"s, "hgt"s, "hcl"s, "ecl"s, "pid"s} }; bool all_fields_valid = true; for (string entry; getline(current_passport, entry, ' '); ) { auto field_delim_pos = entry.find(':'); if (field_delim_pos != string::npos) { string field_name = entry.substr(0, field_delim_pos); string field_value = entry.substr(field_delim_pos+1); mandatory_fields.erase(field_name); if (valid_funcs.contains(field_name)) { all_fields_valid = all_fields_valid && valid_funcs[field_name](field_value); } } } current_passport.clear(); part1 += (uint64_t) mandatory_fields.empty(); part2 += (uint64_t) (mandatory_fields.empty() && all_fields_valid); } } return pair(to_string(part1), to_string(part2)); }