The generation algorithm works, but it could be faster. Things to try:
The solver helper (invoked many times by digOut) re-calculates the possible values for each cell. I could probably build this list up as digOut progresses, saving a lot of redundant work.
If a dug-out cell in digOut has a single possible value, I don't need to check for unique solutions.
I could change the heuristic for picking a cell to populate in the solver; right now I'm using the cell with the fewest number of possible values. Alternatively, I could try the cell that affects the most neighbors.
I could use a priority queue for selecting the next cell to populate in the solver. It might not speed things up that much, but it could be fun.
The generator should probably backtrack when it thinks it can't progress, rather than starting over entirely.
The generation algorithm works, but it could be faster. Things to try: