I'm just now coding a Sudoku solver, in BASIC. This is the info I used
(after much work because I'd never messed with Sudoku before), to code
my program.

It's not nearly as small as the one posted above, but it uses a virtual
"odometer" at the end for any trial and error that's needed - so I
enjoy it. This is the whole info and description:

This is my standard sized Sudoku puzzles algo/program summary.

Box refers to any of the smaller box of 9 squares which are contained
within the larger puzzle.

Peer's are other squares which must be scanned. It might be other
squares on the same row in one case, or other squares in the same
column, or the squares within the same box.

Unit refers to either a row, column, or box, depending on context.

== Start ==

Working the "Possibles":

1. Assign all possible values to an array of possibles to allow record
keeping of them, for every square. I use a 2D array for the possibles,
and a 2D array also, for the puzzle board. The puzzle board is oriented
by row and col, and the possibles array is oriented by square number
(11 to 99), and possible value (1 to 9). Row * 10 + column = square
number.

2. Remove all possibles for each square which conflict with permanent
values in each of the squares' peer's, in each unit (row, column, and
box)

3. Upgrade squares with only one value (a solo), into a permanent
value. If any solo's are upgraded, return to #2 and repeat it and #3,
again.

Repeat steps 2 and 3 until no more changes are made in the possibles.

Working the "Must Be's":

4. Scan each unit, one at a time, for each value. If the unit has a
value located in just one square, then upgrade that possible into a
permanent value.

This is an example: (from today's newspaper Sudoku)
Code:

  1   2   3     4    5    6    7   8      9
=============================================
1347  2  1357  145  1345  45   9  4567 145678


Square #9 on this row has an 8 as a possible, and it's the only square
on the entire row that CAN be an eight. So it get's
updated to 8, permanently. It is a "must be".

Don't forget the column's and box unit's "must be's"!

If you have made changes, return to #2, and repeat steps 2 - 4.

The Rule of Pairs:

There are two rules for pairs, outside and inside. Both are "must be"
logic, applied to pairs. An example of outside:
Code:

 1  2  3   4    5    6   7   8      9
========================================
13  2  13 145  1345  45  9  4567  145678


In the row above, square #1 and #3 have a matching pair of possibles.
By definition of the game, these two squares can ONLY be either a 1 or
a 3, and nothing else. We can't know yet which value will be correct
for either square, but it MUST collectively use up the 1 and 3 value
for the entire row.

So all values of 1 or 3 OUTSIDE the #1 or #3 square, can be eliminated!
Square 4 becomes simply "45", etc.

My program implements this both as a string of char's, and as just
integer values in the possibles array. Both may lead to glazing over of
one's eye's, and remembering the pleasantries to be found in daydreams
& dozing.

The INSIDE rule of pairs removes some possibles from the pairs,
themselves:
Code:

 1    2   3     4      5    6    7   8      9
==============================================
1347  2  1347   45    456   45   9  4567  145678



Square 1 and 3 have matching pairs of possibles "1347", and the "13"
part of their possibles, in unique to those two squares, in this unit.
Which means the 4 & 7 values can be removed from the possibles for
square #1, and square #3. We don't know (again!), which value will be
correct, but it MUST be ONLY a 1 or a 3 for them both.

The examples puzzles I've gather so far, don't have a good example of
the Inside Rule of Pairs, so my program does not include this logic.

The Pairs rules also apply to larger groups of possibles: triples,
quads, etc.

For any changes, you need to loop back to step #2, and repeat all steps
until no more changes are found. This is the great "propagator" in
Sudoku, and it happens fast and often. You don't need to repeat the
steps after every change, but you need to repeat all the steps above
your own,
for any steps listed above which make a change in the possibles.
There's no need to keep any index or record of what changes you've
made, etc. Just give it access to the possibles array and let it run.

Trial and Error Substitution:

Tough Sudoku puzzles can't be solved by mere logical inferences.
(Although they do a huge amount of the work in eliminating possibles.)
Intelligent trial and error will be needed.

I don't use this (yet), but I certainly believe it's the best way to
handle T & E. I call it the "Magic Touch":
Code:

 1    2   3     4    5    6   7   8      9
=============================================
1347  2  1357  145  1345  45  9  4567  145678


Imagine this unit is being looked over for a t&e. Would it be
"magical"? Yep! Square #6 has only two possibles: 4 and 5.

Permanent values such as square #7 will give us nothing here, but
square #6 has a 50% chance of being right.

Save the current board position/possibles arrays, and make square 6
into a 4. Send it back to Step #2 and above, letting the values found,
propagate throughout the board. It's rather amazing how it does it!

Now see if the puzzle is solved. No? Then restore the possibles and
problem arrays, and try the value 5 in square 6, and send it to Step
#2, etc.

You may need to try several combinations of these "magical" squares for
before you find the correct solution, but just keep track of where you
are in the t&e searching, and remember that one of them MUST be right.
(or the puzzle has no solution or your program has an error).

In my program I used an "odometer" approach to this phase. Imagine the
squares of the puzzle all stretched out in a straight line, horizontal.
Each square as a "wheel" with a guessed (or actual) value. Squares with
a permanent values are "jumped over" in any incrementing of values.

Showing this for one row:
Code:

 1   2   3    4    5    6   7   8     9
=========================================
 13  2   37  145  345  456  9   67    78


A small while loop through the possibles arrays for each square finds
the next number for each square to be tried. If it fails when tested
for the
current row, another increment is made to the smallest, rightmost
"wheel", and repeats.

My "odometer" would try:

1 2 3 1 3 4 9 6 7 'initial low values
1 2 3 1 3 4 9 6 8 'increment right-most wheel (the driver)
1 2 3 1 3 4 9 7 7 'increment wheel #8, reset driver wheel
1 2 3 1 3 4 9 7 8 'increment driver wheel
1 2 3 1 3 5 9 6 7 'update sqr #6, reset #7 and driver wheel

As you can see, this is all "stupid", because wheel #4 is a repeat of
#1, an obvious non-solution. So I dutifully wrote a function to supply
only valid possible numbers to the odometer. But the smart way, was
slower than the "stupid" way. Now I let the virtual odometer make it's
own errors, and quickly increment the driver "wheel" value, again.

Eventually finding:

1 2 3 4 5 6 9 7 8 as the first solution

If the smallest wheel increments through all it's possibles, then it
moves the incrementor over to the wheel to it's left, and increments
that wheel to the next possible value. Then it returns to the rightmost
wheel, which has been set for it's smallest possible value.

When a solution is found for all the rows requested, it may stop, or it
can be set to continue throughout the entire search space (which is
until the incrementor control reaches the "zero" column (I use only the
1 - 9 array subscripts in this program). In the latter case, it will
find all the possible solutions to the puzzle.

Imagine an odometer of a car, attached directly to an incredibly fast
high-speed, motor (the cpu). This is simply the virtual representation
of that odometer, at high speed.

If you want it to handle multiple rows at a time, it starts with the
highest row in the puzzle / possibles array, and works it's way to the
lower rows, (toward the higher rows on the screen), by recursively
calling itself with a lower row number. It's important to have the
columns and boxes tests done ONLY if the preceeding tests have been
successful. You have to maximize an odometer's code efficiency.

Is it fast? Yes, but ONLY because a HUGE number of possibles have been
removed by the above steps. Is it efficient? No. "Magical Touch" is
hugely efficient. The "odometer" logic, is just for fun (but it is
plenty fast enough, generally). It all depends on how many possibles
remain, the efficiency of your code in implementing it, and your
hardware. On my laptop with a 950Mhz P3, it's fast enough.

If the puzzle doesn't need the "odometer", (trial & error), then it's
solved in less than a second. Much less than a second if you limit the
amount of info that's printed to the screen. Easy puzzles are done in
"zero" time, less than 6/100's of a second, for Windows.

If the "odometer" is used, it all depends how many rows you want it to
solve for, and how many possibles remain. The search always begins at
the lowest possible set of values. Should the answer be found at the
extreme high end of the search space,

it will use a lot more computation, and a little more time. It's very
important that the implementation of the odometer, be streamlined in
it's operation. Any wasted code in the inner-most loops, are going to
have a big negative impact.

Adak

P.S.
My program is dedicated to Mike Frayer. An exasperating person, but a
true friend.
Mike died from a very rapid leukemia, as a young man, having never been
sick a day in his life
with anything more than a flu/cold. Within 24 hours of first seeing a
doctor for his "flu", he
was brain-dead at Stanford Hospital from the leukemia!

If you wanted to talk about computers, current events, programming, or
computer games, Mike was your guy.
Whatever he lacked in knowledge, he more than made up for with his
infectious brand of boundless enthusiasm for these topics.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Algorithm Geeks" group.
To post to this group, send email to algogeeks@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/algogeeks
-~----------~----~----~----~------~----~------~--~---

Reply via email to