again
parent
d8e31ed03f
commit
91e0399ed6
@ -0,0 +1,60 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# PyCharm / Intellij
|
||||
.idea/
|
@ -0,0 +1,21 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
|
||||
# command to install dependencies
|
||||
install:
|
||||
- "pip install -qq flake8"
|
||||
- "pip install coveralls --quiet"
|
||||
- "pip install ."
|
||||
|
||||
# command to run tests
|
||||
script:
|
||||
- nosetests -s -v --with-coverage --cover-package=constraint
|
||||
- flake8 --ignore E501 constraint examples tests
|
||||
|
||||
after_success:
|
||||
- coveralls
|
@ -0,0 +1,23 @@
|
||||
Copyright (c) 2005-2014 - Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -0,0 +1,159 @@
|
||||
|Build Status| |Code Health| |Code Coverage|
|
||||
|
||||
python-constraint
|
||||
=================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
The Python constraint module offers solvers for `Constraint Satisfaction Problems (CSPs) <https://en.wikipedia.org/wiki/Constraint_satisfaction_problem>`_ over finite domains in simple and pure Python. CSP is class of problems which may be represented in terms of variables (a, b, ...), domains (a in [1, 2, 3], ...), and constraints (a < b, ...).
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Basics
|
||||
~~~~~~
|
||||
|
||||
This interactive Python session demonstrates the module basic operation:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from constraint import *
|
||||
>>> problem = Problem()
|
||||
>>> problem.addVariable("a", [1,2,3])
|
||||
>>> problem.addVariable("b", [4,5,6])
|
||||
>>> problem.getSolutions()
|
||||
[{'a': 3, 'b': 6}, {'a': 3, 'b': 5}, {'a': 3, 'b': 4},
|
||||
{'a': 2, 'b': 6}, {'a': 2, 'b': 5}, {'a': 2, 'b': 4},
|
||||
{'a': 1, 'b': 6}, {'a': 1, 'b': 5}, {'a': 1, 'b': 4}]
|
||||
|
||||
>>> problem.addConstraint(lambda a, b: a*2 == b,
|
||||
("a", "b"))
|
||||
>>> problem.getSolutions()
|
||||
[{'a': 3, 'b': 6}, {'a': 2, 'b': 4}]
|
||||
|
||||
>>> problem = Problem()
|
||||
>>> problem.addVariables(["a", "b"], [1, 2, 3])
|
||||
>>> problem.addConstraint(AllDifferentConstraint())
|
||||
>>> problem.getSolutions()
|
||||
[{'a': 3, 'b': 2}, {'a': 3, 'b': 1}, {'a': 2, 'b': 3},
|
||||
{'a': 2, 'b': 1}, {'a': 1, 'b': 2}, {'a': 1, 'b': 3}]
|
||||
|
||||
Rooks problem
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The following example solves the classical Eight Rooks problem:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> problem = Problem()
|
||||
>>> numpieces = 8
|
||||
>>> cols = range(numpieces)
|
||||
>>> rows = range(numpieces)
|
||||
>>> problem.addVariables(cols, rows)
|
||||
>>> for col1 in cols:
|
||||
... for col2 in cols:
|
||||
... if col1 < col2:
|
||||
... problem.addConstraint(lambda row1, row2: row1 != row2,
|
||||
... (col1, col2))
|
||||
>>> solutions = problem.getSolutions()
|
||||
>>> solutions
|
||||
>>> solutions
|
||||
[{0: 7, 1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 1, 7: 0},
|
||||
{0: 7, 1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 0, 7: 1},
|
||||
{0: 7, 1: 6, 2: 5, 3: 4, 4: 3, 5: 1, 6: 2, 7: 0},
|
||||
{0: 7, 1: 6, 2: 5, 3: 4, 4: 3, 5: 1, 6: 0, 7: 2},
|
||||
...
|
||||
{0: 7, 1: 5, 2: 3, 3: 6, 4: 2, 5: 1, 6: 4, 7: 0},
|
||||
{0: 7, 1: 5, 2: 3, 3: 6, 4: 1, 5: 2, 6: 0, 7: 4},
|
||||
{0: 7, 1: 5, 2: 3, 3: 6, 4: 1, 5: 2, 6: 4, 7: 0},
|
||||
{0: 7, 1: 5, 2: 3, 3: 6, 4: 1, 5: 4, 6: 2, 7: 0},
|
||||
{0: 7, 1: 5, 2: 3, 3: 6, 4: 1, 5: 4, 6: 0, 7: 2},
|
||||
...]
|
||||
|
||||
|
||||
Magic squares
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
This example solves a 4x4 magic square:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> problem = Problem()
|
||||
>>> problem.addVariables(range(0, 16), range(1, 16 + 1))
|
||||
>>> problem.addConstraint(AllDifferentConstraint(), range(0, 16))
|
||||
>>> problem.addConstraint(ExactSumConstraint(34), [0, 5, 10, 15])
|
||||
>>> problem.addConstraint(ExactSumConstraint(34), [3, 6, 9, 12])
|
||||
>>> for row in range(4):
|
||||
... problem.addConstraint(ExactSumConstraint(34),
|
||||
[row * 4 + i for i in range(4)])
|
||||
>>> for col in range(4):
|
||||
... problem.addConstraint(ExactSumConstraint(34),
|
||||
[col + 4 * i for i in range(4)])
|
||||
>>> solutions = problem.getSolutions()
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
The following solvers are available:
|
||||
|
||||
- Backtracking solver
|
||||
- Recursive backtracking solver
|
||||
- Minimum conflicts solver
|
||||
|
||||
|
||||
.. role:: python(code)
|
||||
:language: python
|
||||
|
||||
Predefined constraint types currently available:
|
||||
|
||||
- :python:`FunctionConstraint`
|
||||
- :python:`AllDifferentConstraint`
|
||||
- :python:`AllEqualConstraint`
|
||||
- :python:`ExactSumConstraint`
|
||||
- :python:`MaxSumConstraint`
|
||||
- :python:`MinSumConstraint`
|
||||
- :python:`InSetConstraint`
|
||||
- :python:`NotInSetConstraint`
|
||||
- :python:`SomeInSetConstraint`
|
||||
- :python:`SomeNotInSetConstraint`
|
||||
|
||||
API documentation
|
||||
-----------------
|
||||
Documentation for the module is available at: http://labix.org/doc/constraint/
|
||||
|
||||
Download and install
|
||||
--------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ pip install python-constraint
|
||||
|
||||
Roadmap
|
||||
-------
|
||||
|
||||
This GitHub organization and repository is a global effort to help to
|
||||
maintain python-constraint which was written by Gustavo Niemeyer
|
||||
and originaly located at https://labix.org/python-constraint
|
||||
|
||||
- Create some unit tests - DONE
|
||||
- Enable continuous integration - DONE
|
||||
- Port to Python 3 (Python 2 being also supported) - DONE
|
||||
- Respect Style Guide for Python Code (PEP8) - DONE
|
||||
- Improve code coverage writting more unit tests - ToDo
|
||||
- Move doc to Sphinx or MkDocs - https://readthedocs.org/ - ToDo
|
||||
|
||||
Contact
|
||||
-------
|
||||
- `Gustavo Niemeyer <https://github.com/niemeyer/>`_ <gustavo@niemeyer.net>
|
||||
- `Sébastien Celles <https://github.com/scls19fr/>`_ <s.celles@gmail.com>
|
||||
|
||||
But it's probably better to `open an issue <https://github.com/python-constraint/python-constraint/issues>`_.
|
||||
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.org/python-constraint/python-constraint.svg?branch=master
|
||||
:target: https://travis-ci.org/python-constraint/python-constraint
|
||||
.. |Code Health| image:: https://landscape.io/github/python-constraint/python-constraint/master/landscape.svg?style=flat
|
||||
:target: https://landscape.io/github/python-constraint/python-constraint/master
|
||||
:alt: Code Health
|
||||
.. |Code Coverage| image:: https://coveralls.io/repos/github/python-constraint/python-constraint/badge.svg
|
||||
:target: https://coveralls.io/github/python-constraint/python-constraint
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
PY3 = (sys.version_info[0] >= 3)
|
||||
|
||||
if PY3:
|
||||
string_types = str
|
||||
xrange = range
|
||||
else:
|
||||
string_types = basestring # noqa
|
||||
xrange = xrange
|
@ -0,0 +1,8 @@
|
||||
__author__ = "Gustavo Niemeyer"
|
||||
__copyright__ = "Copyright (c) 2005-2014 - Gustavo Niemeyer <gustavo@niemeyer.net>"
|
||||
__credits__ = ["Sebastien Celles"]
|
||||
__license__ = ""
|
||||
__version__ = "1.3.1"
|
||||
__email__ = "gustavo@niemeyer.net"
|
||||
__status__ = "Development"
|
||||
__url__ = 'https://github.com/python-constraint/python-constraint'
|
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# What's the minimum value for:
|
||||
#
|
||||
# ABC
|
||||
# -------
|
||||
# A+B+C
|
||||
#
|
||||
# From http://www.umassd.edu/mathcontest/abc.cfm
|
||||
#
|
||||
from constraint import Problem
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables("abc", range(1, 10))
|
||||
problem.getSolutions()
|
||||
minvalue = 999 / (9 * 3)
|
||||
minsolution = {}
|
||||
for solution in problem.getSolutions():
|
||||
a = solution["a"]
|
||||
b = solution["b"]
|
||||
c = solution["c"]
|
||||
value = (a * 100 + b * 10 + c) / (a + b + c)
|
||||
if value < minvalue:
|
||||
minsolution = solution
|
||||
return minvalue, minsolution
|
||||
|
||||
|
||||
def main():
|
||||
minvalue, minsolution = solve()
|
||||
print(minvalue)
|
||||
print(minsolution)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# 100 coins must sum to $5.00
|
||||
#
|
||||
# That's kind of a country-specific problem, since depending on the
|
||||
# country there are different values for coins. Here is presented
|
||||
# the solution for a given set.
|
||||
#
|
||||
from constraint import Problem, ExactSumConstraint
|
||||
import sys
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
total = 5.00
|
||||
variables = ("0.01", "0.05", "0.10", "0.50", "1.00")
|
||||
values = [float(x) for x in variables]
|
||||
for variable, value in zip(variables, values):
|
||||
problem.addVariable(variable, range(int(total / value)))
|
||||
problem.addConstraint(ExactSumConstraint(total, values), variables)
|
||||
problem.addConstraint(ExactSumConstraint(100))
|
||||
solutions = problem.getSolutionIter()
|
||||
return solutions, variables
|
||||
|
||||
|
||||
def main():
|
||||
solutions, variables = solve()
|
||||
for i, solution in enumerate(solutions):
|
||||
sys.stdout.write("%03d -> " % (i + 1))
|
||||
for variable in variables:
|
||||
sys.stdout.write("%s:%d " % (variable, solution[variable]))
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/python
|
||||
from constraint import Problem, AllDifferentConstraint
|
||||
import random
|
||||
import sys
|
||||
|
||||
MINLEN = 3
|
||||
|
||||
|
||||
def main(puzzle, lines):
|
||||
puzzle = puzzle.rstrip().splitlines()
|
||||
while puzzle and not puzzle[0]:
|
||||
del puzzle[0]
|
||||
|
||||
# Extract horizontal words
|
||||
horizontal = []
|
||||
word = []
|
||||
predefined = {}
|
||||
for row in range(len(puzzle)):
|
||||
for col in range(len(puzzle[row])):
|
||||
char = puzzle[row][col]
|
||||
if not char.isspace():
|
||||
word.append((row, col))
|
||||
if char != "#":
|
||||
predefined[row, col] = char
|
||||
elif word:
|
||||
if len(word) > MINLEN:
|
||||
horizontal.append(word[:])
|
||||
del word[:]
|
||||
if word:
|
||||
if len(word) > MINLEN:
|
||||
horizontal.append(word[:])
|
||||
del word[:]
|
||||
|
||||
# Extract vertical words
|
||||
vertical = []
|
||||
validcol = True
|
||||
col = 0
|
||||
while validcol:
|
||||
validcol = False
|
||||
for row in range(len(puzzle)):
|
||||
if col >= len(puzzle[row]):
|
||||
if word:
|
||||
if len(word) > MINLEN:
|
||||
vertical.append(word[:])
|
||||
del word[:]
|
||||
else:
|
||||
validcol = True
|
||||
char = puzzle[row][col]
|
||||
if not char.isspace():
|
||||
word.append((row, col))
|
||||
if char != "#":
|
||||
predefined[row, col] = char
|
||||
elif word:
|
||||
if len(word) > MINLEN:
|
||||
vertical.append(word[:])
|
||||
del word[:]
|
||||
if word:
|
||||
if len(word) > MINLEN:
|
||||
vertical.append(word[:])
|
||||
del word[:]
|
||||
col += 1
|
||||
|
||||
# hnames = ["h%d" % i for i in range(len(horizontal))]
|
||||
# vnames = ["v%d" % i for i in range(len(vertical))]
|
||||
|
||||
# problem = Problem(MinConflictsSolver())
|
||||
problem = Problem()
|
||||
|
||||
for hi, hword in enumerate(horizontal):
|
||||
for vi, vword in enumerate(vertical):
|
||||
for hchar in hword:
|
||||
if hchar in vword:
|
||||
hci = hword.index(hchar)
|
||||
vci = vword.index(hchar)
|
||||
problem.addConstraint(lambda hw, vw, hci=hci, vci=vci:
|
||||
hw[hci] == vw[vci],
|
||||
("h%d" % hi, "v%d" % vi))
|
||||
|
||||
for char, letter in predefined.items():
|
||||
for hi, hword in enumerate(horizontal):
|
||||
if char in hword:
|
||||
hci = hword.index(char)
|
||||
problem.addConstraint(lambda hw, hci=hci, letter=letter:
|
||||
hw[hci] == letter, ("h%d" % hi,))
|
||||
for vi, vword in enumerate(vertical):
|
||||
if char in vword:
|
||||
vci = vword.index(char)
|
||||
problem.addConstraint(lambda vw, vci=vci, letter=letter:
|
||||
vw[vci] == letter, ("v%d" % vi,))
|
||||
|
||||
wordsbylen = {}
|
||||
for hword in horizontal:
|
||||
wordsbylen[len(hword)] = []
|
||||
for vword in vertical:
|
||||
wordsbylen[len(vword)] = []
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
ll = len(line)
|
||||
if ll in wordsbylen:
|
||||
wordsbylen[ll].append(line.upper())
|
||||
|
||||
for hi, hword in enumerate(horizontal):
|
||||
words = wordsbylen[len(hword)]
|
||||
random.shuffle(words)
|
||||
problem.addVariable("h%d" % hi, words)
|
||||
for vi, vword in enumerate(vertical):
|
||||
words = wordsbylen[len(vword)]
|
||||
random.shuffle(words)
|
||||
problem.addVariable("v%d" % vi, words)
|
||||
|
||||
problem.addConstraint(AllDifferentConstraint())
|
||||
|
||||
solution = problem.getSolution()
|
||||
if not solution:
|
||||
print("No solution found!")
|
||||
|
||||
maxcol = 0
|
||||
maxrow = 0
|
||||
for hword in horizontal:
|
||||
for row, col in hword:
|
||||
if row > maxrow:
|
||||
maxrow = row
|
||||
if col > maxcol:
|
||||
maxcol = col
|
||||
for vword in vertical:
|
||||
for row, col in vword:
|
||||
if row > maxrow:
|
||||
maxrow = row
|
||||
if col > maxcol:
|
||||
maxcol = col
|
||||
|
||||
matrix = []
|
||||
for row in range(maxrow + 1):
|
||||
matrix.append([" "] * (maxcol + 1))
|
||||
|
||||
for variable in solution:
|
||||
if variable[0] == "v":
|
||||
word = vertical[int(variable[1:])]
|
||||
else:
|
||||
word = horizontal[int(variable[1:])]
|
||||
for (row, col), char in zip(word, solution[variable]):
|
||||
matrix[row][col] = char
|
||||
|
||||
for row in range(maxrow + 1):
|
||||
for col in range(maxcol + 1):
|
||||
sys.stdout.write(matrix[row][col])
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
sys.exit("Usage: crosswords.py <maskfile> <wordsfile>")
|
||||
main(open(sys.argv[1]).read(), open(sys.argv[2]))
|
@ -0,0 +1,27 @@
|
||||
|
||||
# ######## #
|
||||
# # # # #
|
||||
######## # #
|
||||
# # # # #
|
||||
# # ########
|
||||
# # # # # #
|
||||
######## # #
|
||||
# # # # # #
|
||||
# # #
|
||||
######## # #
|
||||
# # # # #
|
||||
# ########
|
||||
# # # # #
|
||||
# # ########
|
||||
# # # # # #
|
||||
# # ########
|
||||
# # # #
|
||||
######## # #
|
||||
# # # # # #
|
||||
# # # # # #
|
||||
######## # #
|
||||
# # # #
|
||||
# ########
|
||||
# # # #
|
||||
######## # #
|
||||
|
@ -0,0 +1,19 @@
|
||||
|
||||
#
|
||||
#########
|
||||
# # #
|
||||
# # ######
|
||||
# # #
|
||||
# # # #
|
||||
# # # #
|
||||
######## #
|
||||
# # #
|
||||
# # #
|
||||
#########
|
||||
# # #
|
||||
#########
|
||||
# # #
|
||||
# #
|
||||
#######
|
||||
#
|
||||
|
@ -0,0 +1,8 @@
|
||||
P
|
||||
Y
|
||||
####T####
|
||||
# H #
|
||||
# O #
|
||||
####N #
|
||||
# #
|
||||
#########
|
@ -0,0 +1,8 @@
|
||||
#
|
||||
#
|
||||
#########
|
||||
# #
|
||||
# # # #
|
||||
##### # #
|
||||
# # #
|
||||
#########
|
@ -0,0 +1,209 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# ALBERT EINSTEIN'S RIDDLE
|
||||
#
|
||||
# ARE YOU IN THE TOP 2% OF INTELLIGENT PEOPLE IN THE WORLD?
|
||||
# SOLVE THE RIDDLE AND FIND OUT.
|
||||
#
|
||||
# There are no tricks, just pure logic, so good luck and don't give up.
|
||||
#
|
||||
# 1. In a street there are five houses, painted five different colours.
|
||||
# 2. In each house lives a person of different nationality
|
||||
# 3. These five homeowners each drink a different kind of beverage, smoke
|
||||
# different brand of cigar and keep a different pet.
|
||||
#
|
||||
# THE QUESTION: WHO OWNS THE FISH?
|
||||
#
|
||||
# HINTS
|
||||
#
|
||||
# 1. The Brit lives in a red house.
|
||||
# 2. The Swede keeps dogs as pets.
|
||||
# 3. The Dane drinks tea.
|
||||
# 4. The Green house is on the left of the White house.
|
||||
# 5. The owner of the Green house drinks coffee.
|
||||
# 6. The person who smokes Pall Mall rears birds.
|
||||
# 7. The owner of the Yellow house smokes Dunhill.
|
||||
# 8. The man living in the centre house drinks milk.
|
||||
# 9. The Norwegian lives in the first house.
|
||||
# 10. The man who smokes Blends lives next to the one who keeps cats.
|
||||
# 11. The man who keeps horses lives next to the man who smokes Dunhill.
|
||||
# 12. The man who smokes Blue Master drinks beer.
|
||||
# 13. The German smokes Prince.
|
||||
# 14. The Norwegian lives next to the blue house.
|
||||
# 15. The man who smokes Blends has a neighbour who drinks water.
|
||||
#
|
||||
# ALBERT EINSTEIN WROTE THIS RIDDLE EARLY DURING THE 19th CENTURY. HE
|
||||
# SAID THAT 98% OF THE WORLD POPULATION WOULD NOT BE ABLE TO SOLVE IT.
|
||||
|
||||
from constraint import Problem, AllDifferentConstraint
|
||||
|
||||
# Check http://www.csc.fi/oppaat/f95/python/talot.py
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
for i in range(1, 6):
|
||||
problem.addVariable("color%d" % i,
|
||||
["red", "white", "green", "yellow", "blue"])
|
||||
problem.addVariable("nationality%d" % i,
|
||||
["brit", "swede", "dane", "norwegian", "german"])
|
||||
problem.addVariable("drink%d" % i,
|
||||
["tea", "coffee", "milk", "beer", "water"])
|
||||
problem.addVariable("smoke%d" % i,
|
||||
["pallmall", "dunhill", "blends",
|
||||
"bluemaster", "prince"])
|
||||
problem.addVariable("pet%d" % i,
|
||||
["dogs", "birds", "cats", "horses", "fish"])
|
||||
|
||||
problem.addConstraint(AllDifferentConstraint(),
|
||||
["color%d" % i for i in range(1, 6)])
|
||||
problem.addConstraint(AllDifferentConstraint(),
|
||||
["nationality%d" % i for i in range(1, 6)])
|
||||
problem.addConstraint(AllDifferentConstraint(),
|
||||
["drink%d" % i for i in range(1, 6)])
|
||||
problem.addConstraint(AllDifferentConstraint(),
|
||||
["smoke%d" % i for i in range(1, 6)])
|
||||
problem.addConstraint(AllDifferentConstraint(),
|
||||
["pet%d" % i for i in range(1, 6)])
|
||||
|
||||
for i in range(1, 6):
|
||||
|
||||
# Hint 1
|
||||
problem.addConstraint(lambda nationality, color:
|
||||
nationality != "brit" or color == "red",
|
||||
("nationality%d" % i, "color%d" % i))
|
||||
|
||||
# Hint 2
|
||||
problem.addConstraint(lambda nationality, pet:
|
||||
nationality != "swede" or pet == "dogs",
|
||||
("nationality%d" % i, "pet%d" % i))
|
||||
|
||||
# Hint 3
|
||||
problem.addConstraint(lambda nationality, drink:
|
||||
nationality != "dane" or drink == "tea",
|
||||
("nationality%d" % i, "drink%d" % i))
|
||||
|
||||
# Hint 4
|
||||
if i < 5:
|
||||
problem.addConstraint(lambda colora, colorb:
|
||||
colora != "green" or colorb == "white",
|
||||
("color%d" % i, "color%d" % (i + 1)))
|
||||
else:
|
||||
problem.addConstraint(lambda color: color != "green",
|
||||
("color%d" % i,))
|
||||
|
||||
# Hint 5
|
||||
problem.addConstraint(lambda color, drink:
|
||||
color != "green" or drink == "coffee",
|
||||
("color%d" % i, "drink%d" % i))
|
||||
|
||||
# Hint 6
|
||||
problem.addConstraint(lambda smoke, pet:
|
||||
smoke != "pallmall" or pet == "birds",
|
||||
("smoke%d" % i, "pet%d" % i))
|
||||
|
||||
# Hint 7
|
||||
problem.addConstraint(lambda color, smoke:
|
||||
color != "yellow" or smoke == "dunhill",
|
||||
("color%d" % i, "smoke%d" % i))
|
||||
|
||||
# Hint 8
|
||||
if i == 3:
|
||||
problem.addConstraint(lambda drink: drink == "milk",
|
||||
("drink%d" % i,))
|
||||
|
||||
# Hint 9
|
||||
if i == 1:
|
||||
problem.addConstraint(lambda nationality:
|
||||
nationality == "norwegian",
|
||||
("nationality%d" % i,))
|
||||
|
||||
# Hint 10
|
||||
if 1 < i < 5:
|
||||
problem.addConstraint(lambda smoke, peta, petb:
|
||||
smoke != "blends" or peta == "cats" or
|
||||
petb == "cats",
|
||||
("smoke%d" % i, "pet%d" % (i - 1),
|
||||
"pet%d" % (i + 1)))
|
||||
else:
|
||||
problem.addConstraint(lambda smoke, pet:
|
||||
smoke != "blends" or pet == "cats",
|
||||
("smoke%d" % i,
|
||||
"pet%d" % (i == 1 and 2 or 4)))
|
||||
|
||||
# Hint 11
|
||||
if 1 < i < 5:
|
||||
problem.addConstraint(lambda pet, smokea, smokeb:
|
||||
pet != "horses" or smokea == "dunhill" or
|
||||
smokeb == "dunhill",
|
||||
("pet%d" % i, "smoke%d" % (i - 1),
|
||||
"smoke%d" % (i + 1)))
|
||||
else:
|
||||
problem.addConstraint(lambda pet, smoke:
|
||||
pet != "horses" or smoke == "dunhill",
|
||||
("pet%d" % i,
|
||||
"smoke%d" % (i == 1 and 2 or 4)))
|
||||
|
||||
# Hint 12
|
||||
problem.addConstraint(lambda smoke, drink:
|
||||
smoke != "bluemaster" or drink == "beer",
|
||||
("smoke%d" % i, "drink%d" % i))
|
||||
|
||||
# Hint 13
|
||||
problem.addConstraint(lambda nationality, smoke:
|
||||
nationality != "german" or smoke == "prince",
|
||||
("nationality%d" % i, "smoke%d" % i))
|
||||
|
||||
# Hint 14
|
||||
if 1 < i < 5:
|
||||
problem.addConstraint(lambda nationality, colora, colorb:
|
||||
nationality != "norwegian" or
|
||||
colora == "blue" or colorb == "blue",
|
||||
("nationality%d" % i, "color%d" % (i - 1),
|
||||
"color%d" % (i + 1)))
|
||||
else:
|
||||
problem.addConstraint(lambda nationality, color:
|
||||
nationality != "norwegian" or
|
||||
color == "blue",
|
||||
("nationality%d" % i,
|
||||
"color%d" % (i == 1 and 2 or 4)))
|
||||
|
||||
# Hint 15
|
||||
if 1 < i < 5:
|
||||
problem.addConstraint(lambda smoke, drinka, drinkb:
|
||||
smoke != "blends" or
|
||||
drinka == "water" or drinkb == "water",
|
||||
("smoke%d" % i, "drink%d" % (i - 1),
|
||||
"drink%d" % (i + 1)))
|
||||
else:
|
||||
problem.addConstraint(lambda smoke, drink:
|
||||
smoke != "blends" or drink == "water",
|
||||
("smoke%d" % i,
|
||||
"drink%d" % (i == 1 and 2 or 4)))
|
||||
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def showSolution(solution):
|
||||
for i in range(1, 6):
|
||||
print("House %d" % i)
|
||||
print("--------")
|
||||
print("Nationality: %s" % solution["nationality%d" % i])
|
||||
print("Color: %s" % solution["color%d" % i])
|
||||
print("Drink: %s" % solution["drink%d" % i])
|
||||
print("Smoke: %s" % solution["smoke%d" % i])
|
||||
print("Pet: %s" % solution["pet%d" % i])
|
||||
print("")
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
print("Found %d solution(s)!" % len(solutions))
|
||||
print("")
|
||||
for solution in solutions:
|
||||
showSolution(solution)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# http://mathworld.wolfram.com/QueensProblem.html
|
||||
#
|
||||
from constraint import Problem
|
||||
import sys
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
size = 8
|
||||
cols = range(size)
|
||||
rows = range(size)
|
||||
problem.addVariables(cols, rows)
|
||||
for col1 in cols:
|
||||
for col2 in cols:
|
||||
if col1 < col2:
|
||||
problem.addConstraint(lambda row1, row2, col1=col1, col2=col2:
|
||||
abs(row1 - row2) != abs(col1 - col2) and
|
||||
row1 != row2, (col1, col2))
|
||||
solutions = problem.getSolutions()
|
||||
return solutions, size
|
||||
|
||||
|
||||
def showSolution(solution, size):
|
||||
sys.stdout.write(" %s \n" % ("-" * ((size * 4) - 1)))
|
||||
for i in range(size):
|
||||
sys.stdout.write(" |")
|
||||
for j in range(size):
|
||||
if solution[j] == i:
|
||||
sys.stdout.write(" %d |" % j)
|
||||
else:
|
||||
sys.stdout.write(" |")
|
||||
sys.stdout.write("\n")
|
||||
if i != size - 1:
|
||||
sys.stdout.write(" |%s|\n" % ("-" * ((size * 4) - 1)))
|
||||
sys.stdout.write(" %s \n" % ("-" * ((size * 4) - 1)))
|
||||
|
||||
|
||||
def main(show=False):
|
||||
solutions, size = solve()
|
||||
print("Found %d solution(s)!" % len(solutions))
|
||||
if show:
|
||||
for solution in solutions:
|
||||
showSolution(solution, size)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
show = False
|
||||
if len(sys.argv) == 2 and sys.argv[1] == "-s":
|
||||
show = True
|
||||
elif len(sys.argv) != 1:
|
||||
sys.exit("Usage: queens.py [-s]")
|
||||
main(show)
|
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# http://mathworld.wolfram.com/RooksProblem.html
|
||||
#
|
||||
from constraint import Problem
|
||||
import sys
|
||||
|
||||
|
||||
def factorial(x):
|
||||
return x == 1 or factorial(x - 1) * x
|
||||
|
||||
|
||||
def solve(size):
|
||||
problem = Problem()
|
||||
cols = range(size)
|
||||
rows = range(size)
|
||||
problem.addVariables(cols, rows)
|
||||
for col1 in cols:
|
||||
for col2 in cols:
|
||||
if col1 < col2:
|
||||
problem.addConstraint(lambda row1, row2: row1 != row2,
|
||||
(col1, col2))
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main(show=False):
|
||||
size = 8
|
||||
solutions = solve(size)
|
||||
print("Found %d solution(s)!" % len(solutions))
|
||||
if show:
|
||||
for solution in solutions:
|
||||
showSolution(solution, size)
|
||||
|
||||
|
||||
def showSolution(solution, size):
|
||||
sys.stdout.write(" %s \n" % ("-" * ((size * 4) - 1)))
|
||||
for i in range(size):
|
||||
sys.stdout.write(" |")
|
||||
for j in range(size):
|
||||
if solution[j] == i:
|
||||
sys.stdout.write(" %d |" % j)
|
||||
else:
|
||||
sys.stdout.write(" |")
|
||||
sys.stdout.write("\n")
|
||||
if i != size - 1:
|
||||
sys.stdout.write(" |%s|\n" % ("-" * ((size * 4) - 1)))
|
||||
sys.stdout.write(" %s \n" % ("-" * ((size * 4) - 1)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
show = False
|
||||
if len(sys.argv) == 2 and sys.argv[1] == "-s":
|
||||
show = True
|
||||
elif len(sys.argv) != 1:
|
||||
sys.exit("Usage: rooks.py [-s]")
|
||||
main(show)
|
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# http://home.chello.no/~dudley/
|
||||
#
|
||||
from constraint import Problem, AllDifferentConstraint, SomeInSetConstraint
|
||||
import sys
|
||||
|
||||
STUDENTDESKS = [[0, 1, 0, 0, 0, 0],
|
||||
[0, 2, 3, 4, 5, 6],
|
||||
[0, 7, 8, 9, 10, 0],
|
||||
[0, 11, 12, 13, 14, 0],
|
||||
[15, 16, 17, 18, 19, 0],
|
||||
[0, 0, 0, 0, 20, 0]]
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"])
|
||||
problem.addConstraint(SomeInSetConstraint(["A"], 4, True))
|
||||
problem.addConstraint(SomeInSetConstraint(["B"], 4, True))
|
||||
problem.addConstraint(SomeInSetConstraint(["C"], 4, True))
|
||||
problem.addConstraint(SomeInSetConstraint(["D"], 4, True))
|
||||
problem.addConstraint(SomeInSetConstraint(["E"], 4, True))
|
||||
for row in range(len(STUDENTDESKS) - 1):
|
||||
for col in range(len(STUDENTDESKS[row]) - 1):
|
||||
lst = [STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1],
|
||||
STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1]]
|
||||
lst = [x for x in lst if x]
|
||||
problem.addConstraint(AllDifferentConstraint(), lst)
|
||||
solutions = problem.getSolution()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
showSolution(solutions)
|
||||
|
||||
|
||||
def showSolution(solution):
|
||||
for row in range(len(STUDENTDESKS)):
|
||||
for col in range(len(STUDENTDESKS[row])):
|
||||
id = STUDENTDESKS[row][col]
|
||||
sys.stdout.write(" %s" % (id and solution[id] or " "))
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,71 @@
|
||||
#
|
||||
# Sudoku puzzle solver by by Luigi Poderico (www.poderico.it).
|
||||
#
|
||||
import sys
|
||||
from constraint import Problem, AllDifferentConstraint
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
|
||||
# Define the variables: 9 rows of 9 variables rangin in 1...9
|
||||
for i in range(1, 10):
|
||||
problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10))
|
||||
|
||||
# Each row has different values
|
||||
for i in range(1, 10):
|
||||
problem.addConstraint(AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10))
|
||||
|
||||
# Each colum has different values
|
||||
for i in range(1, 10):
|
||||
problem.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10))
|
||||
|
||||
# Each 3x3 box has different values
|
||||
problem.addConstraint(AllDifferentConstraint(), [11, 12, 13, 21, 22, 23, 31, 32, 33])
|
||||
problem.addConstraint(AllDifferentConstraint(), [41, 42, 43, 51, 52, 53, 61, 62, 63])
|
||||
problem.addConstraint(AllDifferentConstraint(), [71, 72, 73, 81, 82, 83, 91, 92, 93])
|
||||
|
||||
problem.addConstraint(AllDifferentConstraint(), [14, 15, 16, 24, 25, 26, 34, 35, 36])
|
||||
problem.addConstraint(AllDifferentConstraint(), [44, 45, 46, 54, 55, 56, 64, 65, 66])
|
||||
problem.addConstraint(AllDifferentConstraint(), [74, 75, 76, 84, 85, 86, 94, 95, 96])
|
||||
|
||||
problem.addConstraint(AllDifferentConstraint(), [17, 18, 19, 27, 28, 29, 37, 38, 39])
|
||||
problem.addConstraint(AllDifferentConstraint(), [47, 48, 49, 57, 58, 59, 67, 68, 69])
|
||||
problem.addConstraint(AllDifferentConstraint(), [77, 78, 79, 87, 88, 89, 97, 98, 99])
|
||||
|
||||
# Some value is given.
|
||||
initValue = [[0, 9, 0, 7, 0, 0, 8, 6, 0],
|
||||
[0, 3, 1, 0, 0, 5, 0, 2, 0],
|
||||
[8, 0, 6, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 7, 0, 5, 0, 0, 0, 6],
|
||||
[0, 0, 0, 3, 0, 7, 0, 0, 0],
|
||||
[5, 0, 0, 0, 1, 0, 7, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 1, 0, 9],
|
||||
[0, 2, 0, 6, 0, 0, 0, 5, 0],
|
||||
[0, 5, 4, 0, 0, 8, 0, 7, 0]]
|
||||
|
||||
for i in range(1, 10):
|
||||
for j in range(1, 10):
|
||||
if initValue[i - 1][j - 1] != 0:
|
||||
problem.addConstraint(lambda var, val=initValue[i - 1][j - 1]:
|
||||
var == val, (i * 10 + j,))
|
||||
|
||||
# Get the solutions.
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
# Print the solutions
|
||||
for solution in solutions:
|
||||
for i in range(1, 10):
|
||||
for j in range(1, 10):
|
||||
index = i * 10 + j
|
||||
sys.stdout.write("%s " % solution[index])
|
||||
print("")
|
||||
print("")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Assign equal values to equal letters, and different values to
|
||||
# different letters, in a way that satisfies the following sum:
|
||||
#
|
||||
# SEIS
|
||||
# + SEIS
|
||||
# ------
|
||||
# DOZE
|
||||
#
|
||||
from constraint import Problem, AllDifferentConstraint
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables("seidoz", range(10))
|
||||
problem.addConstraint(lambda s, e: (2 * s) % 10 == e, "se")
|
||||
problem.addConstraint(lambda i, s, z, e: ((10 * 2 * i) + (2 * s)) % 100 ==
|
||||
z * 10 + e, "isze")
|
||||
problem.addConstraint(lambda s, e, i, d, o, z:
|
||||
2 * (s * 1000 + e * 100 + i * 10 + s) ==
|
||||
d * 1000 + o * 100 + z * 10 + e, "seidoz")
|
||||
problem.addConstraint(lambda s: s != 0, "s")
|
||||
problem.addConstraint(lambda d: d != 0, "d")
|
||||
problem.addConstraint(AllDifferentConstraint())
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
print("SEIS+SEIS=DOZE")
|
||||
for s in solutions:
|
||||
print("%(s)d%(e)d%(i)d%(s)s+%(s)d%(e)d%(i)d%(s)d="
|
||||
"%(d)d%(o)d%(z)d%(e)d") % s
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Assign equal values to equal letters, and different values to
|
||||
# different letters, in a way that satisfies the following sum:
|
||||
#
|
||||
# SEND
|
||||
# + MORE
|
||||
# ------
|
||||
# MONEY
|
||||
#
|
||||
from constraint import Problem, NotInSetConstraint, AllDifferentConstraint
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables("sendmory", range(10))
|
||||
problem.addConstraint(lambda d, e, y: (d + e) % 10 == y, "dey")
|
||||
problem.addConstraint(lambda n, d, r, e, y: (n * 10 + d + r * 10 + e) % 100 ==
|
||||
e * 10 + y, "ndrey")
|
||||
problem.addConstraint(lambda e, n, d, o, r, y:
|
||||
(e * 100 + n * 10 + d + o * 100 + r * 10 + e) % 1000 ==
|
||||
n * 100 + e * 10 + y, "endory")
|
||||
problem.addConstraint(lambda s, e, n, d, m, o, r, y:
|
||||
1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e ==
|
||||
10000 * m + 1000 * o + 100 * n + 10 * e + y, "sendmory")
|
||||
problem.addConstraint(NotInSetConstraint([0]), "sm")
|
||||
problem.addConstraint(AllDifferentConstraint())
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
print("SEND+MORE=MONEY")
|
||||
for s in solutions:
|
||||
print("%(s)d%(e)d%(n)d%(d)d+"
|
||||
"%(m)d%(o)d%(r)d%(e)d="
|
||||
"%(m)d%(o)d%(n)d%(e)d%(y)d" % s)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Assign equal values to equal letters, and different values to
|
||||
# different letters, in a way that satisfies the following sum:
|
||||
#
|
||||
# TWO
|
||||
# + TWO
|
||||
# -----
|
||||
# FOUR
|
||||
#
|
||||
from constraint import Problem, AllDifferentConstraint, NotInSetConstraint
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables("twofur", range(10))
|
||||
problem.addConstraint(lambda o, r: (2 * o) % 10 == r, "or")
|
||||
problem.addConstraint(lambda w, o, u,
|
||||
r: ((10 * 2 * w) + (2 * o)) % 100 == u * 10 + r, "wour")
|
||||
problem.addConstraint(lambda t, w, o, f, u, r:
|
||||
2 * (t * 100 + w * 10 + o) ==
|
||||
f * 1000 + o * 100 + u * 10 + r, "twofur")
|
||||
problem.addConstraint(NotInSetConstraint([0]), "ft")
|
||||
problem.addConstraint(AllDifferentConstraint())
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
print("TWO+TWO=FOUR")
|
||||
for s in solutions:
|
||||
print("%(t)d%(w)d%(o)d+%(t)d%(w)d%(o)d=%(f)d%(o)d%(u)d%(r)d" % s)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Reorganize the following numbers in a way that each line of
|
||||
# 5 numbers sum to 27.
|
||||
#
|
||||
# 1 6
|
||||
# 2 7
|
||||
# 3
|
||||
# 8 4
|
||||
# 9 5
|
||||
#
|
||||
from constraint import Problem, AllDifferentConstraint
|
||||
|
||||
|
||||
def solve():
|
||||
problem = Problem()
|
||||
problem.addVariables("abcdxefgh", range(1, 10))
|
||||
problem.addConstraint(lambda a, b, c, d, x:
|
||||
a < b < c < d and a + b + c + d + x == 27, "abcdx")
|
||||
problem.addConstraint(lambda e, f, g, h, x:
|
||||
e < f < g < h and e + f + g + h + x == 27, "efghx")
|
||||
problem.addConstraint(AllDifferentConstraint())
|
||||
solutions = problem.getSolutions()
|
||||
return solutions
|
||||
|
||||
|
||||
def main():
|
||||
solutions = solve()
|
||||
print("Found %d solutions!" % len(solutions))
|
||||
showSolutions(solutions)
|
||||
|
||||
|
||||
def showSolutions(solutions):
|
||||
for solution in solutions:
|
||||
print(""" %d %d
|
||||
%d %d
|
||||
%d
|
||||
%d %d
|
||||
%d %d
|
||||
""" % (solution["a"], solution["e"],
|
||||
solution["b"], solution["f"],
|
||||
solution["x"],
|
||||
solution["g"], solution["c"],
|
||||
solution["h"], solution["d"]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,9 @@
|
||||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[bdist_rpm]
|
||||
doc_files = README.rst
|
||||
use_bzip2 = 1
|
||||
|
||||
[sdist]
|
||||
formats = bztar
|
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from setuptools import setup, find_packages # Always prefer setuptools over distutils
|
||||
from codecs import open # To use a consistent encoding
|
||||
from os import path
|
||||
import io
|
||||
|
||||
NAME = 'python-constraint'
|
||||
filename = "%s/version.py" % 'constraint'
|
||||
with open(filename) as f:
|
||||
exec(f.read())
|
||||
|
||||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
def readme():
|
||||
filename = path.join(here, 'README.rst')
|
||||
with io.open(filename, 'rt', encoding='UTF-8') as f:
|
||||
return f.read()
|
||||
|
||||
setup(
|
||||
name=NAME,
|
||||
|
||||
# Versions should comply with PEP440. For a discussion on single-sourcing
|
||||
# the version across setup.py and the project code, see
|
||||
# https://packaging.python.org/en/latest/development.html#single-sourcing-the-version
|
||||
#version='0.0.1',
|
||||
version=__version__,
|
||||
|
||||
description="python-constraint is a module implementing support "\
|
||||
"for handling CSPs (Constraint Solving Problems) over finite domain",
|
||||
|
||||
long_description=readme(),
|
||||
|
||||
# The project's main homepage.
|
||||
url=__url__,
|
||||
|
||||
# Author details
|
||||
author=__author__,
|
||||
author_email=__email__,
|
||||
|
||||
# Choose your license
|
||||
license=__license__,
|
||||
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
# How mature is this project? Common values are
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
'Development Status :: 3 - Alpha',
|
||||
|
||||
# Indicate who your project is intended for
|
||||
'Environment :: Console',
|
||||
#'Topic :: Software Development :: Build Tools',
|
||||
'Intended Audience :: Science/Research',
|
||||
'Operating System :: OS Independent',
|
||||
|
||||
# Specify the Python versions you support here. In particular, ensure
|
||||
# that you indicate whether you support Python 2, Python 3 or both.
|
||||
'Programming Language :: Cython',
|
||||
|
||||
'Programming Language :: Python',
|
||||
#'Programming Language :: Python :: 2',
|
||||
#'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
#'Programming Language :: Python :: 3',
|
||||
#'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
|
||||
'Topic :: Scientific/Engineering',
|
||||
|
||||
# Pick your license as you wish (should match "license" above)
|
||||
'License :: OSI Approved :: BSD License',
|
||||
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='csp constraint solving problems problem solver',
|
||||
|
||||
# You can just specify the packages manually here if your project is
|
||||
# simple. Or you can use find_packages().
|
||||
packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
|
||||
|
||||
# List run-time dependencies here. These will be installed by pip when your
|
||||
# project is installed. For an analysis of "install_requires" vs pip's
|
||||
# requirements files see:
|
||||
# https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files
|
||||
install_requires=[],
|
||||
|
||||
# List additional groups of dependencies here (e.g. development dependencies).
|
||||
# You can install these using the following syntax, for example:
|
||||
# $ pip install -e .[dev,test]
|
||||
extras_require = {
|
||||
'dev': ['check-manifest', 'nose'],
|
||||
'test': ['coverage', 'nose'],
|
||||
},
|
||||
|
||||
# If there are data files included in your packages that need to be
|
||||
# installed, specify them here. If using Python 2.6 or less, then these
|
||||
# have to be included in MANIFEST.in as well.
|
||||
#package_data={
|
||||
# 'sample': ['logging.conf'],
|
||||
#},
|
||||
|
||||
# Although 'package_data' is the preferred approach, in some case you may
|
||||
# need to place data files outside of your packages.
|
||||
# see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
|
||||
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
|
||||
#data_files=[('my_data', ['data/data_file'])],
|
||||
|
||||
# To provide executable scripts, use entry points in preference to the
|
||||
# "scripts" keyword. Entry points provide cross-platform support and allow
|
||||
# pip to create the appropriate form of executable for the target platform.
|
||||
#entry_points={
|
||||
# 'console_scripts': [
|
||||
# 'sample=sample:main',
|
||||
# ],
|
||||
#},
|
||||
)
|
@ -0,0 +1,91 @@
|
||||
import constraint
|
||||
|
||||
from examples.abc import abc
|
||||
from examples.coins import coins
|
||||
# from examples.crosswords import crosswords
|
||||
from examples.einstein import einstein
|
||||
from examples.queens import queens
|
||||
from examples.rooks import rooks
|
||||
from examples.studentdesks import studentdesks
|
||||
# from examples.sudoku import sudoku
|
||||
# from examples.wordmath import (seisseisdoze, sendmoremoney, twotwofour)
|
||||
# from examples.xsum import xsum
|
||||
|
||||
import constraint.compat as compat
|
||||
|
||||
|
||||
def test_abc():
|
||||
solutions = abc.solve()
|
||||
minvalue, minsolution = solutions
|
||||
assert minvalue == 37
|
||||
assert minsolution == {'a': 1, 'c': 2, 'b': 1}
|
||||
|
||||
|
||||
def test_coins():
|
||||
solutions = coins.solve()
|
||||
assert len(solutions) == 2
|
||||
|
||||
|
||||
def test_einstein():
|
||||
solutions = einstein.solve()
|
||||
expected_solutions = [
|
||||
{
|
||||
'nationality2': 'dane',
|
||||
'nationality3': 'brit',
|
||||
'nationality1': 'norwegian',
|
||||
'nationality4': 'german',
|
||||
'nationality5': 'swede',
|
||||
'color1': 'yellow',
|
||||
'color3': 'red',
|
||||
'color2': 'blue',
|
||||
'color5': 'white',
|
||||
'color4': 'green',
|
||||
'drink4': 'coffee',
|
||||
'drink5': 'beer',
|
||||
'drink1': 'water',
|
||||
'drink2': 'tea',
|
||||
'drink3': 'milk',
|
||||
'smoke5': 'bluemaster',
|
||||
'smoke4': 'prince',
|
||||
'smoke3': 'pallmall',
|
||||
'smoke2': 'blends',
|
||||
'smoke1': 'dunhill',
|
||||
'pet5': 'dogs',
|
||||
'pet4': 'fish',
|
||||
'pet1': 'cats',
|
||||
'pet3': 'birds',
|
||||
'pet2': 'horses'
|
||||
}
|
||||
]
|
||||
assert solutions == expected_solutions
|
||||
|
||||
|
||||
def test_queens():
|
||||
solutions, size = queens.solve()
|
||||
assert size == 8
|
||||
for solution in solutions:
|
||||
queens.showSolution(solution, size)
|
||||
|
||||
|
||||
def test_rooks():
|
||||
size = 8
|
||||
solutions = rooks.solve(size)
|
||||
assert len(solutions) == rooks.factorial(size)
|
||||
|
||||
|
||||
def test_studentdesks():
|
||||
solutions = studentdesks.solve()
|
||||
expected_solutions = {1: 'A', 2: 'E', 3: 'D', 4: 'E', 5: 'D', 6: 'A', 7: 'C', 8: 'B', 9: 'C', 10: 'B', 11: 'E', 12: 'D', 13: 'E', 14: 'D', 15: 'A', 16: 'C', 17: 'B', 18: 'C', 19: 'B', 20: 'A'}
|
||||
assert solutions == expected_solutions
|
||||
|
||||
|
||||
def test_constraint_without_variables():
|
||||
problem = constraint.Problem()
|
||||
problem.addVariable("a", [1, 2, 3])
|
||||
problem.addConstraint(lambda a: a * 2 == 6)
|
||||
solutions = problem.getSolutions()
|
||||
assert solutions == [{'a': 3}]
|
||||
|
||||
|
||||
def test_version():
|
||||
assert isinstance(constraint.__version__, compat.string_types)
|
@ -0,0 +1,17 @@
|
||||
from constraint import Problem, MinConflictsSolver
|
||||
|
||||
|
||||
def test_min_conflicts_solver():
|
||||
problem = Problem(MinConflictsSolver())
|
||||
problem.addVariable("x", [0, 1])
|
||||
problem.addVariable("y", [0, 1])
|
||||
solution = problem.getSolution()
|
||||
|
||||
possible_solutions = [
|
||||
{'x': 0, 'y': 0},
|
||||
{'x': 0, 'y': 1},
|
||||
{'x': 1, 'y': 0},
|
||||
{'x': 1, 'y': 1}
|
||||
]
|
||||
|
||||
assert solution in possible_solutions
|
@ -0,0 +1,102 @@
|
||||
from constraint import Domain, Variable, SomeNotInSetConstraint
|
||||
|
||||
|
||||
def test_empty_constraint():
|
||||
constrainer = SomeNotInSetConstraint(set())
|
||||
v1, v2 = variables = [Variable('v1'), Variable('v2')]
|
||||
assignments = {v1: 'a', v2: 'b'}
|
||||
|
||||
assert constrainer(variables, {}, assignments)
|
||||
|
||||
|
||||
def test_no_overlap():
|
||||
constrainer = SomeNotInSetConstraint(set('zy'))
|
||||
v1, v2 = variables = [Variable('v1'), Variable('v2')]
|
||||
assignments = {v1: 'a', v2: 'b'}
|
||||
|
||||
assert constrainer(variables, {}, assignments)
|
||||
|
||||
|
||||
def test_some_overlap():
|
||||
constrainer = SomeNotInSetConstraint(set('b'))
|
||||
v1, v2 = variables = [Variable('v1'), Variable('v2')]
|
||||
assignments = {v1: 'a', v2: 'b'}
|
||||
|
||||
assert constrainer(variables, {}, assignments)
|
||||
|
||||
|
||||
def test_too_much_overlap():
|
||||
constrainer = SomeNotInSetConstraint(set('ab'))
|
||||
v1, v2 = variables = [Variable('v1'), Variable('v2')]
|
||||
assignments = {v1: 'a', v2: 'b'}
|
||||
|
||||
assert not constrainer(variables, {}, assignments)
|
||||
|
||||
|
||||
def test_exact():
|
||||
constrainer = SomeNotInSetConstraint(set('abc'), n=2, exact=True)
|
||||
v1, v2, v3 = variables = [Variable('v1'), Variable('v2'), Variable('v3')]
|
||||
|
||||
assignments = {v1: 'a', v2: 'y', v3: 'z'}
|
||||
assert constrainer(variables, {}, assignments)
|
||||
|
||||
assignments = {v1: 'a', v2: 'y'}
|
||||
assert constrainer(variables, {}, assignments)
|
||||
|
||||
assignments = {v1: 'a', v2: 'b', v3: 'z'}
|
||||
assert not constrainer(variables, {}, assignments)
|
||||
|
||||
assignments = {v1: 'a', v2: 'b'}
|
||||
assert not constrainer(variables, {}, assignments)
|
||||
|
||||
assignments = {v1: 'a', v2: 'b', v3: 'c'}
|
||||
assert not constrainer(variables, {}, assignments)
|
||||
|
||||
assignments = {v1: 'x', v2: 'y', v3: 'z'}
|
||||
assert not constrainer(variables, {}, assignments)
|
||||
|
||||
|
||||
def test_forwardcheck():
|
||||
constrainer = SomeNotInSetConstraint(set('abc'), n=2)
|
||||
v1, v2, v3 = variables = [Variable('v1'), Variable('v2'), Variable('v3')]
|
||||
|
||||
domains = {v1: Domain(['a']), v2: Domain(['b', 'y']),
|
||||
v3: Domain(['c', 'z'])}
|
||||
assert constrainer(variables, domains, {v1: 'a'})
|
||||
assert ['a'] == list(domains[v1])
|
||||
assert ['b', 'y'] == list(domains[v2])
|
||||
assert ['c', 'z'] == list(domains[v3])
|
||||
|
||||
assert constrainer(variables, domains, {v1: 'a'}, True)
|
||||
assert ['a'] == list(domains[v1])
|
||||
assert ['y'] == list(domains[v2])
|
||||
assert ['z'] == list(domains[v3])
|
||||
|
||||
|
||||
def test_forwardcheck_empty_domain():
|
||||
constrainer = SomeNotInSetConstraint(set('abc'))
|
||||
v1, v2 = variables = [Variable('v1'), Variable('v2')]
|
||||
|
||||
domains = {v1: Domain(['a']), v2: Domain(['b'])}
|
||||
assert constrainer(variables, domains, {v1: 'a'})
|
||||
assert not constrainer(variables, domains, {v1: 'a'}, True)
|
||||
|
||||
|
||||
def test_forwardcheck_exact():
|
||||
constrainer = SomeNotInSetConstraint(set('abc'), n=2, exact=True)
|
||||
v1, v2, v3 = variables = [Variable('v1'), Variable('v2'), Variable('v3')]
|
||||
assignments = {v1: 'a'}
|
||||
|
||||
domains = {v1: Domain(['a', 'x']), v2: Domain(['b', 'y']),
|
||||
v3: Domain(['c', 'z'])}
|
||||
assert constrainer(variables, domains, assignments)
|
||||
assert constrainer(variables, domains, assignments, True)
|
||||
assert 'b' not in domains[v2]
|
||||
assert 'y' in domains[v2]
|
||||
assert 'c' not in domains[v3]
|
||||
assert 'z' in domains[v3]
|
||||
|
||||
domains = {v1: Domain(['a', 'x']), v2: Domain(['b', 'y']),
|
||||
v3: Domain(['c'])}
|
||||
assert constrainer(variables, domains, assignments)
|
||||
assert not constrainer(variables, domains, assignments, True)
|
Loading…
Reference in New Issue