Where I work we're still on .Net 2.0, but I'm somewhat familiar with the 3.0/3.5 stuff. I wanted to get some practice using linq/lambda expression in C# so I wrote a simple Sudoku solver using a lot of generic List<T>
and lambda expressions with the aggregate methods it provides.
In my solver, I have this at the top of the solver algorithm:
private Puzzle RecursiveSolve(Puzzle p, int idx)
{
// start with simple filter to narrow down recursive paths
// puzzle is still solved without this line, but it takes at least 20x longer
while( p.board.Any(cell => cell.FilterPossibles()) ); // while(); <- empty while loop is intentional
As you can probably tell, it's a simple recursive algorithm, but I did optimize it a bit to get the run time down to something reasonable (3.6s for the toughest puzzle I could find on google).
To understand the snippet, Puzzle.board
is a List<Cell>
, and Cell.FilterPossibles()
checks each cell's possible values against the values of other Cells in the same row, column, and 3x3 box to see if it can eliminate any. If it gets down to one possible it sets the value for the cell and returns true. Otherwise it returns false. So that while loop will run as long as at least one cell on the board changed (was solved) with the previous iteration.
What concerns me is that the while loop is empty. It amounts to a code smell and tells me I'm probably missing something. Is there a way I could write this as a statement, rather than a loop?
I actually have a whole bunch of questions as the result of this project: (Have I unknowingly implemented some interfaces I could tell the compiler about? Are my function choices generally appropriate? I have a lot of boolean methods to simplify the expressions: how could that be better? How could I better architect this to possible use immutable Puzzle/Cell objects?) But this is the one that's nagging at me the most right now.