VOOZH about

URL: https://www.geeksforgeeks.org/dsa/solving-cryptarithmetic-puzzles/

⇱ Solving Cryptarithmetic Puzzles - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Solving Cryptarithmetic Puzzles

Last Updated : 23 Jul, 2025

Newspapers and magazines often have crypt-arithmetic puzzles of the form:

SEND
+ MORE
--------
MONEY
--------

Where the goal is to assign each letter a digit from 0 to 9 so that the arithmetic works out correctly. The rules are that all occurrences of a letter must be assigned the same digit, and no digit can be assigned to more than one letter. You are given three strings a, b, and sum, representing the crypt-arithmetic puzzles, your task is to solve the puzzle and print the three strings representing its solution.

Note: If no possible solution exists, print "-1". If multiple solutions exist, print any.

Example:

Input: a = "send", b = "more", sum = "money"
Output: 7531 0825 08356
Explanation: 7531 + 0825 = 08356, and all the unique characters are assigned unique digits. 2817, 0368, 03185, is also the possible answer.

Input: a = "s", b = "p", sum = "f"
Output: 2 1 3

[Expected Approach] - Using Backtracking - O(10 ^ n ) Time and O(n) Space

The idea is to firstly create a list of all the characters that need assigning to pass to Solve. Now use backtracking to assign all possible digits to the characters.

  • If all characters are assigned, return true if puzzle is solved, false otherwise
  • Otherwise, consider the first unassigned character
  • for (every possible choice among the digits not in use)
  • If all digits have been tried and nothing worked, return false to trigger backtracking

Output
2 1 3 

Time Complexity: O(10 ^ n), where n is number of unique characters. For each character we have 10 digits, thus the time complexity is 10 multiplied n times = O(10 ^ n).
Auxiliary Space: O(n), considering the recursive call stack.

[Optimized Approach] - O(10! / (10 - n)!) Time and O(n) Space

The idea is to assign the characters starting from the one's place and moving to the left, at each stage, we can verify the correctness of what we have so far before we continue onwards.

Below is the step-by-step approach:

  • Start by examining the rightmost digit of the topmost row, with a carry of 0
  • If we are beyond the leftmost digit of the puzzle, return true if no carry, false otherwise
  • If we are currently trying to assign a char in one of the addends If char already assigned, just recur on the row beneath this one, adding value into the sum If not assigned, then
    • for (every possible choice among the digits not in use) make that choice and then on row beneath this one, if successful, return true if !successful, unmake assignment and try another digit
    • return false if no assignment worked to trigger backtracking
  • Else if trying to assign a char in the sum
  • If char assigned & matches correct, recur on next column to the left with carry, if success return true,
  • If char assigned & doesn't match, return false
  • If char unassigned & correct digit already used, return false
  • If char unassigned & correct digit unused, assign it and recur on next column to left with carry, if success return true
  • return false to trigger backtracking

Output
2817 0368 03185 

Time Complexity: O(10! / (10 - n)!), where n is the number of unique characters. Let k be the number of unique characters (k ≤ 10 in typical puzzles) and n be the length of the strings (digits in the numbers). The assignDigits function tries all possible assignments for k characters, which in the worst-case is on the order of O(P(10, k)) = O(10!/(10–k)!) assignments.
Auxiliary Space: O(n), considering the recursive call stack.


Comment
Article Tags:
Article Tags: