Verbal Arithmetic Puzzle in C++


Suppose we have an equation, expressions are represented by words on left side and the result on right side. We have to check whether the equation is solvable under the following rules or not −

  • Each character is decoded as one digit (0 to 9).

  • Every pair of different characters must map to different digits.

  • Each words[i] and result are decoded as a number where no leading zeros are present.

  • Sum of numbers on left side will equal to the number on right side.

  • We will check whether the equation is solvable or not.

So, if the input is like words = ["SEND","MORE"], result = "MONEY", then the output will beTrue, as when we map the letters as follows: Map 'S'-> 9, 'E'->5, 'N'->6, 'D'->7, 'M'->1, 'O'->0,'R'->8, 'Y'->'2', then "SEND" + "MORE" = "MONEY" is same as 9567 + 1085 = 10652.

To solve this, we will follow these steps −

  • Define an array i2c of size: 10, an array c2i of size: 26 and another array w

  • Define a function solve(), this will take idx, l, sum,

  • if l is same as size of r, then −

    • return true when sum is same as 0

  • if idx is same as size of w, then −

    • if c2i[r[l] - ASCII of 'A'] is not equal to -1, then −

      • if c2i[r[l] - ASCII of 'A'] is same as sum mod 10, then −

        • return solve(0, l + 1, sum / 10)

    • otherwise when i2c[sum mod 10] is same as -1, then −

      • if l is same as size of r and sum mod 10 is same as 0, then −

        • return false

      • c2i[r[l] - ASCII of 'A'] = sum mod 10

      • i2c[sum mod 10] = r[l] - ASCII of 'A'

      • temp := solve(0, l + 1, sum / 10)

      • c2i[r[l] - ASCII of 'A'] = - 1

      • i2c[sum mod 10] = - 1

      • return temp

    • return false

  • if l >= size of w[idx], then −

    • return solve(idx + 1, l, sum)

  • if c2i[w[idx, l] - 'A'] is not equal to -1, then −

    • if l is same as size of w[idx] and c2i[w[idx, l] - ASCII of 'A'] is same as 0, then −

      • return false

    • return solve(idx + 1, l, sum + c2i[w[idx, l] - ASCII of 'A'])

  • for initialize i := 0, when i < 10, update (increase i by 1), do −

    • if i2c[i] is not equal to -1, then −

      • Ignore following part, skip to the next iteration

    • if i is same as 0 and l is same as size of w[idx], then −

      • Ignore following part, skip to the next iteration

    • i2c[i] := w[idx, l] - ASCII of 'A'

    • c2i[w[idx, l] - ASCII of 'A'] = i

    • temp := solve(idx + 1, l, sum + i)

    • i2c[i] := -1

    • c2i[w[idx, l] - ASCII of 'A'] = - 1

    • if temp is non-zero, then −

      • return true

  • return false

  • From the main method do the following −

  • fill i2c and c2i with -1

  • reverse the array result

  • for initialize i := 0, when i < size of words, update (increase i by 1), do−

    • if size of words[i] > size of result, then −

      • return false

    • reverse the array words[i]

  • r := result, w := words

  • return solve(0, 0, 0)

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   char i2c[10];
   int c2i[26];
   vector<string> w;
   string r;
   bool solve(int idx, int l, int sum){
      if (l == r.size()) {
         return sum == 0;
      }
      if (idx == w.size()) {
         if (c2i[r[l] - 'A'] != -1) {
            if (c2i[r[l] - 'A'] == sum % 10) {
               return solve(0, l + 1, sum / 10);
            }
         }
         else if (i2c[sum % 10] == -1) {
            if (l == r.size() - 1 && sum % 10 == 0)
            return false;
            c2i[r[l] - 'A'] = sum % 10;
            i2c[sum % 10] = r[l] - 'A';
            bool temp = solve(0, l + 1, sum / 10);
            c2i[r[l] - 'A'] = -1;
            i2c[sum % 10] = -1;
            return temp;
         }
         return false;
      }
      if (l >= w[idx].size()) {
         return solve(idx + 1, l, sum);
      }
      if (c2i[w[idx][l] - 'A'] != -1) {
         if (l == w[idx].size() - 1 && c2i[w[idx][l] - 'A'] == 0){
            return false;
         }
         return solve(idx + 1, l, sum + c2i[w[idx][l] - 'A']);
      }
      for (int i = 0; i < 10; i++) {
         if (i2c[i] != -1)
         continue;
         if (i == 0 && l == w[idx].size() - 1)
         continue;
         i2c[i] = w[idx][l] - 'A';
         c2i[w[idx][l] - 'A'] = i;
         bool temp = solve(idx + 1, l, sum + i);
         i2c[i] = -1;
         c2i[w[idx][l] - 'A'] = -1;
         if (temp)
         return true;
      }
      return false;
   }
   bool isSolvable(vector<string>& words, string result){
      memset(i2c, -1, sizeof(i2c));
      memset(c2i, -1, sizeof(c2i));
      reverse(result.begin(), result.end());
      for (int i = 0; i < words.size(); i++) {
         if (words[i].size() > result.size())
         return false;
         reverse(words[i].begin(), words[i].end());
      }
      r = result;
      w = words;
      return solve(0, 0, 0);
   }
};
main(){
   Solution ob;
   vector<string> v = {"SEND","MORE"};
   cout << (ob.isSolvable(v, "MONEY"));
}

Input

{"SEND","MORE"}, "MONEY"

Output

1

Updated on: 08-Jun-2020

367 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements