Advertisement
Guest User

Untitled

a guest
Oct 16th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.81 KB | None | 0 0
  1. #include <iostream>
  2. #include <sstream>
  3. #include <cctype>
  4. #include <regex>
  5. #include <algorithm>
  6. #include <string>
  7. #include <vector>
  8. #include <tuple>
  9. #include <map>
  10. #include <set>
  11.  
  12. using namespace std;
  13.  
  14. namespace
  15. {
  16.  
  17. enum ComponentType
  18. {
  19. Transistor,
  20. Diode,
  21. Resistor,
  22. Capacitor,
  23. VoltageSource,
  24. InvalidType
  25. };
  26.  
  27. string componentTypeToString(ComponentType type)
  28. {
  29. switch (type)
  30. {
  31. case Transistor:return "T";
  32. case Diode:return "D";
  33. case Resistor:return "R";
  34. case Capacitor:return "C";
  35. case VoltageSource:return "E";
  36. case InvalidType:return "";
  37. }
  38.  
  39. return "";
  40. }
  41.  
  42. typedef signed long int VertexID;
  43. typedef signed long int ConnectedElementsCount;
  44. typedef string RawLabel;
  45. typedef string Model;
  46. typedef pair<ComponentType, int> Label;
  47. typedef pair<Label, Model> Component;
  48. typedef pair<vector<Label>, Model> ComponentLabelsCollection;
  49.  
  50. ComponentType charToComponentType(const char &c)
  51. {
  52. switch (c)
  53. {
  54. case 'T':return Transistor;
  55. case 'D':return Diode;
  56. case 'R':return Resistor;
  57. case 'C':return Capacitor;
  58. case 'E':return VoltageSource;
  59. default:return InvalidType;
  60. }
  61. }
  62.  
  63. bool validateAbbreviation(const char &abbreviation)
  64. {
  65. ComponentType type = charToComponentType(abbreviation);
  66. return type != InvalidType;
  67. }
  68.  
  69. bool validateNumber(const string &number)
  70. {
  71. bool valid;
  72. signed long int value;
  73. signed long int NUMBER_LOWER_BOUND = 0;
  74. signed long int NUMBER_UPPER_BOUND = 999'999'999;
  75.  
  76. regex number_regex("\\b(([1-9][[:digit:]]*)|[0])\\b"); // ^ isntead of \b ?
  77.  
  78. valid = regex_match(number, number_regex);
  79.  
  80. if (valid)
  81. {
  82. value = stoi(number);
  83.  
  84. if (NUMBER_LOWER_BOUND <= value && value <= NUMBER_UPPER_BOUND)
  85. {
  86. valid = true;
  87. }
  88. }
  89.  
  90. return valid;
  91. }
  92.  
  93. bool validateLabel(const string &word)
  94. {
  95. return validateAbbreviation(word[0]) && validateNumber(word.substr(1));
  96. }
  97.  
  98. bool validateModel(const string &word)
  99. {
  100. regex regex("\\b([[:upper:]]|[[:digit:]])[[:alnum:],-\\/]*([\\s]|$)");
  101.  
  102. return regex_match(word, regex);
  103. }
  104.  
  105. bool validateVertexNumber(const string &number)
  106. {
  107. return validateNumber(number);
  108. }
  109.  
  110. void sendErrorMessage(signed long int line_number, const string &line)
  111. {
  112. cerr << "Error in line " << line_number << ": " << line << "\n"; // Do I need '\n' here?
  113. }
  114.  
  115. vector<Label> *getLabels(ComponentLabelsCollection &collection)
  116. {
  117. return &(collection.first);
  118. }
  119.  
  120. int getLabelsCount(ComponentLabelsCollection &collection)
  121. {
  122. return (*getLabels(collection)).size();
  123. }
  124.  
  125. string labelToString(Label label)
  126. {
  127. return componentTypeToString(label.first) + to_string(label.second);
  128. }
  129.  
  130. string printLabelsCollection(ComponentLabelsCollection &collection)
  131. {
  132. string result = "";
  133. auto labelsCount = getLabelsCount(collection);
  134. for (auto i = 0; i < labelsCount; i++)
  135. {
  136. result += labelToString((*getLabels(collection))[i]);
  137. result += i != labelsCount - 1 ? ", " : ": ";
  138. }
  139. return result + collection.second + "\n";
  140. }
  141.  
  142. void sortLabelsCollection(ComponentLabelsCollection &collection)
  143. {
  144. sort((*getLabels(collection)).begin(), (*getLabels(collection)).end());
  145. }
  146.  
  147. bool compareCollections(ComponentLabelsCollection &labelsCollection1, ComponentLabelsCollection &labelsCollection2)
  148. {
  149. return (*getLabels(labelsCollection1))[0] < (*getLabels(labelsCollection2))[0];
  150. }
  151.  
  152. void sortLabelsCollections(vector<ComponentLabelsCollection> &collections)
  153. {
  154. for (auto &collection: collections)
  155. {
  156. sortLabelsCollection(collection);
  157. }
  158. sort(collections.begin(), collections.end(), compareCollections);
  159. }
  160.  
  161. vector<ComponentLabelsCollection> transformGroupedLabels(map<ComponentType, map<Model, vector<Label>>> &groupedLabels)
  162. {
  163. vector<ComponentLabelsCollection> result;
  164. for (auto &mapOfType: groupedLabels)
  165. {
  166. for (auto &group : mapOfType.second)
  167. result.push_back({group.second, group.first});
  168. }
  169. return result;
  170. }
  171.  
  172. bool isLineEmpty(const string &line)
  173. {
  174. return line.length() == 0;
  175. }
  176.  
  177. bool containsData(const string &line)
  178. {
  179. string word;
  180. stringstream ss;
  181.  
  182. ss << line;
  183. ss >> word;
  184.  
  185. return ss.good();
  186. }
  187.  
  188. int calculateVertexCount(const RawLabel &rawLabel)
  189. {
  190. int vertexCount;
  191.  
  192. if (componentTypeToString(Transistor) == rawLabel.substr(0, 1))
  193. {
  194. vertexCount = 3;
  195. } else
  196. {
  197. vertexCount = 2;
  198. }
  199.  
  200. return vertexCount;
  201. }
  202.  
  203. bool validateVertexID(const string &vertexID)
  204. {
  205. return validateNumber(vertexID);
  206. }
  207.  
  208. bool checkConnectionToDifferentVertices(set<VertexID> &componentVertices)
  209. {
  210. bool valid = false;
  211.  
  212. if (componentVertices.size() > 1)
  213. {
  214. valid = true;
  215. }
  216.  
  217. return valid;
  218. }
  219.  
  220. bool validateComponentVertices(stringstream &ss, const int vertexCount, set<VertexID> &componentVertices)
  221. {
  222. bool valid = true;
  223.  
  224. for (int i = 0; i < vertexCount && valid; ++i)
  225. {
  226. string vertexID;
  227.  
  228. ss >> vertexID;
  229.  
  230. valid &= validateVertexID(vertexID);
  231.  
  232. if (valid)
  233. {
  234. componentVertices.insert(stoi(vertexID));
  235. }
  236. }
  237.  
  238. valid &= checkConnectionToDifferentVertices(componentVertices);
  239.  
  240. return valid;
  241. }
  242.  
  243. bool validateEndOfData(stringstream &ss)
  244. {
  245. string word;
  246. ss >> word;
  247.  
  248. return ss.eof() && ss.fail();
  249. }
  250.  
  251. void connectToVertices(map<VertexID, ConnectedElementsCount> &vertices, const set<VertexID> &componentVertices)
  252. {
  253. for (VertexID vertexID : componentVertices)
  254. {
  255. vertices[vertexID]++;
  256. }
  257. }
  258.  
  259. Label createLabel(const RawLabel &rawLabel)
  260. {
  261. return {charToComponentType(rawLabel[0]), stoi(rawLabel.substr(1))};
  262. }
  263.  
  264. Component createComponent(Label &label, Model &model)
  265. {
  266. return {label, model};
  267. }
  268.  
  269. vector<VertexID> findUnconnectedVertices(const map<VertexID, ConnectedElementsCount> &vertices)
  270. {
  271. vector<VertexID> unconnectedVectices;
  272.  
  273. for (auto &vertex : vertices)
  274. {
  275. if (vertex.second < 2)
  276. {
  277. unconnectedVectices.push_back(vertex.first);
  278. }
  279. }
  280.  
  281. sort(unconnectedVectices.begin(), unconnectedVectices.end());
  282.  
  283. return unconnectedVectices;
  284. }
  285.  
  286. void sendErrorUnconnectedVertices(vector<VertexID> &unconnectedVectices)
  287. {
  288. cerr << "Warning, unconnected node(s): ";
  289.  
  290. for (vector<VertexID>::size_type i = 0; i < unconnectedVectices.size() - 1; ++i)
  291. {
  292. cerr << unconnectedVectices[i] << ", ";
  293. }
  294.  
  295. cerr << unconnectedVectices[unconnectedVectices.size() - 1] << "\n";
  296. }
  297.  
  298. void checkForUnconnectedVertices(map<VertexID, ConnectedElementsCount> &vertices)
  299. {
  300. vector<VertexID> unconnectedVectices = findUnconnectedVertices(vertices);
  301.  
  302. if (unconnectedVectices.size() > 0)
  303. {
  304. sendErrorUnconnectedVertices(unconnectedVectices);
  305. }
  306. }
  307. }
  308. int main()
  309. {
  310. string line;
  311. int lineNumber = 1;
  312. map<VertexID, ConnectedElementsCount> vertices;
  313. map<ComponentType, map<Model, vector<Label>>> groupedLabels;
  314. map<RawLabel, bool> labelsExist;
  315.  
  316. vertices[0]=0;
  317.  
  318. while (!cin.eof())
  319. {
  320. getline(cin, line);
  321.  
  322. if (!isLineEmpty(line))
  323. {
  324. bool valid;
  325. stringstream ss;
  326.  
  327. RawLabel rawLabel;
  328. Label label;
  329. Model model;
  330. Component component;
  331. set<VertexID> componentVertices;
  332.  
  333. string word;
  334. int vertexCount;
  335.  
  336. valid = containsData(line);
  337. ss << line;
  338.  
  339. ss >> rawLabel;
  340. valid &= validateLabel(rawLabel);
  341.  
  342. ss >> model;
  343. valid &= validateModel(model);
  344.  
  345. if (valid)
  346. {
  347. vertexCount = calculateVertexCount(rawLabel);
  348.  
  349. valid &= validateComponentVertices(ss, vertexCount, componentVertices);
  350. valid &= validateEndOfData(ss);
  351.  
  352. valid &= (!labelsExist[rawLabel]);
  353. }
  354.  
  355. if (valid)
  356. {
  357. labelsExist[rawLabel] = true;
  358. connectToVertices(vertices, componentVertices);
  359.  
  360. label = createLabel(rawLabel);
  361.  
  362. component = createComponent(label, model);
  363.  
  364. groupedLabels[label.first][model].push_back(label);
  365. } else
  366. {
  367. sendErrorMessage(lineNumber, line);
  368. }
  369. }
  370.  
  371. lineNumber++;
  372. }
  373.  
  374. checkForUnconnectedVertices(vertices);
  375. auto labelsCollection = transformGroupedLabels(groupedLabels);
  376. sortLabelsCollections(labelsCollection);
  377. for (auto &collection: labelsCollection)
  378. {
  379. cout << printLabelsCollection(collection);
  380. }
  381.  
  382. return 0;
  383. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement