export const solve = (puzzle) => {
const [left, right] = puzzle.split(' == ');
const words = left.split(' + ').concat(right);
const letters = [...new Set(puzzle.match(/[A-Z]/g))];
const firstLetters = new Set(words.filter(w => w.length > 1).map(w => w[0]));
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const mapping = {};
const backtrack = (index, used) => {
if (index === letters.length) {
return isValid(words, letters, mapping) ? { ...mapping } : null;
}
const letter = letters[index];
for (let d of digits) {
if (used.has(d)) continue;
if (d === 0 && firstLetters.has(letter)) continue;
mapping[letter] = d;
used.add(d);
const res = backtrack(index + 1, used);
if (res) return res;
used.delete(d);
}
return null;
};
return backtrack(0, new Set());
};
function isValid(words, letters, mapping) {
const nums = words.map(w => parseInt([...w].map(l => mapping[l]).join('')));
const sum = nums.slice(0, -1).reduce((a, b) => a + b, 0);
return sum === nums[nums.length - 1];
}