[try Beta version]
Not logged in

 
solving a puzzle

Jan 31, 2016 at 3:07pm
S E N D
+ M O R E
-----------
M O N E Y

I want to start programming a solution for this puzzle, not only this specific words but other words like: TOO + TOO = GOOD and etc.

I thought about it and decided that I need to use: Brute Force, Vectors, Next_Permutation().

But I honestly don't know how to start it.

The initial part which I must do which is assigning letters to numbers. I don't know how to do that with vectors. I think I will need two vectors but how can I assign the values in the first vectors to the values in the second vector?

Sample Input:
1
2
3
TO + GET = HER

SEND + MORE = MONEY


Sample Output:
1
2
3
no solution

9567 + 1085 = 10652


This is what I have so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
	vector <char> smm = { 'S', 'E', 'N', 'D', 'M', 'O', 'R', 'Y' };
	vector <int> digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

	do 
	{
		
	} while (next_permutation(smm.begin(), smm.end()));



	system("PAUSE");
	return 0;
}


Don't give me the fish, teach me how to fish. I don't want codes. I want to know where to start.
Jan 31, 2016 at 3:39pm
Have you tried associative array for this?
Something like this ?
smm['S'] = 9
Jan 31, 2016 at 3:44pm
How can you set a char to a number?

int smm['S'] = 9

char smm['S'] = 9

Those won't work..
Jan 31, 2016 at 3:49pm
Jan 31, 2016 at 5:57pm
You don't need a map, just create an array that can hold all characters:
int letterToDigit[256];
For maximum portability you should use numeric_limits for the size:
1
2
#include <limits>
int letterToDigit[std::numeric_limits<char>::max()+1];


When necessary, assign digits to the letters. Here's a simple example:
1
2
3
4
    int digit=0;
    for (int ch : "SENDMORY") {
        letterToDigit[ch] = digit++;
    }


Now getting to the meat of the problem.

To go through all permutations of digits, you can star with a string of the digits and permute them:
1
2
3
4
    string digits = "0123456789";
    do {
        ...
    } while (std::next_permutation(digits.begin(), digits.end()));


With each permutation you could assign digits to the letterToDigit array:
1
2
3
4
5
6
7
void setLettersToDigits(const string &lettersInPuzzle, const string &digits)
{
    size_t i=0;
    for (size_t ch : lettersInPuzzle) {
        letterToDigit[ch] = digits[i++] - '0';
    }
}


You also need a function that will take a word and convert it to a number:
1
2
3
4
5
6
7
8
int wordToNum(const string &str)
{
    int result = 0;
    for (size_t ch : str) {
        result = result * 10 + letterToDigit[ch];
    }
    return result;
}


With these pieces, putting together a full solution is fairly easy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <limits>
#include <algorithm>
#include <string>

using std::numeric_limits;
using std::string;
using std::cout;

int letterToDigit[std::numeric_limits<char>::max()+1];


void setLettersToDigits(const string &lettersInPuzzle, const string &digits)
{
    size_t i=0;
    for (size_t ch : lettersInPuzzle) {
        letterToDigit[ch] = digits[i++] - '0';
    }
}


int wordToNum(const string &str)
{
    int result = 0;
    for (size_t ch : str) {
        result = result * 10 + letterToDigit[ch];
    }
    return result;
}


bool checkSum(const string &addend1, const string &addend2, const string &sum)
{
    int a1 = wordToNum(addend1);
    int a2 = wordToNum(addend2);
    int s = wordToNum(sum);
    // cout << a1 << " + " << a2 << " = " << s << "?\n";
    return a1 + a2 == s;
}

int
main()
{
    string lettersInPuzzle = "SENDMORY";
    string addend1 = "SEND";
    string addend2 = "MORE";
    string sum = "MONEY";
    string digits = "0123456789";
    bool found = false;
    do {
        setLettersToDigits(lettersInPuzzle, digits);
        if (checkSum(addend1, addend2, sum)) {
            cout << wordToNum(addend1) << " + "
                 << wordToNum(addend2) << " = "
                 << wordToNum(sum) << '\n';
            found = true;
        }
    } while (std::next_permutation(digits.begin(), digits.end()));
    if (!found) {
        cout << "No solution found\n";
    }
    return !found;              // return 0 for success, 1 for failure
}

2817 + 368 = 3185
2817 + 368 = 3185
2819 + 368 = 3187
2819 + 368 = 3187
3712 + 467 = 4179
3712 + 467 = 4179
3719 + 457 = 4176
3719 + 457 = 4176
3821 + 468 = 4289
3821 + 468 = 4289
3829 + 458 = 4287
3829 + 458 = 4287
5731 + 647 = 6378
5731 + 647 = 6378
5732 + 647 = 6379
5732 + 647 = 6379
5849 + 638 = 6487
5849 + 638 = 6487
6415 + 734 = 7149
6415 + 734 = 7149
6419 + 724 = 7143
6419 + 724 = 7143
6524 + 735 = 7259
6524 + 735 = 7259
6851 + 738 = 7589
6851 + 738 = 7589
6853 + 728 = 7581
6853 + 728 = 7581
7316 + 823 = 8139
7316 + 823 = 8139
7429 + 814 = 8243
7429 + 814 = 8243
7531 + 825 = 8356
7531 + 825 = 8356
7534 + 825 = 8359
7534 + 825 = 8359
7539 + 815 = 8354
7539 + 815 = 8354
7643 + 826 = 8469
7643 + 826 = 8469
7649 + 816 = 8465
7649 + 816 = 8465
8324 + 913 = 9237
8324 + 913 = 9237
8432 + 914 = 9346
8432 + 914 = 9346
8542 + 915 = 9457
8542 + 915 = 9457
9567 + 1085 = 10652
9567 + 1085 = 10652

Notice that this prints out each solution twice. Can you figure out why? Also it takes my computer 1.6 seconds to get the solutions, but a human can find at least 1 solution in under an hour. Can you think of ways to speed this up?
Jan 31, 2016 at 8:14pm
Your question sounds sooo random lol
Feb 2, 2016 at 12:28pm
RUNNER PRO AGARIO, are you referring to my questions or the original post? I asked why my program prints out each solution twice because printing twice indicates a bug, or at least odd behavior. The fact that a person can solve this in less than an hour means that there must be an easier way to do it. Perhaps that can be coded.
Feb 2, 2016 at 11:47pm
@dhayden yes
Topic archived. No new replies allowed.