Here is one possible design for coding up a solver for these types of problems.
That design would be to write down all the rules of arithmetic
in terms of carry digits, in terms of odd and even and so on.
Now, that seems like a challenging task.
There's a lot of complexity involved in understanding all the rules about arithmetic.
Even if we figured out everything about addition, there's also subtraction
and multiplication and other operators.
So what we really want is a short cut that'll allow us to eliminate this complexity.
Let's go back to the back of the envelope
and see if we can figure out a shortcut.
One possibility would be to try all possibilities.
There are 10 digits.
All combinations of digits--all permutations of the digits, rather--
would be only 10 factorial,
which I happen to know is about 3 million.
That's not so many.
It seems like it's feasible to try all the possibilities.
It's not going to be super quick.
We would rather have this be thousands rather than millions
because there seems to be a fair amount of work in substituting in all the letters with digits.
But we can expect to be able to try all millions,
not within a second, but within about a minute or so.
Now we have an approved design, which is we represent our formula as a string,
and we'll use official Python notation here with the double equal sign.
Then we fill in with all permutations of the 10 digits for each of the letter,
and if there's fewer letters, we have to account for that.
For example, we might substitute a 1 for the Os,
and a 2 for the Ds, and a 3 for the Es, and a 4 for the Vs, and a 5 for the Ns.
Otherwise just copy the equation.
Then evaluate that and check if that's equal to True.
If it is, then we have a solution.
If it's not, we'll go back and we'll try another combination--
maybe 1, 3, 3, and so on.
We'll keep on going through until we find some permutation that works.
That's the design.
Now, let's take an inventory of all the concepts we're going to need.
First we have equations.
There's two types of those--the original and the filled-in.
The original has letters. The filled in has digits.
Letters and digits are concepts we have to deal with.
The assignment of a letter to a digit or set of those is also a concept we have to deal with.
I think that's pretty much it.
Maybe one more concept is evaluation or validation
that the filled in equation is an accurate one.
Now let's come up with some choices to represent each of these concepts.
The original equation can be a string.
The filled-in equation can also be a string.
The letters will be single character strings like D.
The digits will also be single character strings--like 3.
The assignment of letters to digits will be some sort of mapping or a table
that consists of this type of mapping that says D would be replaced by 3 and so on.
It turns out that there is a facility built into Python that's part of strings
called the translate function.
We can call the str.translate method in order to enact that type of assignment or substitution.
Then for the evaluation, there is a function called "eval" in Python,
which takes a string and evaluates it as an expression.
You may not be that familiar with these last two items, so let's go over them.
Eval is pretty simple.
If we asked for eval of the string "2 + 2," then that would give us a value 4.
If we asked for eval of the string "2 + 2 == 3," Python would evaluate that
using it's normal rules and tell us that that's equal to False.