Update 2011-02-09 Use version 14
Version 13 may be the fastest, but in transitioning from version 10→11
we lost the ability to solve the veryhard puzzle. Revisions 11-13 don't
solve it. The change is quite short:
@@ -87,8 +87,7 @@
passno += 1
for acell in [x for x in reduce(lambda a,b:a+b, the_puzzle)
- if x.type == 0 and len(x.possibles) == 2]:
- # For now try it only on cells having exactly 2 possibles
+ if x.type == 0]:
for aval in acell.possibles:
achange = cut_contradictory_possibles(acell, aval)
more_to_do += achange
Update 2010-03-28: This version is 60-90x as fast
I wouldn't care about the speed except that the previous version
took over 15 minutes to solve the puzzle of
http://www.bestkakuro.com/killer2.gif (click the figure at right to
see a larger image). Version 7 is what I had last week. Version 11
is probably the fastest. Here are some times for comparison; I ran each
version twice using time(1) and entered here the shorter of the two "user"
times:
| version#
| Athlon64 3000+, 1GHz Bogomips 2009.75 Python 2.6.2 Linux 2.6.28 (Ubuntu 9.04)
| Xeon 5150, 2.6GHz bogomips 5333.61 Python 2.4.3 Linux 2.6.18 (RHEL 5.4)
| Powerbook G4, 1.67GHz Python 2.3.5 Mac OS X 10.4 (Tiger)
|
| 7 (from last week) | 15m41.179s | 5m54.746s | 54m36.416s
|
| 8 (k2-8.py) | 14m45.403s | 4m54.429s | 45m45.055s
|
| 9 (k2-9.py) | 14m41.455s | 4m47.196s | 45m41.441s
|
| 10 (k2-10.py) | 1m55.443s | 0m53.560s | 5m58.529s
|
| 11 (k2-11.py) | 0m8.561s | 0m5.346s | 0m27.454s
|
| 12 (k2-12.py) | 0m10.241s | 0m7.735s | 0m32.570s
|
| 13 (k2-13.py) 2010-03-29 | 0m7.040s | 0m4.628s | 0m22.976s output
|
| 14 (k2-14.py) 2011-02-09 | ? | ? | 26sec
|
What do the versions do?
- version 8 implements this rule: Suppose we have two
cells which must be either 1 or 2. Then no other cell in that
sum can be either of those values. The same thing holds if there
are three cells which must be one of (1,2,3) -- no other cell can have
any of those values. As you can see, it helped nontrivially but
not spectacularly.
- version 9 changes the trace outputs a little (why did I bother?)
- version 10 was the first major improvement (about 7:1); when
setting up the list of possible permutations for each total (e.g.,
the 45 heading downward in the puzzle at right), only allow those
permutations whose first element is in the first
cell's list of possibles, and whose last element is in the
last cell's list of possibles.
- version 11 gives another 10:1 (or better) improvement over version 10
by screening the possible permutation against the possible values in
all the cells. This screening is done using a "compiled" lambda
(create a string that checks each component of the permutation vs a
constant list of the possibles of each cell in the sum).
- version 12 applies the change of version 11 to every pass, but not the
list of permutations while initially loading into the Total instance.
This is a little slower than version 11 (memory allocation overhead?).
- version 13 restores the screening to the "while initially loading"
phase. This is the fastest version so far.
- Version 14 again solves the veryhard puzzle.
Update 2010-03-21: Solves Vegard Hanssen's very hard puzzles
...and has prettier output. The old k2.py is here at
k2-Mar_19_2255.py, but it couldn't solve,
for example, puzzle
#345943 (marked "very hard", and it is).
The new k2.py can; it
has prettier HTML, too. See download section
for sources.
An example of the prettier html is at
veryhard.html, which was created like this:
./k2.py < veryhard-messeske.no-395943 > veryhard.html
Here's "very hard" puzzle #345943 solved:
|
| A
| B
| C
| D
| E
| F
| G
| H
|
|---|
| 0
|
|
|
|
|
|
|
|
|
| 1
|
|
|
|
|
| 8
| 2
|
|
| 2
|
|
|
| 1
| 4
| 9
| 5
|
|
| 3
|
|
| 3
| 2
| 6
|
| 3
| 1
|
| 4
|
|
| 9
| 3
| 8
|
| 4
| 2
|
| 5
|
| 9
| 6
|
| 9
| 8
| 1
|
|
| 6
|
| 7
| 5
|
| 5
| 9
| 7
|
|
| 7
|
|
| 8
| 3
| 7
| 6
|
|
|
| 8
|
|
| 7
| 1
|
|
|
|
|
Update 2010-03-19: HTML output
... as seen at
http://collinpark.blogspot.com/2010/03/last-kakuro-posting-for-while-i-promise.html !
New program: k2.py;
see download section for sources.
Run it as:
$ ./k2.py < sample-march7.txt > march7.html
Output looks like this:
|
| A
| B
| C
| D
| E
| F
| G
| H
| I
| J
| K
| L
| M
| N
|
|---|
| 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1
|
|
| 7
| 9
| 8
|
| 4
| 2
| 1
|
|
| 1
| 7
|
|
| 2
|
| 8
| 5
| 7
| 9
|
| 8
| 9
| 7
|
| 2
| 5
| 1
| 6
|
| 3
|
| 7
| 9
|
|
| 7
| 9
|
|
| 2
| 1
|
| 4
| 9
|
| 4
|
|
| 8
| 7
| 6
| 5
|
|
|
| 1
| 3
|
| 6
| 8
|
| 5
|
|
|
| 1
| 9
|
|
|
| 2
| 7
|
| 9
| 5
|
|
| 6
|
|
|
|
| 8
| 9
|
| 1
| 4
|
|
| 7
| 3
| 1
|
| 7
|
| 1
| 3
|
|
| 7
| 5
| 6
| 9
| 8
|
|
| 8
| 9
|
| 8
|
| 9
| 1
| 7
|
|
| 2
| 3
|
| 1
| 9
|
|
|
|
| 9
|
|
| 5
| 9
|
| 7
| 6
|
|
|
| 8
| 6
|
|
|
| 10
|
| 2
| 4
|
| 4
| 9
|
|
|
| 8
| 7
| 3
| 1
|
|
| 11
|
| 1
| 7
|
| 6
| 8
|
|
| 1
| 2
|
|
| 2
| 1
|
| 12
|
| 3
| 6
| 2
| 1
|
| 3
| 1
| 2
|
| 8
| 5
| 7
| 9
|
| 13
|
|
| 8
| 5
|
|
| 9
| 6
| 8
|
| 2
| 1
| 3
|
|
Files to accompany
Download
The program text is Copyright © 2010 Collin Park; see the source for details.
If your browser tries to execute the programs when you click on the link,
you can try using right-click (or ctrl-click on Mac OS) and "save as". You
may need to run Python explicitly if /usr/bin/python doesn't exist on your
computer. It's been run under Python 2.3.4 and Python 2.6.2.
What you need to download:
- Cell.py, the cell class;
- k2.py (or k2-11.py or...), the solver's "main" part,
which will give HTML output on stdout.
- graytotals.png for pretty HTML
- a sample puzzle or two, e.g., sample1.txt or
bestkiller2
Here's the text:
- 2010-03-28 update: 60-90x speedup, and intermediate stages...
- k1.py -- the main part of the solver
- k2.py prettier HTML and *does* solve Vegard Hanssen's veryhard puzzles -- at least the ones I tried
- graytotals.png needed for the prettier HTML
- k2-Mar_19_2255.py -- k1.py but with HTML output (doesn't solve Vegard Hanssen's puzzles)
- Cell.py -- Cell and Total classes needed by k1.py
Here are a few sample puzzles:
Here's an example of how to run the program.
$ ./k1.py < Hard_Kakuro_for_19.March.2010
k1.py: solve a kakuro puzzle from stdin
Copyright (C) 2010 Collin Park
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See <http://www.gnu.org/licenses/> for full license text.
The above is just so everyone knows that the program
is free for anyone to use under the GPL. There's probably a more
professional way to do this, like "No warranty; type 'show c' for copyright"
or something like that, but this isn't a professional project; I'm just playing.
A B C D E F G
+-----+-----+-----+-----+-----+-----+-----+
0|XXXXX|XXXXX|11\ |25\ |XXXXX|XXXXX|XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
1|XXXXX|27\ 6| ___ | ___ |20\ |12\ |13\ |
+-----+-----+-----+-----+-----+-----+-----+
2| \39| ___ | ___ | ___ | ___ | ___ | ___ |
+-----+-----+-----+-----+-----+-----+-----+
3|XXXXX| ___ | 7\30| ___ | ___ | ___ | ___ |
+-----+-----+-----+-----+-----+-----+-----+
4| \11| ___ | ___ | ___ | ___ | 6\ | ___ |
+-----+-----+-----+-----+-----+-----+-----+
5| \21| ___ | ___ | ___ | ___ | 5 | ___ |
+-----+-----+-----+-----+-----+-----+-----+
6|XXXXX|XXXXX|XXXXX| \ 4| 3 | 1 |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
The solver stops after executing
steps #1-#6 as described here. As you can see in this rather hard puzzle, those steps filled in
three whole cells, leaving 23 (if I counted correctly) still open. Below is
some information I used in trying to decide what to do next.
Lines starting with "%%%" give the list of possible values for the named
cell; lines starting with ">>>" give the list of possible combinations for the
named total.
%%% 1C [2, 4, 5]
%%% 1D [1, 2, 4, 5]
%%% 2B [5, 6, 7, 8, 9]
%%% 2C [4, 5, 6, 7, 9]
%%% 2D [4, 5, 6, 7, 8, 9]
%%% 2E [4, 5, 6, 7, 8, 9]
%%% 2F [4, 5, 7, 8, 9]
%%% 2G [4, 6, 7]
%%% 3B [3, 5, 6, 7, 8, 9]
%%% 3D [6, 7, 8, 9]
%%% 3E [6, 7, 8, 9]
%%% 3F [7, 8, 9]
%%% 3G [6, 7]
%%% 4B [3, 5]
%%% 4C [1, 2, 3, 5]
%%% 4D [1, 2, 3, 5]
%%% 4E [1, 2, 5]
%%% 4G [1, 2, 3, 4, 6, 7]
%%% 5B [3, 6]
%%% 5C [1, 2, 3, 4, 6]
%%% 5D [1, 2, 3, 4, 6]
%%% 5E [1, 2, 4, 6]
%%% 5G [1, 2, 3, 4, 6]
>>> 0C down [(5, 6), (4, 7), (2, 9)]
>>> 0D down [(3, 4, 5, 6, 7), (2, 4, 5, 6, 8), (2, 3, 5, 7, 8), (1, 4, 5, 7, 8), (1, 3, 6, 7, 8), (2, 3, 5, 6, 9), (1, 4, 5, 6, 9), (2, 3, 4, 7, 9), (1, 3, 5, 7, 9), (1, 2, 6, 7, 9), (1, 3, 4, 8, 9), (1, 2, 5, 8, 9)]
>>> 1B across [(2, 4), (1, 5)]
>>> 1B down [(5, 6, 7, 9), (3, 7, 8, 9)]
>>> 1E down [(2, 3, 4, 5, 6), (1, 3, 4, 5, 7), (1, 2, 3, 6, 8), (1, 2, 3, 5, 9)]
>>> 1F down [(5, 7), (4, 8), (3, 9)]
>>> 1G down [(1, 2, 4, 6), (1, 2, 3, 7)]
>>> 2A across [(4, 5, 6, 7, 8, 9)]
>>> 3C across [(6, 7, 8, 9)]
>>> 3C down [(3, 4), (2, 5), (1, 6)]
>>> 4A across [(1, 2, 3, 5)]
>>> 5A across [(1, 2, 3, 4, 5, 6)]
After printing the intermediate results above, the program
proceeds to finish the job. So far it's been successful.
A B C D E F G
+-----+-----+-----+-----+-----+-----+-----+
0|XXXXX|XXXXX|11\ |25\ |XXXXX|XXXXX|XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
1|XXXXX|27\ 6| 2 | 4 |20\ |12\ |13\ |
+-----+-----+-----+-----+-----+-----+-----+
2| \39| 7 | 9 | 8 | 6 | 5 | 4 |
+-----+-----+-----+-----+-----+-----+-----+
3|XXXXX| 9 | 7\30| 9 | 8 | 7 | 6 |
+-----+-----+-----+-----+-----+-----+-----+
4| \11| 5 | 3 | 1 | 2 | 6\ | 1 |
+-----+-----+-----+-----+-----+-----+-----+
5| \21| 6 | 4 | 3 | 1 | 5 | 2 |
+-----+-----+-----+-----+-----+-----+-----+
6|XXXXX|XXXXX|XXXXX| \ 4| 3 | 1 |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
$
Here's what happens when you feed it an "easy" puzzle:
$ ./k1.py < easy.19mar2010
k1.py: solve a kakuro puzzle from stdin
Copyright (C) 2010 Collin Park
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
See for full license text.
A B C D E F G
+-----+-----+-----+-----+-----+-----+-----+
0|XXXXX|XXXXX|XXXXX|XXXXX|10\ |17\ |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
1|XXXXX|XXXXX| 3\12| 1 | 2 | 9 |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
2| \ 3| 2 | 1 |10\ 9| 1 | 8 |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
3|XXXXX| \ 6| 2 | 1 | 3 |17\ |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
4|XXXXX|XXXXX| 3\15| 2 | 4 | 9 |XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
5|XXXXX| \ 5| 2 | 3 | \ 9| 8 | 1 |
+-----+-----+-----+-----+-----+-----+-----+
6|XXXXX| \ 7| 1 | 4 | 2 |XXXXX|XXXXX|
+-----+-----+-----+-----+-----+-----+-----+
$
Just running steps #1-6 solved that one.