K, I've been Sudoking all day so for the last couple of hours, I decided I would give my brain a change of focus and start work on my own solver. Here's the first part of the story.
I chose C as it's quick and easy to knock up code in.
- Write a function to validate any partially filled grid (check rows 1-9 for multiple digits, check cols...check blocks)
- write a recursive function "solve()" that scans thruough the grid looking for a 0, then tries numbers 1-9 in that spot, if a valid digit is found, it calls solve again recursivly, if not and all 9 digits have been tried, it gives up on this iteration and returns.
The firsat run on a random "Hard" puzzle from Waynes program took about 260 seconds - I now the algorithm was AWFULLY inefficient but that time just sucked!
1st improvement - the checkgrid routine was rewritten to hold the checked digits in a single integer, using bit arithmetic to check each row, column and grid - that halved the time, but still no good.
2nd improvement - I realised that in the solve function, rather than checking the entire grid whenever I placed a number, I just needed to check the row/column and block that the cell was in. Whilst making this improvement, I also used a couple of arrays to get me the starting cell for any block, and the block number for any cell (assuming 9x9 grids) - eliminating a lot of calculations to work ouitwhihc block any cell was in and vice-versa.
That took me from 130 seconds down to a mere 0.2 seconds! (witjh 39,000 recursions into the solve function)
Interestingly, given a totally empty grid, it only takes 0.02 seconds and 392 recursions to find a solution (which is:
123 456 789
456 789 123
789 123 456
214 365 897
365 897 214
897 214 365
531 642 978
632 978 531
978 531 642
I can think of lots of improvements (obvious one being to do a simple candidate scan and only use valid candidates - which starts me on the road to a logic solver)
Not bad results though for such a simple minded (120 lines) C program and an hour or two tinkering!