//Fun/AdventCalendar2020/Day4-1.cpp //Matthew Ellison // Created: 12-04-20 //Modified: 12-04-20 //Validate passport data #include #include #include #include #include "Stopwatch.hpp" #include "Algorithms.hpp" struct passport{ std::string birthYear; std::string issueYear; std::string expirationYear; std::string height; std::string hairColor; std::string eyeColor; std::string passportId; std::string countryId; //Returns true if the passport is valid bool isValid(){ if(birthYearIsValid() && issueYearIsValid() && expirationYearIsValid() && heightIsValid() && hairColorIsValid() && eyeColorIsValid() && passportIdIsValid()){ return true; } else{ return false; } } //Returns true if the string is a valid string bool validString(std::string str){ if(!str.empty()){ return true; } else{ return false; } } bool birthYearIsValid(){ //There must be four digits if(birthYear.size() != 4){ return false; } //That are all numbers for(char ch : birthYear){ if(!std::isdigit(ch)){ return false; } } //The number must be 1920 <= x <= 2002 int num = std::stoi(birthYear); if((num < 1920) || (num > 2002)){ return false; } //If none of the other conditions were hit return true; return true; } bool issueYearIsValid(){ //There must be four digits if(issueYear.size() != 4){ return false; } //That are all numbers for(char ch : issueYear){ if(!std::isdigit(ch)){ return false; } } //The number must be 2010 <= x <= 2020 int num = std::stoi(issueYear); if((num < 2010) || (num > 2020)){ return false; } //If none of the other conditions were hit return true; return true; } bool expirationYearIsValid(){ //There must be four digits if(expirationYear.size() != 4){ return false; } //That are all numbers for(char ch : expirationYear){ if(!std::isdigit(ch)){ return false; } } //The number must be 2020<= x <= 2030 int num = std::stoi(expirationYear); if((num < 2020) || (num > 2030)){ return false; } //If none of the other conditions were hit return true; return true; } bool heightIsValid(){ //It must be a number followed by 2 characters (in or cm) //Split the string into digits and suffix std::string numStr; int num = 0; std::string suffix; int strLoc = 0; for(;strLoc < height.size();++strLoc){ if(std::isdigit(height[strLoc])){ numStr += height[strLoc]; } else{ break; } } if(numStr.size() == 0){ return false; } num = std::stoi(numStr); for(;strLoc < height.size();++strLoc){ if(std::isdigit(height[strLoc])){ return false; } else{ suffix += height[strLoc]; } } //If suffix is in 59 <= x <= 76 if(suffix == "in"){ if((num < 59) || (num > 76)){ return false; } else{ return true; } } //If suffix is cm 150 <= x <= 193 else if(suffix == "cm"){ if((num < 150) || (num > 193)){ return false; } else{ return true; } } else{ return false; } //If none of the other conditions were hit return true; return true; } bool hairColorIsValid(){ //Contains 7 characters if(hairColor.size() != 7){ return false; } //Start with # if(hairColor[0] != '#'){ return false; } //Then 6 hex characters for(int cnt = 1;cnt < hairColor.size();++cnt){ if(!std::isxdigit(hairColor[cnt])){ return false; } } //If none of the other conditions were hit return true; return true; } bool eyeColorIsValid(){ //amb or blu or brn or gry or grn or hzl or oth if(eyeColor == "amb"){ return true; } else if(eyeColor == "blu"){ return true; } else if(eyeColor == "brn"){ return true; } else if(eyeColor == "gry"){ return true; } else if(eyeColor == "grn"){ return true; } else if(eyeColor == "hzl"){ return true; } else if(eyeColor == "oth"){ return true; } else{ return false; } } bool passportIdIsValid(){ //Must be a 9-digit number if(passportId.size() != 9){ return false; } for(char ch : passportId){ if(!std::isdigit(ch)){ return false; } } //If none of the other conditions were hit return true; return true; } }; std::vector importData(){ std::vector passports; std::ifstream inputFile; inputFile.open("inputs/Day4.txt"); //Open the file that has the input for the question //Get the input one line at a time because a full blank line is the end of a passport while(!inputFile.eof()){ passport currentPassport; std::string currentLine; std::getline(inputFile, currentLine); while(currentLine != ""){ //Split the string on [space] for(std::string str : mee::split(currentLine, ' ')){ //Split the string on : std::vector fields = mee::split(str, ':'); std::string field = fields[0]; std::string value = fields[1]; //Determine what field you are dealing with and save the data if(field == "byr"){ currentPassport.birthYear = value; } else if(field == "iyr"){ currentPassport.issueYear = value; } else if(field == "eyr"){ currentPassport.expirationYear = value; } else if(field == "hgt"){ currentPassport.height = value; } else if(field == "hcl"){ currentPassport.hairColor = value; } else if(field == "ecl"){ currentPassport.eyeColor = value; } else if(field == "pid"){ currentPassport.passportId = value; } else if(field == "cid"){ currentPassport.countryId = value; } else{ std::cout << "ERROR!\n" << "field = " << field << "\tValue = " << value << std::endl; exit(1); } } std::getline(inputFile, currentLine); } passports.push_back(currentPassport); } return passports; } int main(){ mee::Stopwatch timer; int validPassports = 0; //Start the timer timer.start(); //Get the passport data std::vector passports = importData(); //Count how many are valid for(passport pspt : passports){ if(pspt.isValid()){ ++validPassports; } } //Stop the timer timer.stop(); //Print the results std::cout << "There are " << validPassports << " valid passports" << "\nIt took " << timer.getStr() << " to finish this problem" << std::endl; return 0; } /* Results: There are 175 valid passports It took 1.999 milliseconds to finish this problem */