JP / EN
Insights / Algorithm

The Mathematics and Implementation of Make 10

Why is "Proof by Exhaustion" the most elegant solution?
A firmware engineer's algorithmic approach to a classic number puzzle.

1. The License Plate Puzzle

Do you ever find yourself staring at the license plate of the car in front of you while driving? Especially when the four digits are all distinct (no repeating numbers), a certain process automatically starts running in my brain.

"Use these four numbers and the four arithmetic operations (+, -, *, /) to make 10."

This is the so-called "Make 10" (or Ten Puzzle). I've been good at this since I was a child. The moment I see a car at a traffic light, the solution pops into my head almost reflexively. For example, if I see "1, 3, 7, 9", I immediately formulate $(7+3) \times (9-1) \div 8$ ... or more simply $(9-7) \times (1+3) + \dots$.

As a rule of thumb, if you choose "four distinct digits from 1 to 9", you will almost never encounter an unsolvable combination. But can we prove this mathematically? If you try to prove the proposition "If you choose four different numbers, you can always make 10" using beautiful algebraic formulas with variables $x$ and $y$, you will hit an unexpected wall.

2. The Defeat of Algebra: Operators Cannot Be Variables

Usually, when we think of mathematical proofs, we think of algebraic manipulation. However, the difficulty of Make 10 lies in the fact that not only the numbers ($a, b, c, d$) but also the "operators ($+, -, \times, \div$)" and the "calculation order (parentheses)" themselves are variables.

Standard equations like $f(x) = 10$ cannot fully express the "structural changes" caused by combinations of operators. Approaches from analysis (calculus, etc.), which deal with continuous numerical changes, are powerless against such discrete structures.

3. The Engineer's Solution: Proof by Exhaustion

This is where the algorithmic approach—our forte as engineers—comes into play. If it cannot be generalized by a formula, we simply need to "verify every possible pattern (Proof by exhaustion)."

Does that sound inelegant? No, this is the most powerful and definitive proof in discrete mathematics.

  • Number combinations: Choosing 4 distinct digits from 1 to 9 (${}_9C_4$) = 126 patterns

There are only 126 patterns. Even if we apply all patterns of operators and orders (tree structures like Reverse Polish Notation) to each combination, the computational load is negligible for a computer.

This is the same philosophy as "State Transition Testing" in firmware development. Unlike analog circuits with infinite inputs, digital systems (discrete systems) have finite states, so "total coverage" is the ultimate quality assurance (proof).

4. Verification Code (C Language)

The proof is in the pudding. I actually wrote a solver in C to verify all 126 combinations. The following code uses recursive search (DFS) to reduce the numbers and explore all possible operation patterns.

/**
 * Make 10 Solver & Prover
 * Author: Dr. WataWata (M.A.L.)
 * Description: Verifies that all combinations of 4 distinct digits (1-9) can make 10.
 */
#include <stdio.h>
#include <math.h>
#include <stdbool.h>

#define TARGET 10.0
#define EPSILON 1e-6

// Recursive function to perform operations (Depth First Search)
bool can_make_10(double nums[], int n) {
    // [Base Case] When only one number remains
    if (n == 1) {
        // Success if the difference from the target (10) is within the error margin
        return fabs(nums[0] - TARGET) < EPSILON;
    }

    // Pick two numbers from the list, operate, create a new list, and recurse
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i == j) continue; // Cannot pick the same element

            double next_nums[4];
            int m = 0;
            
            // Copy the remaining numbers to the list for the next step
            for (int k = 0; k < n; k++) {
                if (k != i && k != j) next_nums[m++] = nums[k];
            }

            double a = nums[i];
            double b = nums[j];

            // Try 4 operations, add result to list, and recurse
            
            // Addition
            next_nums[m] = a + b;
            if (can_make_10(next_nums, n - 1)) return true;

            // Subtraction
            next_nums[m] = a - b;
            if (can_make_10(next_nums, n - 1)) return true;

            // Multiplication
            next_nums[m] = a * b;
            if (can_make_10(next_nums, n - 1)) return true;

            // Division (Guard against division by zero)
            if (fabs(b) > EPSILON) {
                next_nums[m] = a / b;
                if (can_make_10(next_nums, n - 1)) return true;
            }
        }
    }
    return false;
}

int main() {
    int count = 0;
    int success_count = 0;
    
    printf("Exploring all combinations of 4 distinct digits from 1-9...\n");

    // Choose 4 distinct digits from 1 to 9 (9C4)
    for (int i = 1; i <= 9; i++) {
        for (int j = i + 1; j <= 9; j++) {
            for (int k = j + 1; k <= 9; k++) {
                for (int l = k + 1; l <= 9; l++) {
                    
                    count++;
                    double initial_set[4] = {(double)i, (double)j, (double)k, (double)l};
                    
                    if (can_make_10(initial_set, 4)) {
                        success_count++;
                    } else {
                        printf("[FAIL] %d, %d, %d, %d -> Impossible\n", i, j, k, l);
                    }
                }
            }
        }
    }

    printf("------------------------------------------------\n");
    printf("Total combinations tested: %d\n", count);
    printf("Solvable combinations:     %d\n", success_count);
    
    if (count == success_count) {
        printf("Result: PROVED. All distinct combinations can make 10.\n");
    } else {
        printf("Result: DISPROVED.\n");
    }

    return 0;
}

Running this program yields Result: PROVED. This mathematically (computationally) proves that solutions exist for all 126 combinations of "4 distinct digits from 1 to 9".

5. Dr.WataWata Insight

Just because it cannot be solved by a "formula" does not mean it is not "mathematical." In a finite discrete structure, exhaustive search using a computer (algorithm) is a legitimate mathematical proof.

The reason I can instantly make "10" when I see a license plate is not because I have a high-performance CPU in my brain, but perhaps because my intuition is supported by the peace of mind that "the existence of a solution is mathematically guaranteed."

Next time the car in front of you has "four different numbers," try to solve it with confidence. The answer is definitely there.