Files
AdventOfCode2020/Day4-2.cpp
2020-12-04 21:34:42 -05:00

308 lines
6.3 KiB
C++

//Fun/AdventCalendar2020/Day4-2.cpp
//Matthew Ellison
// Created: 12-04-20
//Modified: 12-04-20
//Validate passport data
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#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<passport> importData(){
std::vector<passport> 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<std::string> 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<passport> 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
*/