Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <cctype>
- #include <regex>
- #include <algorithm>
- #include <string>
- #include <vector>
- #include <tuple>
- #include <map>
- #include <set>
- using namespace std;
- namespace
- {
- enum ComponentType
- {
- Transistor,
- Diode,
- Resistor,
- Capacitor,
- VoltageSource,
- InvalidType
- };
- string componentTypeToString(ComponentType type)
- {
- switch (type)
- {
- case Transistor:return "T";
- case Diode:return "D";
- case Resistor:return "R";
- case Capacitor:return "C";
- case VoltageSource:return "E";
- case InvalidType:return "";
- }
- return "";
- }
- typedef signed long int VertexID;
- typedef signed long int ConnectedElementsCount;
- typedef string RawLabel;
- typedef string Model;
- typedef pair<ComponentType, int> Label;
- typedef pair<Label, Model> Component;
- typedef pair<vector<Label>, Model> ComponentLabelsCollection;
- ComponentType charToComponentType(const char &c)
- {
- switch (c)
- {
- case 'T':return Transistor;
- case 'D':return Diode;
- case 'R':return Resistor;
- case 'C':return Capacitor;
- case 'E':return VoltageSource;
- default:return InvalidType;
- }
- }
- bool validateAbbreviation(const char &abbreviation)
- {
- ComponentType type = charToComponentType(abbreviation);
- return type != InvalidType;
- }
- bool validateNumber(const string &number)
- {
- bool valid;
- signed long int value;
- signed long int NUMBER_LOWER_BOUND = 0;
- signed long int NUMBER_UPPER_BOUND = 999'999'999;
- regex number_regex("\\b(([1-9][[:digit:]]*)|[0])\\b"); // ^ isntead of \b ?
- valid = regex_match(number, number_regex);
- if (valid)
- {
- value = stoi(number);
- if (NUMBER_LOWER_BOUND <= value && value <= NUMBER_UPPER_BOUND)
- {
- valid = true;
- }
- }
- return valid;
- }
- bool validateLabel(const string &word)
- {
- return validateAbbreviation(word[0]) && validateNumber(word.substr(1));
- }
- bool validateModel(const string &word)
- {
- regex regex("\\b([[:upper:]]|[[:digit:]])[[:alnum:],-\\/]*([\\s]|$)");
- return regex_match(word, regex);
- }
- bool validateVertexNumber(const string &number)
- {
- return validateNumber(number);
- }
- void sendErrorMessage(signed long int line_number, const string &line)
- {
- cerr << "Error in line " << line_number << ": " << line << "\n"; // Do I need '\n' here?
- }
- vector<Label> *getLabels(ComponentLabelsCollection &collection)
- {
- return &(collection.first);
- }
- int getLabelsCount(ComponentLabelsCollection &collection)
- {
- return (*getLabels(collection)).size();
- }
- string labelToString(Label label)
- {
- return componentTypeToString(label.first) + to_string(label.second);
- }
- string printLabelsCollection(ComponentLabelsCollection &collection)
- {
- string result = "";
- auto labelsCount = getLabelsCount(collection);
- for (auto i = 0; i < labelsCount; i++)
- {
- result += labelToString((*getLabels(collection))[i]);
- result += i != labelsCount - 1 ? ", " : ": ";
- }
- return result + collection.second + "\n";
- }
- void sortLabelsCollection(ComponentLabelsCollection &collection)
- {
- sort((*getLabels(collection)).begin(), (*getLabels(collection)).end());
- }
- bool compareCollections(ComponentLabelsCollection &labelsCollection1, ComponentLabelsCollection &labelsCollection2)
- {
- return (*getLabels(labelsCollection1))[0] < (*getLabels(labelsCollection2))[0];
- }
- void sortLabelsCollections(vector<ComponentLabelsCollection> &collections)
- {
- for (auto &collection: collections)
- {
- sortLabelsCollection(collection);
- }
- sort(collections.begin(), collections.end(), compareCollections);
- }
- vector<ComponentLabelsCollection> transformGroupedLabels(map<ComponentType, map<Model, vector<Label>>> &groupedLabels)
- {
- vector<ComponentLabelsCollection> result;
- for (auto &mapOfType: groupedLabels)
- {
- for (auto &group : mapOfType.second)
- result.push_back({group.second, group.first});
- }
- return result;
- }
- bool isLineEmpty(const string &line)
- {
- return line.length() == 0;
- }
- bool containsData(const string &line)
- {
- string word;
- stringstream ss;
- ss << line;
- ss >> word;
- return ss.good();
- }
- int calculateVertexCount(const RawLabel &rawLabel)
- {
- int vertexCount;
- if (componentTypeToString(Transistor) == rawLabel.substr(0, 1))
- {
- vertexCount = 3;
- } else
- {
- vertexCount = 2;
- }
- return vertexCount;
- }
- bool validateVertexID(const string &vertexID)
- {
- return validateNumber(vertexID);
- }
- bool checkConnectionToDifferentVertices(set<VertexID> &componentVertices)
- {
- bool valid = false;
- if (componentVertices.size() > 1)
- {
- valid = true;
- }
- return valid;
- }
- bool validateComponentVertices(stringstream &ss, const int vertexCount, set<VertexID> &componentVertices)
- {
- bool valid = true;
- for (int i = 0; i < vertexCount && valid; ++i)
- {
- string vertexID;
- ss >> vertexID;
- valid &= validateVertexID(vertexID);
- if (valid)
- {
- componentVertices.insert(stoi(vertexID));
- }
- }
- valid &= checkConnectionToDifferentVertices(componentVertices);
- return valid;
- }
- bool validateEndOfData(stringstream &ss)
- {
- string word;
- ss >> word;
- return ss.eof() && ss.fail();
- }
- void connectToVertices(map<VertexID, ConnectedElementsCount> &vertices, const set<VertexID> &componentVertices)
- {
- for (VertexID vertexID : componentVertices)
- {
- vertices[vertexID]++;
- }
- }
- Label createLabel(const RawLabel &rawLabel)
- {
- return {charToComponentType(rawLabel[0]), stoi(rawLabel.substr(1))};
- }
- Component createComponent(Label &label, Model &model)
- {
- return {label, model};
- }
- vector<VertexID> findUnconnectedVertices(const map<VertexID, ConnectedElementsCount> &vertices)
- {
- vector<VertexID> unconnectedVectices;
- for (auto &vertex : vertices)
- {
- if (vertex.second < 2)
- {
- unconnectedVectices.push_back(vertex.first);
- }
- }
- sort(unconnectedVectices.begin(), unconnectedVectices.end());
- return unconnectedVectices;
- }
- void sendErrorUnconnectedVertices(vector<VertexID> &unconnectedVectices)
- {
- cerr << "Warning, unconnected node(s): ";
- for (vector<VertexID>::size_type i = 0; i < unconnectedVectices.size() - 1; ++i)
- {
- cerr << unconnectedVectices[i] << ", ";
- }
- cerr << unconnectedVectices[unconnectedVectices.size() - 1] << "\n";
- }
- void checkForUnconnectedVertices(map<VertexID, ConnectedElementsCount> &vertices)
- {
- vector<VertexID> unconnectedVectices = findUnconnectedVertices(vertices);
- if (unconnectedVectices.size() > 0)
- {
- sendErrorUnconnectedVertices(unconnectedVectices);
- }
- }
- }
- int main()
- {
- string line;
- int lineNumber = 1;
- map<VertexID, ConnectedElementsCount> vertices;
- map<ComponentType, map<Model, vector<Label>>> groupedLabels;
- map<RawLabel, bool> labelsExist;
- vertices[0]=0;
- while (!cin.eof())
- {
- getline(cin, line);
- if (!isLineEmpty(line))
- {
- bool valid;
- stringstream ss;
- RawLabel rawLabel;
- Label label;
- Model model;
- Component component;
- set<VertexID> componentVertices;
- string word;
- int vertexCount;
- valid = containsData(line);
- ss << line;
- ss >> rawLabel;
- valid &= validateLabel(rawLabel);
- ss >> model;
- valid &= validateModel(model);
- if (valid)
- {
- vertexCount = calculateVertexCount(rawLabel);
- valid &= validateComponentVertices(ss, vertexCount, componentVertices);
- valid &= validateEndOfData(ss);
- valid &= (!labelsExist[rawLabel]);
- }
- if (valid)
- {
- labelsExist[rawLabel] = true;
- connectToVertices(vertices, componentVertices);
- label = createLabel(rawLabel);
- component = createComponent(label, model);
- groupedLabels[label.first][model].push_back(label);
- } else
- {
- sendErrorMessage(lineNumber, line);
- }
- }
- lineNumber++;
- }
- checkForUnconnectedVertices(vertices);
- auto labelsCollection = transformGroupedLabels(groupedLabels);
- sortLabelsCollections(labelsCollection);
- for (auto &collection: labelsCollection)
- {
- cout << printLabelsCollection(collection);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement