Having done a couple of these sums with letters substituted for digits recently I thought it would be fun to write a general solver for them.

The following code takes a straightforward right-to-left approach on the columns of the sum, recursively examining the possibilities for each column. There are three interfaces to it: _substituted_sum() is the core of the algorithm, but it assumes its arguments are nicely formed. substituted_sum() is a friendlier way to run the algorithm, it makes sure the arguments are valid and fills out sensible default values. SubstitutedSum() wraps the previous function as a class so you don’t have to remember the terms in sum itself, and provides some handy functions for reporting solutions.

Gratifyingly this solution runs in 139ms, nearly 10× faster than the previous solution.