port of PYSWIP package.

This commit is contained in:
Vítor Santos Costa
2010-06-01 00:33:32 +01:00
parent 0645040602
commit e94104306c
27 changed files with 2502 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
% Prolog Sudoku Solver (C) 2007 Markus Triska (triska@gmx.at)
% Public domain code.
:- use_module(library(clpfd)).
% Pss is a list of lists representing the game board.
sudoku(Pss) :-
flatten(Pss, Ps),
allin(Ps, 1..9),
maplist(all_different, Pss),
Pss = [R1,R2,R3,R4,R5,R6,R7,R8,R9],
columns(R1, R2, R3, R4, R5, R6, R7, R8, R9),
blocks(R1, R2, R3), blocks(R4, R5, R6), blocks(R7, R8, R9),
label(Ps).
columns([], [], [], [], [], [], [], [], []).
columns([A|As],[B|Bs],[C|Cs],[D|Ds],[E|Es],[F|Fs],[G|Gs],[H|Hs],[I|Is]) :-
all_different([A,B,C,D,E,F,G,H,I]),
columns(As, Bs, Cs, Ds, Es, Fs, Gs, Hs, Is).
blocks([], [], []).
blocks([X1,X2,X3|R1], [X4,X5,X6|R2], [X7,X8,X9|R3]) :-
all_different([X1,X2,X3,X4,X5,X6,X7,X8,X9]),
blocks(R1, R2, R3).
allin([],_).
allin([Pos|Board],D) :-
Pos in D,
allin(Board,D).

View File

@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from pyswip.prolog import Prolog
from pyswip.easy import *
_ = 0
puzzle1 = [
[_,6,_,1,_,4,_,5,_],
[_,_,8,3,_,5,6,_,_],
[2,_,_,_,_,_,_,_,1],
[8,_,_,4,_,7,_,_,6],
[_,_,6,_,_,_,3,_,_],
[7,_,_,9,_,1,_,_,4],
[5,_,_,_,_,_,_,_,2],
[_,_,7,2,_,6,9,_,_],
[_,4,_,5,_,8,_,7,_]
]
puzzle2 = [
[_,_,1,_,8,_,6,_,4],
[_,3,7,6,_,_,_,_,_],
[5,_,_,_,_,_,_,_,_],
[_,_,_,_,_,5,_,_,_],
[_,_,6,_,1,_,8,_,_],
[_,_,_,4,_,_,_,_,_],
[_,_,_,_,_,_,_,_,3],
[_,_,_,_,_,7,5,2,_],
[8,_,2,_,9,_,7,_,_]
]
def pretty_print(table):
print "".join(["/---", "----"*8, "\\"])
for row in table:
print "".join(["|", "|".join(" %s " % (i or " ") for i in row), "|"])
print "".join(["\\---", "----"*8, "/"])
def solve(problem):
prolog.consult("sudoku.pl")
p = str(problem).replace("0", "_")
result = list(prolog.query("L=%s,sudoku(L)" % p, maxresult=1))
if result:
result = result[0]
return result["L"]
else:
return False
def main():
puzzle = puzzle1
print "-- PUZZLE --"
pretty_print(puzzle)
print
print " -- SOLUTION --"
solution = solve(puzzle)
if solution:
pretty_print(solution)
else:
print "This puzzle has no solutions [is it valid?]"
if __name__ == "__main__":
prolog = Prolog()
main()

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
# Sudoku auto-solver. Get today's sudoku at http://www.sudoku.org.uk/daily.asp
# and solve it
import urllib
from HTMLParser import HTMLParser, HTMLParseError
from pyswip.prolog import Prolog
from pyswip.easy import *
URL = "http://www.sudoku.org.uk/daily.asp"
class DailySudokuPuzzle(HTMLParser):
def __init__(self):
self.puzzle = []
self.__in_td = False
HTMLParser.__init__(self)
def handle_starttag(self, tag, attrs):
if tag == "td":
for attr in attrs:
if attr[0] == "class" and attr[1] == "InnerTDone":
self.__in_td = True
break
elif tag == "input":
if self.__in_td:
self.puzzle.append(0)
def handle_endtag(self, tag):
if tag == "td":
self.__in_td = False
def handle_data(self, data):
if self.__in_td:
self.puzzle.append(int(data))
def pretty_print(table):
print "".join(["/---", "----"*8, "\\"])
for row in table:
print "".join(["|", "|".join(" %s " % (i or " ") for i in row), "|"])
print "".join(["\\---", "----"*8, "/"])
def get_daily_sudoku(url):
puzzle = DailySudokuPuzzle()
f = urllib.urlopen(url)
try:
puzzle.feed(f.read())
except HTMLParseError:
pass
puzzle = puzzle.puzzle
return [puzzle[i*9:i*9+9] for i in range(9)]
def solve(problem):
prolog.consult("sudoku.pl")
p = str(problem).replace("0", "_")
result = list(prolog.query("Puzzle=%s,sudoku(Puzzle)" % p, maxresult=1))
if result:
result = result[0]
return result["Puzzle"]
else:
return False
if __name__ == "__main__":
prolog = Prolog() # having this in `solve` bites! because of __del__
print "Getting puzzle from:", URL
puzzle = get_daily_sudoku(URL)
print "-- PUZZLE --"
pretty_print(puzzle)
print
print " -- SOLUTION --"
solution = solve(puzzle)
if solution:
pretty_print(solution)
else:
print "This puzzle has no solutions [is it valid?]"