diff --git a/examples/README.md b/examples/README.md index 39e3381..2dbd50d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,7 +7,7 @@ The ones marked with (clp) requires `clp` library of SWI-Prolog. * (clp) `coins/` * (clp) `draughts/` * `hanoi/` : Towers of Hanoi -* (clp) `sendmoremoney/` : if, SEND * MORE = MONEY, what is S, E, N, D, M, O, R, Y? -* (clp) `sudoku/` : Sudoku solver (Prolog code is contributed by Markus Triska) -* `create_term.py` : shows creating a Prolog term -* `register_foreign.py` : shows registering a foreign function +* (clp) `sendmoremoney/` : If, SEND * MORE = MONEY, what is S, E, N, D, M, O, R, Y? +* (clp) `sudoku/` : Moved to `pyswip.examples.sudoku` package +* `create_term.py` : Shows creating a Prolog term +* `register_foreign.py` : Shows registering a foreign function diff --git a/examples/sudoku/sudoku.pl b/examples/sudoku/sudoku.pl deleted file mode 100644 index d572c20..0000000 --- a/examples/sudoku/sudoku.pl +++ /dev/null @@ -1,26 +0,0 @@ - -% Prolog Sudoku Solver (C) 2007 Markus Triska (triska@gmx.at) -% Public domain code. - -:- use_module(library(bounds)). - -% Pss is a list of lists representing the game board. - -sudoku(Pss) :- - flatten(Pss, Ps), - Ps in 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). diff --git a/examples/sudoku/sudoku.py b/examples/sudoku/sudoku.py deleted file mode 100644 index 50cf5eb..0000000 --- a/examples/sudoku/sudoku.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- - -# pyswip -- Python SWI-Prolog bridge -# Copyright (c) 2007-2018 Yüce Tekol -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from pyswip.prolog import Prolog - - -_ = 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", relative_to=__file__) - 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__": - main() diff --git a/examples/sudoku/sudoku_daily.py b/examples/sudoku/sudoku_daily.py deleted file mode 100644 index 7d11915..0000000 --- a/examples/sudoku/sudoku_daily.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- - -# pyswip -- Python SWI-Prolog bridge -# Copyright (c) 2007-2018 Yüce Tekol -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -# Sudoku auto-solver. Get today's sudoku at http://www.sudoku.org.uk/daily.asp -# and solve it - -from html.parser import HTMLParser -import urllib.request as urllib_request - -from pyswip.prolog import Prolog - - -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_request.urlopen(url) - puzzle.feed(f.read().decode("latin-1")) - puzzle = puzzle.puzzle - return [puzzle[i * 9 : i * 9 + 9] for i in range(9)] - - -def solve(problem): - Prolog.consult("sudoku.pl", relative_to=__file__) - p = str(problem).replace("0", "_") - result = list(Prolog.query(f"Puzzle={p},sudoku(Puzzle)", maxresult=1)) - if result: - result = result[0] - return result["Puzzle"] - else: - return False - - -if __name__ == "__main__": - URL = "https://www.sudoku.org.uk/daily.asp" - - 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?]") diff --git a/src/pyswip/examples/sudoku.py b/src/pyswip/examples/sudoku.py index 92236a7..955b8dc 100644 --- a/src/pyswip/examples/sudoku.py +++ b/src/pyswip/examples/sudoku.py @@ -119,19 +119,19 @@ def prolog_source() -> str: def main(): puzzle = Matrix.from_text(""" -. 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 . -""") - print("-- PUZZLE --") +. . 5 . 7 . 2 6 8 +. . 4 . . 2 . . . +. . 1 . 9 . . . . +. 8 . . . . 1 . . +. 2 . 9 . . . 7 . +. . 6 . . . . 3 . +. . 2 . 4 . 7 . . +. . . 5 . . 9 . . +9 5 7 . 3 . . . . + """) + print("\n-- PUZZLE --") puzzle.pretty_print() - print(" -- SOLUTION --") + print("\n-- SOLUTION --") solution = solve(puzzle) if solution: solution.pretty_print()