Skip to content

Commit 5b30e2b

Browse files
authored
Update 1307-verbal-arithmetic-puzzle.js
1 parent e8be0f5 commit 5b30e2b

File tree

1 file changed

+44
-46
lines changed

1 file changed

+44
-46
lines changed

1307-verbal-arithmetic-puzzle.js

+44-46
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,52 @@
44
* @return {boolean}
55
*/
66
const isSolvable = function (words, result) {
7-
const firstChars = new Set()
8-
9-
// this will hold the key as the character and multiple as the value
10-
const map = {}
11-
for (let i = 0; i < result.length; i++) {
12-
const char = result[i]
13-
if (!i) firstChars.add(char)
14-
if (!map.hasOwnProperty(char)) map[char] = 0
15-
map[char] -= 10 ** (result.length - i - 1)
16-
}
17-
for (let j = 0; j < words.length; j++) {
18-
const word = words[j]
19-
for (let i = 0; i < word.length; i++) {
20-
const char = word[i]
21-
if (!i) firstChars.add(char)
22-
if (!map.hasOwnProperty(char)) map[char] = 0
23-
map[char] += 10 ** (word.length - i - 1)
7+
const _isSolvable = (wordIndex, charIndex, wordsSum, resultSum, num) => {
8+
if (wordIndex >= words.length) {
9+
return wordsSum === resultSum
2410
}
25-
}
26-
27-
const positives = []
28-
const negatives = []
29-
Object.entries(map).forEach((entry) => {
30-
if (entry[1] < 0) negatives.push(entry)
31-
else positives.push(entry)
32-
})
33-
34-
const numsUsed = new Set()
35-
const backtrack = (val = 0) => {
36-
// if we have used all the characters and the value is 0 the input is solvable
37-
if (!positives.length && !negatives.length) return val === 0
38-
39-
// get the store that we are going to examine depending on the value
40-
const store =
41-
val > 0 || (val === 0 && negatives.length) ? negatives : positives
42-
if (store.length === 0) return false
43-
const entry = store.pop()
44-
const [char, multiple] = entry
45-
46-
// try every possible value watching out for the edge case that it was a first character
47-
for (let i = firstChars.has(char) ? 1 : 0; i < 10; i++) {
48-
if (numsUsed.has(i)) continue
49-
numsUsed.add(i)
50-
if (backtrack(i * multiple + val)) return true
51-
numsUsed.delete(i)
11+
const wordLen = words[wordIndex].length
12+
if (charIndex >= wordLen) {
13+
if (wordIndex === words.length - 1) {
14+
return _isSolvable(wordIndex + 1, 0, wordsSum, num, 0)
15+
}
16+
return _isSolvable(wordIndex + 1, 0, wordsSum + num, resultSum, 0)
17+
}
18+
const char = words[wordIndex][charIndex]
19+
if (map.get(char) !== undefined) {
20+
if (map.get(char) === 0 && num === 0 && charIndex >= 1) {
21+
return false
22+
}
23+
return _isSolvable(
24+
wordIndex,
25+
charIndex + 1,
26+
wordsSum,
27+
resultSum,
28+
num * 10 + map.get(char)
29+
)
30+
}
31+
for (let digit = 0; digit <= 9; digit++) {
32+
if (digit === 0 && num === 0 && wordLen > 1) continue
33+
if (map.get(digit) !== undefined) continue
34+
map.set(digit, char)
35+
map.set(char, digit)
36+
if (
37+
_isSolvable(
38+
wordIndex,
39+
charIndex + 1,
40+
wordsSum,
41+
resultSum,
42+
num * 10 + digit
43+
)
44+
) {
45+
return true
46+
}
47+
map.set(digit, undefined)
48+
map.set(char, undefined)
5249
}
53-
store.push(entry)
5450
return false
5551
}
56-
return backtrack()
52+
const map = new Map()
53+
words = [...words, result]
54+
return _isSolvable(0, 0, 0, 0, 0)
5755
}

0 commit comments

Comments
 (0)