![]() |
|
#1
|
|||
|
|||
sudoku solverHi,
In order to practice using ncurses I wrote a little sudoku solver: CPP / C++ / C Code:
It can solve e.g. the following problem: Code:
Code:
however there still exists many sudoku problems for which there is only one solution but my solver cannot solve. Like: Code:
and using brute force solving is less elegant than using logical solving.. Any ideas how to improve the solving without brute force method? |
|
#2
|
|||
|
|||
Re: sudoku solverQuote:
Well, it won't even come close to compiling (at least not for me, and, possibly, with other C compilers), since all of the function prototype declarations have "incomplete element type" errors. So, for those playing at home, if you have problems getting it to compile, you could try a few changes along the following lines: CPP / C++ / C Code:
Quote:
By my count, this puzzle has exactly zero cells that can be filled by simple elimination or filling. Something over 40 trial-and-error attempts are required (I think). The simplest brute-force program that I could come up with (Just start at the top left and go to the bottom right, calling a solver function recursively by iterating through all legal values for unfilled cells) required 4,480,699 recursions for that puzzle. (It took a smidgen over one second on my modest Linux system). If you want to see some ideas, you might consider an "exact cover" approach. Here is an interesting forum: Sudoku Programmers Forum Go to short C-solver with source (exact-cover-algorithm) A program derived from code there solved that problem in something like four milliseconds real time (User time only goes down to a measurement precision of 1 millisecond, and that is what it showed.) It also verified that the solution is unique. For "puzzles" with more than one solution, it can find them all if you want. (Although by most people's definitions, I think, in order to call it Sudoku, it must have a unique solution.) One reason I like that forum: Lots of good ideas. I learned a lot (and still had a lot to learn when my all-too-evanescent fancy drifted on to other things). Two reasons I like the particular piece of code of the first post in that thread: 1. Precious little white space, indentation, etc. Whenever someone issues a challenge about my spending too much effort trying to make source code "pretty", I show them this. (The author was following a tradition among a certain group of above-average programmers who wanted to be able to get the whole program on one page.) 2. Whenever someone points out that "goto" is part of the language and that certain people are too strident in their criticism if frivolous or other gratuitous of goto's, I like to introduce a subtle bug in the middle of the code and ask them to debug it. Now, in defense of the program and programmer: They certainly don't need me to defend them, but I will make a comment. This is a complicated sequence of steps. Getting rid of goto statements won't necessarily make it less complicated or easier to understand. I invite any and all to try it. (No, I will not post my structured programming version of the exact cover solver derived from this. After all, I think that other people should not be deprived of that kind of fun.) It might soothe the sensibilities of the "goto commandos," but it's still pretty intricate. Sometimes people get mad when we can't explain a complicated sequence in "25 words or less," but that's the way it goes... Bottom line: If you look for information from experienced puzzle makers and puzzle solvers (get a book or look on the web), you may find lots of non-recursive, non-random-trial-and-error methods that might be someting to put in your program. Good Luck! Regards, Dave Footnote number 1: In this problem there is one board array and one matrix array. This is one of those places where I might consider use of global variables for these things, therefore eliminating problems of function definitions and eliminating the overhead of their parameters every time. Just a thought Footnote number 2: In a program like this, where I am likely to run it many, many (many) times during the course of development/debugging, I hate having to enter the puzzle interactively. I would always allow for a command line argument that would allow the puzzle to be read from a file. Just a thought. Footnote number 3: How much experience do you have in solving very hard Sudoku puzzles, like your second example, "by hand?" Have you tried X-wing? Swordfish? ... The forum for which I gave the link has a sticky titled "Solving Technique Index." See whether any of those might suggest reasonable additions to your program. There are, of course many other web sites with more-or-less useful solving methodologies. Just a thought. (Three thoughts in a row! No extra charge! Feel free to disagree/ignore. No hard feelings.) |
|
#3
|
|||
|
|||
Re: sudoku solverThanks Dave! That is very good site indeed. I have not spent much time solving sudokus by hand so it is plain to see that my technique is amateurish. But now I can try implementing some X-wing etc.
Thanks for the suggestions too.. not (yet) runned it many times but will be so as you said will need file input included. |
|
#4
|
|||
|
|||
Re: sudoku solverQuote:
I appreciate the effort and I admire the results. I just like the option of using a file input for something that I will use over and over. Besides the convenience of multiple runs with the same or slightly different data during development and debugging, I can also use the same input file with other implementations of various sudoku solvers for comparison purposes. Regards, Dave |
|
#5
|
|||
|
|||
Re: sudoku solverHi,
The project goes on and after meditating some time I desided to split the program into two parts. One is solver program which eats files and prints results to stdout. The other is ncurses interactive editor which also can launch the solver to solve the puzzle: sudokueditor.c: CPP / C++ / C Code:
Name of the solver program can be given as parameter or if omitted then assumes it is called "sudokusolver". The other part is then the puzzle solver... but there I haven't yet done much anything new.. anyway it takes filename as commandline parameter and attempts solving... (well the TODO list is quite long still ) (also the current ..finder_1 and ..finder_2 can be combined I think and it will become much shorter that way ) sudokusolver.c CPP / C++ / C Code:
|
|
#6
|
|||
|
|||
Re: sudoku solverJust thought I'd let you guys know that I compiled this (with the modifications as dave suggested) using pdcurses for win32 which I installed into my mingw setup last month but haven't really gotten to yet. (determined to conquer more msdn console api first)
It compiles and runs ok... pretty cool. So anyone running win32 can write & run in ncurses too. I did wonder about something though. For me the starting grid looks like this: Code:
...and does that pdcurses 0xfc output make sense? (maybe I should look at the code huh...) ++Howard; |
|
#7
|
|||
|
|||
Re: sudoku solverQuote:
I developed in debian and the initial empty table looks like: Code:
That '\xB7' is supposed to be shown as a centered dot glyph.. If I limited my strings to standard ASCII codes (0-127) it would be more likely that it shows 'correctly' in other environments. Source: http://invisible-island.net/ncurses/ncurses.faq.html From chapter "Line-drawing characters come out as x's and q's" forward explains some of the reasons why the characters may not show the way expected. I am a bit confused what would be the best solution though... One option is that I limit myself to use plain ASCII to ensure that it shows properly on other systems (what a pity). Other possibility is that I try to somehow write code that can adapt to the expected encoding... no clue yet how to do that, maybe someone can help me out with this ? |
|
#8
|
|||
|
|||
Re: sudoku solverYes plain ascii makes sense but 0xB7 is into the extended ascii set which will show different characters for different systems.
I think a value between 0x20 and 0x7e should show the same character on all systems. I guess the only thing centered though is the - or maybe a + or = or * . Not as nifty as a centered dot... oh well. I guess the another thing to do would be a slew of #ifdef's which seems overkill unless you feel need to spend time learning more about that... It's not a deal, I was just curious. It works well! Solved Wikipedia's example. Howard; |
Recent GIDBlog
US Elections and the ?Voter?s Responsibility? by crystalattice
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Sudoku - Lite version | MiZaRiZ | C++ Forum | 6 | 03-Mar-2007 07:40 |
| sudoku C++, need lots of help :S | 3shtar | C++ Forum | 3 | 06-Apr-2006 11:10 |
| sudoku help | kris5683 | C++ Forum | 2 | 18-Nov-2005 07:58 |
| sudoku | kris5683 | C++ Forum | 1 | 08-Nov-2005 09:48 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The