fork(2) download
  1. #include <iostream>
  2. #include <string>
  3. #include <map>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include <functional>
  7. #include <chrono>
  8.  
  9. template <typename unit, typename Clock = std::chrono::high_resolution_clock>
  10. struct StopWatch {
  11. typename Clock::time_point start;
  12. StopWatch() : start(Clock::now()) {}
  13.  
  14. unsigned getDifference(){
  15. return std::chrono::duration_cast<unit>(Clock::now() - start).count();
  16. }
  17. };
  18.  
  19. template <typename Integer>
  20. struct Resolver {
  21. using Calculator = std::function<Integer(Integer,Integer)>;
  22.  
  23. std::string line;
  24. std::string word1;
  25. std::string word2;
  26. std::string ope;
  27. std::string word3;
  28.  
  29. std::map<char,Integer> charCombinationMap;
  30. Calculator calcurator;
  31.  
  32. static Calculator getBinaryCalculator(std::string& operatorString){
  33. if( operatorString.size() == 1 ) switch(operatorString[0]){
  34. case '+': return std::plus<Integer>();
  35. case '-': return std::minus<Integer>();
  36. case '*': return std::multiplies<Integer>();
  37. case '/': return std::divides<Integer>();
  38. }
  39. return std::plus<Integer>();
  40. }
  41.  
  42. Resolver(std::string& aLine) : line(aLine) {
  43. std::string eq;
  44. std::stringstream(line) >> word1 >> ope >> word2 >> eq >> word3;
  45. calcurator = getBinaryCalculator(ope);
  46. }
  47.  
  48. std::string getResultString(){
  49. std::string result;
  50. std::string integerMap = "0123456789";
  51. for( auto ch :line )
  52. result.push_back( (charCombinationMap.count(ch) > 0) ?
  53. integerMap[ charCombinationMap[ch] ] : ch );
  54.  
  55. return result;
  56. }
  57.  
  58. bool validate(){
  59. for( auto word: std::vector<std::string>{word1,word2,word3} )
  60. if( charCombinationMap[ word[0] ] == 0 )
  61. return false;
  62.  
  63. return calcurator( toInteger(word1), toInteger(word2) ) == toInteger(word3);
  64. }
  65.  
  66. Integer toInteger(std::string& word){
  67. return std::accumulate( word.begin(), word.end(),0, [&](Integer prev, char ch){
  68. return (prev * 10) + charCombinationMap[ch];
  69. });
  70. }
  71.  
  72. std::string getCharList(){
  73. std::string charList;
  74. {
  75. std::map<char,bool> exists;
  76. for( auto word: std::vector<std::string>{word1,word2,word3} )
  77. for( auto ch: word )
  78. exists[ch] = true;
  79.  
  80. for( auto entry: exists )
  81. charList.push_back(entry.first);
  82. }
  83. return charList;
  84. }
  85.  
  86. std::string resolve(){
  87. std::string charList = getCharList();
  88. std::vector<bool> taken(10);
  89. std::fill(taken.end() - charList.size(), taken.end() , true);
  90.  
  91. do {
  92. std::vector<Integer> combination;
  93. for (int i = 0; i < 10; ++i){
  94. if ( taken[i] )
  95. combination.push_back(i);
  96. }
  97.  
  98. do {
  99. auto it = charList.begin();
  100. for( auto value :combination ){
  101. charCombinationMap[*it] = value;
  102. ++it;
  103. }
  104.  
  105. if( validate() )
  106. return getResultString();
  107. }
  108. while (std::next_permutation(combination.begin(), combination.end()));
  109.  
  110. }
  111. while (std::next_permutation(taken.begin(), taken.end()));
  112.  
  113. return "not found";
  114. }
  115. };
  116.  
  117. int main() {
  118. for( std::string line; std::getline(std::cin,line); ){
  119. StopWatch<std::chrono::milliseconds> stopWatch;
  120. std::string result = Resolver<int>(line).resolve();
  121.  
  122. std::cout << result
  123. << " (in " << stopWatch.getDifference() << "ms)"
  124. << std::endl;
  125. }
  126.  
  127. return 0;
  128. }
Success #stdin #stdout 2.26s 3248KB
stdin
SEND + MORE = MONEY
WWWDOT - GOOGLE = DOTCOM
stdout
9567 + 1085 = 10652 (in 1160ms)
777589 - 188103 = 589486 (in 1113ms)