-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay13.cpp
More file actions
154 lines (130 loc) · 4 KB
/
Day13.cpp
File metadata and controls
154 lines (130 loc) · 4 KB
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
This problem was asked by Google.
A cryptarithmetic puzzle is a mathematical game where the digits of some numbers are represented by letters. Each letter represents a unique digit.
For example, a puzzle of the form:
SEND
+ MORE
--------
MONEY
may have the solution:
{'S': 9, 'E': 5, 'N': 6, 'D': 7, 'M': 1, 'O', 0, 'R': 8, 'Y': 2}
Given a three-word puzzle like the one above, create an algorithm that finds a solution.
*/
#include <bits/stdc++.h>
using namespace std;
// Function to check if the puzzle is solvable with the given character assignments
bool solvePuzzleHelper(const string &a, const string &b, const string &sum,
int pos, int carry, unordered_map<char, int> &charToDigit, bitset<10> &usedDigits)
{
// Base case: if we have processed all digits
if (pos >= sum.size())
{
return carry == 0;
}
// Calculate sum at current position
int sumVal = carry;
if (pos < a.size() && charToDigit.count(a[a.size() - 1 - pos]))
{
sumVal += charToDigit[a[a.size() - 1 - pos]];
}
if (pos < b.size() && charToDigit.count(b[b.size() - 1 - pos]))
{
sumVal += charToDigit[b[b.size() - 1 - pos]];
}
char sumChar = sum[sum.size() - 1 - pos];
// If sumChar is already assigned, check if it matches
if (charToDigit.count(sumChar))
{
if (charToDigit[sumChar] != sumVal % 10)
{
return false;
}
return solvePuzzleHelper(a, b, sum, pos + 1,
sumVal / 10, charToDigit, usedDigits);
}
// Ensure digit is not already used
if (usedDigits[sumVal % 10])
{
return false;
}
// Assign the digit to sumChar
charToDigit[sumChar] = sumVal % 10;
usedDigits[sumVal % 10] = 1;
// Recur for next position
if (solvePuzzleHelper(a, b, sum, pos + 1,
sumVal / 10, charToDigit, usedDigits))
{
return true;
}
// Backtrack if assignment fails
charToDigit.erase(sumChar);
usedDigits[sumVal % 10] = 0;
return false;
}
// Function to assign digits to unique characters and check if assignment is valid
bool assignDigits(const string &a, const string &b, const string &sum, int index,
const string &order, unordered_map<char, int> &charToDigit, bitset<10> &usedDigits)
{
// Base case: If all characters are assigned
if (index == order.size())
{
return solvePuzzleHelper(a, b, sum, 0, 0, charToDigit, usedDigits);
}
char ch = order[index];
// Try assigning each digit to the character
for (int digit = 0; digit < 10; digit++)
{
if (!usedDigits[digit])
{
charToDigit[ch] = digit;
usedDigits[digit] = 1;
if (assignDigits(a, b, sum, index + 1, order, charToDigit, usedDigits))
{
return true;
}
// Backtrack if unsuccessful
usedDigits[digit] = 0;
charToDigit.erase(ch);
}
}
return false;
}
// Main function to solve Cryptarithmetic puzzle
vector<string> solvePuzzle(string a, string b, string sum)
{
unordered_map<char, int> charToDigit;
bitset<10> usedDigits;
unordered_set<char> uniqueChars;
string order;
// Identify unique characters in the input strings
for (char ch : a + b + sum)
{
if (uniqueChars.insert(ch).second)
{
order += ch;
}
}
// Assign digits to characters and check validity
if (assignDigits(a, b, sum, 0, order, charToDigit, usedDigits))
{
string x, y, z;
for (char ch : a)
x += '0' + charToDigit[ch];
for (char ch : b)
y += '0' + charToDigit[ch];
for (char ch : sum)
z += '0' + charToDigit[ch];
return {x, y, z};
}
return {"-1"};
}
int main()
{
string a = "SEND", b = "MORE", sum = "MONEY";
vector<string> ans = solvePuzzle(a, b, sum);
for (const auto &res : ans)
{
cout << res << " ";
}
return 0;
}