Obwody

                Never    
C/C++
       
#include <iostream>
#include <sstream>
#include <cctype>
#include <regex>
#include <algorithm>
#include <string>
#include <vector>
#include <tuple>
#include <map>
#include <set>

#define NUMBER_LOWER_BOUND 0
#define NUMBER_UPPER_BOUND 999'999'999

using namespace std;

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";
    }
}

typedef int VertexID;
typedef 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;
    int value;
    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:],-/]*\\b");

    return regex_match(word, regex);
}

bool validateVertexNumber(const string& number) {
    return validateNumber(number);
}

void sendErrorMessage(int line_number, const string& line) {
    cerr << "Error in line " << line_number << ": " << line; // 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 (int 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);
}

bool isLineEmpty(const string &line) {
    string word;
    stingstream ss;

    ss << line;
    ss >> word;

    return ss.good();
}

bool validateLine(stringstream &ss, RawLabel &rawLabel, Model &model, set<VertexID> &componentVertices, map<VertexID, ConnectedElementsCount> &vertices) {
    bool valid = true;
    string word;
    int vertexCount;

    ss >> rawLabel;
    valid &= validateLabel(rawLabel);

    ss >> model;
    valid &= validateModel(model);

    if (valid) {
        vertexCount = calculateVertexCount(rawLabel);

        valid = validateComponentVertices(ss, vertexCount, componentVertices);
    }

    return valid;
}

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;
}

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};
}

int main() {
    string line;
    int lineNumber = 1;
    map<VertexID, ConnectedElementsCount> vertices;

    while (getline(cin, line)) {
        if (!isLineEmpty(line)) {
            bool valid;
            stringstream ss << line;

            RawLabel rawLabel;
            Label label;
            Model model;
            Component component;
            set<VertexID> componentVertices;

            valid = validateLine(ss, rawLabel, model, componentVertices, vertices);

            if (valid) {
                connectToVertices(vertices, componentVertices);

                label = createLabel(rawLabel);
                component = createComponent(label, model);
            } else {
                sendErrorMessage(lineNumber, line);
            }
        }

        lineNumber++;
    }

    Label label1 = {Diode, 126};
    Label label2 = {Diode, 595};
    Label label3 = {Diode, 65};

    Label label4 = {Diode, 123};
    Label label5 = {Diode, 995};
    Label label6 = {Diode, 265};

    Label label7 = {VoltageSource, 123};
    Label label8 = {VoltageSource, 795};
    Label label9 = {VoltageSource, 565};

    vector<Label> collection1 = {label1, label2, label3};
    vector<Label> collection2 = {label4, label5, label6};
    vector<Label> collection3 = {label7, label8, label9};
    ComponentLabelsCollection labelsCollection1 = {collection1, "blah1"};
    ComponentLabelsCollection labelsCollection2 = {collection2, "blah2"};
    ComponentLabelsCollection labelsCollection3 = {collection3, "blah3"};
    vector<ComponentLabelsCollection> collections = {labelsCollection1, labelsCollection2, labelsCollection3};
    for (auto& collection : collections) {
        cout <<printLabelsCollection(collection);
    }
    cout <<"\n";
    sortLabelsCollections(collections);
    for (auto& collection : collections) {
        cout <<printLabelsCollection(collection);
    }
}

Raw Text