Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
open-source
logilab-constraint
Commits
494f431b485a
Commit
547e0867
authored
Jul 28, 2021
by
Laurent Peuch
Browse files
chore(format-source): black the code
parent
c8e309de5d62
Pipeline
#130507
passed with stages
in 1 minute and 56 seconds
Changes
31
Pipelines
47
Hide whitespace changes
Inline
Side-by-side
.hg-format-source
View file @
494f431b
...
...
@@ -88,3 +88,33 @@
{"pattern": "test/test_fi.py", "tool": "pyupgrade"}
{"pattern": "test/test_propagation.py", "tool": "pyupgrade"}
{"pattern": "test/test_validation.py", "tool": "pyupgrade"}
{"pattern": "__pkginfo__.py", "tool": "black"}
{"pattern": "examples/chess.py", "tool": "black"}
{"pattern": "examples/conferences.py", "tool": "black"}
{"pattern": "examples/intervals.py", "tool": "black"}
{"pattern": "examples/knights.py", "tool": "black"}
{"pattern": "examples/menza.py", "tool": "black"}
{"pattern": "examples/menza2.py", "tool": "black"}
{"pattern": "examples/menza_brute_force.py", "tool": "black"}
{"pattern": "examples/money.py", "tool": "black"}
{"pattern": "examples/money2.py", "tool": "black"}
{"pattern": "examples/queens.py", "tool": "black"}
{"pattern": "examples/queens2.py", "tool": "black"}
{"pattern": "examples/queens3.py", "tool": "black"}
{"pattern": "examples/rooks.py", "tool": "black"}
{"pattern": "examples/sudoku.py", "tool": "black"}
{"pattern": "logilab/__init__.py", "tool": "black"}
{"pattern": "logilab/constraint/__init__.py", "tool": "black"}
{"pattern": "logilab/constraint/distributors.py", "tool": "black"}
{"pattern": "logilab/constraint/fd.py", "tool": "black"}
{"pattern": "logilab/constraint/fi.py", "tool": "black"}
{"pattern": "logilab/constraint/interfaces.py", "tool": "black"}
{"pattern": "logilab/constraint/propagation.py", "tool": "black"}
{"pattern": "setup.py", "tool": "black"}
{"pattern": "test/__profile__.py", "tool": "black"}
{"pattern": "test/test_constraints.py", "tool": "black"}
{"pattern": "test/test_distributors.py", "tool": "black"}
{"pattern": "test/test_domains.py", "tool": "black"}
{"pattern": "test/test_fi.py", "tool": "black"}
{"pattern": "test/test_propagation.py", "tool": "black"}
{"pattern": "test/test_validation.py", "tool": "black"}
__pkginfo__.py
View file @
494f431b
...
...
@@ -17,15 +17,15 @@
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-constraint. If not, see <http://www.gnu.org/licenses/>.
modname
=
'
constraint
'
distname
=
'
logilab-constraint
'
modname
=
"
constraint
"
distname
=
"
logilab-constraint
"
numversion
=
(
0
,
6
,
0
)
version
=
'.'
.
join
(
map
(
str
,
numversion
))
version
=
"."
.
join
(
map
(
str
,
numversion
))
license
=
'
LGPL
'
copyright
=
'''
Copyright (c) 2002-2010 LOGILAB S.A. (Paris, FRANCE).
http://www.logilab.fr/ -- mailto:contact@logilab.fr
'''
license
=
"
LGPL
"
copyright
=
"""
Copyright (c) 2002-2010 LOGILAB S.A. (Paris, FRANCE).
http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
description
=
"constraints satisfaction solver in Python"
...
...
@@ -42,15 +42,14 @@ author_email = "contact@logilab.fr"
web
=
"http://www.logilab.org/projects/%s"
%
distname
mailinglist
=
"http://lists.logilab.org/mailman/listinfo/python-logic/"
subpackage_of
=
'
logilab
'
subpackage_of
=
"
logilab
"
classifiers
=
[
"Topic :: Scientific/Engineering"
,
"Programming Language :: Python"
,
"Programming Language :: Python :: 2"
,
"Programming Language :: Python :: 3"
,
]
classifiers
=
[
"Topic :: Scientific/Engineering"
,
"Programming Language :: Python"
,
"Programming Language :: Python :: 2"
,
"Programming Language :: Python :: 3"
,
]
install_requires
=
[
'setuptools'
,
'logilab-common >= 0.63.2'
,
'six >= 1.4.0'
]
install_requires
=
[
"setuptools"
,
"logilab-common >= 0.63.2"
,
"six >= 1.4.0"
]
tests_require
=
[]
examples/chess.py
View file @
494f431b
...
...
@@ -30,7 +30,7 @@ class ChessDomain(fd.FiniteDomain):
def
__repr__
(
self
):
vals
=
self
.
getValues
()
vals
.
sort
()
return
'
<ChessDomain %s>
'
%
str
(
vals
)
return
"
<ChessDomain %s>
"
%
str
(
vals
)
class
QueensConstraint
(
AbstractConstraint
):
...
...
@@ -38,7 +38,7 @@ class QueensConstraint(AbstractConstraint):
AbstractConstraint
.
__init__
(
self
,
variables
)
def
__repr__
(
self
):
return
'
<QueensConstraint %s>
'
%
str
(
self
.
_variables
)
return
"
<QueensConstraint %s>
"
%
str
(
self
.
_variables
)
def
narrow
(
self
,
domains
):
maybe_entailed
=
1
...
...
@@ -60,9 +60,11 @@ class QueensConstraint(AbstractConstraint):
continue
val2_0
=
val2
[
0
]
val2_1
=
val2
[
1
]
if
val1_0
<
val2_0
and
\
val1_1
!=
val2_1
and
\
abs
(
val1_0
-
val2_0
)
!=
abs
(
val1_1
-
val2_1
):
if
(
val1_0
<
val2_0
and
val1_1
!=
val2_1
and
abs
(
val1_0
-
val2_0
)
!=
abs
(
val1_1
-
val2_1
)
):
keep1
[
val1
]
=
1
keep2
[
val2
]
=
1
else
:
...
...
@@ -72,8 +74,7 @@ class QueensConstraint(AbstractConstraint):
dom1
.
removeValues
([
val
for
val
in
values1
if
val
not
in
keep1
])
dom2
.
removeValues
([
val
for
val
in
values2
if
val
not
in
keep2
])
except
ConsistencyFailure
:
raise
ConsistencyFailure
(
'Inconsistency while applying %s'
%
repr
(
self
))
raise
ConsistencyFailure
(
"Inconsistency while applying %s"
%
repr
(
self
))
except
Exception
:
print
(
self
,
kwargs
)
raise
...
...
examples/conferences.py
View file @
494f431b
...
...
@@ -19,43 +19,46 @@
# import Repository, ListDomain and MathematicConstraint
from
logilab.constraint
import
*
variables
=
(
'c01'
,
'c02'
,
'c03'
,
'c04'
,
'c05'
,
'c06'
,
'c07'
,
'c08'
,
'c09'
,
'c10'
)
values
=
[(
room
,
slot
)
for
room
in
(
'room A'
,
'room B'
,
'room C'
)
for
slot
in
(
'day 1 AM'
,
'day 1 PM'
,
'day 2 AM'
,
'day 2 PM'
)]
variables
=
(
"c01"
,
"c02"
,
"c03"
,
"c04"
,
"c05"
,
"c06"
,
"c07"
,
"c08"
,
"c09"
,
"c10"
)
values
=
[
(
room
,
slot
)
for
room
in
(
"room A"
,
"room B"
,
"room C"
)
for
slot
in
(
"day 1 AM"
,
"day 1 PM"
,
"day 2 AM"
,
"day 2 PM"
)
]
domains
=
{}
for
v
in
variables
:
domains
[
v
]
=
fd
.
FiniteDomain
(
values
)
constraints
=
[]
# Internet access is in room C only
for
conf
in
(
'c03'
,
'c04'
,
'c05'
,
'c06'
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[0] == 'room C'"
%
conf
))
for
conf
in
(
"c03"
,
"c04"
,
"c05"
,
"c06"
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[0] == 'room C'"
%
conf
))
# Speakers only available on day 1
for
conf
in
(
'c01'
,
'c05'
,
'c10'
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[1].startswith('day 1')"
%
conf
))
for
conf
in
(
"c01"
,
"c05"
,
"c10"
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[1].startswith('day 1')"
%
conf
))
# Speakers only available on day 2
for
conf
in
(
'c02'
,
'c03'
,
'c04'
,
'c09'
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[1].startswith('day 2')"
%
conf
))
for
conf
in
(
"c02"
,
"c03"
,
"c04"
,
"c09"
):
constraints
.
append
(
fd
.
make_expression
((
conf
,),
"%s[1].startswith('day 2')"
%
conf
))
# try to satisfy people willing to attend several conferences
groups
=
((
'c01'
,
'c02'
,
'c03'
,
'c10'
),
(
'c02'
,
'c06'
,
'c08'
,
'c09'
),
(
'c03'
,
'c05'
,
'c06'
,
'c07'
),
(
'c01'
,
'c03'
,
'c07'
,
'c08'
))
groups
=
(
(
"c01"
,
"c02"
,
"c03"
,
"c10"
),
(
"c02"
,
"c06"
,
"c08"
,
"c09"
),
(
"c03"
,
"c05"
,
"c06"
,
"c07"
),
(
"c01"
,
"c03"
,
"c07"
,
"c08"
),
)
for
g
in
groups
:
for
conf1
in
g
:
for
conf2
in
g
:
if
conf2
>
conf1
:
print
(
f
'
{
conf1
}
[1] !=
{
conf2
}
[1]'
)
constraints
.
append
(
fd
.
make_expression
((
conf1
,
conf2
),
'%s[1] != %s[1]'
%
(
conf1
,
conf2
)))
print
(
f
"
{
conf1
}
[1] !=
{
conf2
}
[1]"
)
constraints
.
append
(
fd
.
make_expression
(
(
conf1
,
conf2
),
"%s[1] != %s[1]"
%
(
conf1
,
conf2
)
)
)
constraints
.
append
(
fd
.
AllDistinct
(
variables
))
...
...
examples/intervals.py
View file @
494f431b
...
...
@@ -32,19 +32,19 @@ def intervals(size=5, verbose=0):
domains
=
{}
constraints
=
[]
for
i
in
range
(
size
):
name
=
'
v%02d
'
%
i
name
=
"
v%02d
"
%
i
variables
.
append
(
name
)
domains
[
name
]
=
fi
.
FiniteIntervalDomain
(
0
,
size
*
5
,
5
)
domains
[
name
]
=
fi
.
FiniteIntervalDomain
(
0
,
size
*
5
,
5
)
for
i
,
q1
in
enumerate
(
variables
):
if
i
+
1
==
len
(
variables
):
if
i
+
1
==
len
(
variables
):
continue
q2
=
variables
[
i
+
1
]
q2
=
variables
[
i
+
1
]
c
=
fi
.
StartsAfterEnd
(
q1
,
q2
)
constraints
.
append
(
c
)
## print domains
## print constraints
## print domains
## print constraints
r
=
Repository
(
variables
,
domains
,
constraints
)
yield
from
Solver
(
fi
.
FiniteIntervalDistributor
()).
solve_all
(
r
,
verbose
)
...
...
@@ -52,9 +52,10 @@ def intervals(size=5, verbose=0):
def
main
(
args
=
None
):
import
sys
import
getopt
if
args
is
None
:
args
=
sys
.
argv
[
1
:]
opts
,
args
=
getopt
.
getopt
(
args
,
'
dvf
'
)
opts
,
args
=
getopt
.
getopt
(
args
,
"
dvf
"
)
display
=
0
verbose
=
0
first
=
0
...
...
@@ -63,9 +64,9 @@ def main(args=None):
else
:
size
=
8
for
o
,
v
in
opts
:
if
o
==
'
-d
'
:
if
o
==
"
-d
"
:
display
=
1
elif
o
==
'
-v
'
:
elif
o
==
"
-v
"
:
verbose
+=
1
elif
o
==
"-f"
:
first
=
1
...
...
@@ -74,15 +75,15 @@ def main(args=None):
count
+=
1
if
display
:
print
(
sol
)
print
(
'*'
*
80
)
print
(
"*"
*
80
)
if
first
:
break
if
not
display
:
print
(
'
Use -d option to display solutions
'
)
print
(
count
,
'
solutions found.
'
)
print
(
"
Use -d option to display solutions
"
)
print
(
count
,
"
solutions found.
"
)
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
## import hotshot
## p = hotshot.Profile('/tmp/queens.prof')
# p.runcall(main)
...
...
examples/knights.py
View file @
494f431b
...
...
@@ -36,14 +36,14 @@ def knight_tour(size=6, verbose=0):
# the white tiles: one less if n is odd
for
row
in
range
(
size
):
for
column
in
range
(
size
):
if
(
row
+
column
)
%
2
==
0
:
if
(
row
+
column
)
%
2
==
0
:
black_checker
.
append
((
row
,
column
))
else
:
white_checker
.
append
((
row
,
column
))
# One variable for each step in the tour
for
i
in
range
(
size
*
size
):
name
=
'
x%02d
'
%
i
for
i
in
range
(
size
*
size
):
name
=
"
x%02d
"
%
i
variables
.
append
(
name
)
# The knight's move jumps from black to white
# and vice versa, so we make all the even steps black
...
...
@@ -54,19 +54,23 @@ def knight_tour(size=6, verbose=0):
domains
[
name
]
=
fd
.
FiniteDomain
(
white_checker
)
if
i
>
0
:
j
=
i
-
1
k1
=
'
x%02d
'
%
j
k2
=
'
x%02d
'
%
i
k1
=
"
x%02d
"
%
j
k2
=
"
x%02d
"
%
i
# the knight's move constraint
c
=
fd
.
make_expression
((
k1
,
k2
),
'abs(%(v1)s[0]-%(v2)s[0]) + abs(%(v1)s[1]-%(v2)s[1]) == 3'
%
{
'v1'
:
k1
,
'v2'
:
k2
})
c
=
fd
.
make_expression
(
(
k1
,
k2
),
"abs(%(v1)s[0]-%(v2)s[0]) + abs(%(v1)s[1]-%(v2)s[1]) == 3"
%
{
"v1"
:
k1
,
"v2"
:
k2
},
)
constraints
.
append
(
c
)
c
=
fd
.
make_expression
((
k1
,
k2
),
'abs(abs(%(v1)s[0]-%(v2)s[0]) - abs(%(v1)s[1]-%(v2)s[1])) == 1'
%
{
'v1'
:
k1
,
'v2'
:
k2
})
c
=
fd
.
make_expression
(
(
k1
,
k2
),
"abs(abs(%(v1)s[0]-%(v2)s[0]) - abs(%(v1)s[1]-%(v2)s[1])) == 1"
%
{
"v1"
:
k1
,
"v2"
:
k2
},
)
constraints
.
append
(
c
)
constraints
.
append
(
fd
.
AllDistinct
(
variables
))
half
=
size
/
2
half
=
size
/
2
r
=
Repository
(
variables
,
domains
,
constraints
)
sol
=
Solver
(
EnumeratorDistributor
()).
solve_one
(
r
,
verbose
)
return
sol
...
...
@@ -77,27 +81,28 @@ def draw_solution(sol, size):
# to display the results.
# I'm sure there's a better way to do this, but I'm
# new to python
board
=
''
board
+=
'_'
*
(
size
*
3
+
1
)
+
'
\n
'
board
=
""
board
+=
"_"
*
(
size
*
3
+
1
)
+
"
\n
"
squares
=
{}
for
t
in
sol
.
items
():
squares
[(
t
[
1
][
0
]
*
size
)
+
t
[
1
][
1
]]
=
t
[
0
]
squares
[(
t
[
1
][
0
]
*
size
)
+
t
[
1
][
1
]]
=
t
[
0
]
for
i
in
range
(
size
):
for
j
in
range
(
size
):
# find the variable whose value is (i,j)
square
=
squares
[
i
*
size
+
j
]
square
=
squares
[
i
*
size
+
j
]
# numbering should start from 1 ,not 0
intsquare
=
int
(
square
[
1
:
4
])
+
1
board
+=
'
|%02s
'
%
intsquare
board
+=
'
|
\n
'
board
+=
'¯'
*
(
size
*
3
+
1
)
+
'
\n
'
board
+=
"
|%02s
"
%
intsquare
board
+=
"
|
\n
"
board
+=
"¯"
*
(
size
*
3
+
1
)
+
"
\n
"
print
(
board
)
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
import
sys
import
getopt
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'dv'
)
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"dv"
)
display
=
0
verbose
=
0
if
args
:
...
...
@@ -105,12 +110,12 @@ if __name__ == '__main__':
else
:
size
=
6
for
o
,
v
in
opts
:
if
o
==
'
-d
'
:
if
o
==
"
-d
"
:
display
=
1
elif
o
==
'
-v
'
:
elif
o
==
"
-v
"
:
verbose
+=
2
count
=
0
sol
=
knight_tour
(
size
,
verbose
)
if
display
:
print
(
'
Solution found:
'
)
print
(
"
Solution found:
"
)
draw_solution
(
sol
,
size
)
examples/menza.py
View file @
494f431b
...
...
@@ -34,7 +34,7 @@ class DistinctDigits(BasicConstraint):
domain
=
domains
[
self
.
_variable
]
for
v
in
domain
.
getValues
():
s
=
str
(
v
)
for
d
in
(
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
):
for
d
in
(
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
):
if
s
.
count
(
d
)
not
in
(
0
,
1
):
domain
.
removeValue
(
v
)
break
...
...
@@ -42,53 +42,53 @@ class DistinctDigits(BasicConstraint):
def
__repr__
(
self
):
return
'
<DistinctDigits on variable %s>
'
%
self
.
_variable
return
"
<DistinctDigits on variable %s>
"
%
self
.
_variable
def
menza
():
"""
"""
""" """
VARS
=
'
ab
'
VARS
=
"
ab
"
variables
=
list
(
VARS
)
domains
=
{}
constraints
=
[]
domains
[
'a'
]
=
fd
.
FiniteDomain
(
range
(
0
,
1000
))
domains
[
'b'
]
=
fd
.
FiniteDomain
(
range
(
0
,
100
))
domains
[
"a"
]
=
fd
.
FiniteDomain
(
range
(
0
,
1000
))
domains
[
"b"
]
=
fd
.
FiniteDomain
(
range
(
0
,
100
))
me
=
fd
.
make_expression
for
v
in
variables
:
constraints
.
append
(
DistinctDigits
(
v
))
dist
=
[
'
10000 < a*b
'
]
dist
=
[
"
10000 < a*b
"
]
for
digit
in
range
(
10
):
dist
.
append
(
'("%%.3d%%.2d%%.5d" %% (a,b,a*b)).count("%d")==1'
%
digit
)
constraints
.
append
(
me
((
'a'
,
'b'
),
'
and
'
.
join
(
dist
)))
constraints
.
append
(
me
((
"a"
,
"b"
),
"
and
"
.
join
(
dist
)))
r
=
Repository
(
variables
,
domains
,
constraints
)
return
r
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
import
sys
import
getopt
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'dv'
)
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"dv"
)
verbose
=
0
display
=
0
create_problem
=
menza
for
o
,
v
in
opts
:
if
o
==
'
-v
'
:
if
o
==
"
-v
"
:
verbose
+=
1
elif
o
==
'
-d
'
:
elif
o
==
"
-d
"
:
display
=
1
r
=
create_problem
()
print
(
'
problem created. let us solve it.
'
)
print
(
"
problem created. let us solve it.
"
)
s
=
[]
for
sol
in
Solver
().
solve_all
(
r
,
verbose
):
s
.
append
(
sol
)
if
display
:
sol
[
'c'
]
=
sol
[
'a'
]
*
sol
[
'b'
]
sol
[
"c"
]
=
sol
[
"a"
]
*
sol
[
"b"
]
print
(
"%(a)s x %(b)s = %(c)s"
%
sol
)
if
not
display
:
print
(
'
Found %d solutions
'
%
len
(
s
))
print
(
"
Found %d solutions
"
%
len
(
s
))
examples/menza2.py
View file @
494f431b
...
...
@@ -36,17 +36,16 @@ class DistinctDigits(BasicConstraint):
try
:
for
v
in
domain
.
getValues
():
s
=
str
(
v
)
for
d
in
(
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
):
for
d
in
(
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
):
if
s
.
count
(
d
)
not
in
(
0
,
1
):
domain
.
removeValue
(
v
)
break
except
ConsistencyFailure
as
e
:
raise
ConsistencyFailure
(
'inconsistency while applying %s'
%
repr
(
self
))
raise
ConsistencyFailure
(
"inconsistency while applying %s"
%
repr
(
self
))
return
1
def
__repr__
(
self
):
return
'
<DistinctDigits>
'
return
"
<DistinctDigits>
"
def
mensa
():
...
...
@@ -54,14 +53,14 @@ def mensa():
ABC*DE=FGHIJ with all letters different and in domain [0,9]
"""
VARS
=
'
xy
'
VARS
=
"
xy
"
variables
=
list
(
VARS
)
domains
=
{}
constraints
=
[]
# x = ABC and y = DE, x*y = FGHIJ
domains
[
'x'
]
=
fd
.
FiniteDomain
(
range
(
0
,
1000
))
domains
[
'y'
]
=
fd
.
FiniteDomain
(
range
(
0
,
100
))
domains
[
"x"
]
=
fd
.
FiniteDomain
(
range
(
0
,
1000
))
domains
[
"y"
]
=
fd
.
FiniteDomain
(
range
(
0
,
100
))
# x and y *must* have distinct digits themselves
# (for example this will remove 232 from x's domain)
...
...
@@ -72,31 +71,32 @@ def mensa():
dist
=
[]
for
digit
in
range
(
10
):
dist
.
append
(
'("%%.3d%%.2d%%.5d" %% (x,y,x*y)).count("%d")==1'
%
digit
)
c
=
'
and
'
.
join
(
dist
)
constraints
.
append
(
fd
.
make_expression
((
'x'
,
'y'
),
c
))
c
=
"
and
"
.
join
(
dist
)
constraints
.
append
(
fd
.
make_expression
((
"x"
,
"y"
),
c
))
r
=
Repository
(
variables
,
domains
,
constraints
)
return
r
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
import
sys
import
getopt
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'dv'
)
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"dv"
)
verbose
=
0
display
=
0
for
o
,
v
in
opts
:
if
o
==
'
-v
'
:
if
o
==
"
-v
"
:
verbose
+=
1
elif
o
==
'
-d
'
:
elif
o
==
"
-d
"
:
display
=
1
r
=
mensa
()
print
(
'
problem created. let us solve it.
'
)
print
(
"
problem created. let us solve it.
"
)
s
=
[]
for
sol
in
Solver
().
solve_all
(
r
,
verbose
):
s
.
append
(
sol
)
if
display
:
sol
[
'c'
]
=
sol
[
'x'
]
*
sol
[
'y'
]
sol
[
"c"
]
=
sol
[
"x"
]
*
sol
[
"y"
]
print
(
"%(x)s x %(y)s = %(c)s"
%
sol
)
if
not
display
:
print
(
'
Found %d solutions
'
%
len
(
s
))
print
(
"
Found %d solutions
"
%
len
(
s
))
examples/menza_brute_force.py
View file @
494f431b
...
...
@@ -17,22 +17,21 @@
# with logilab-constraint. If not, see <http://www.gnu.org/licenses/>.
def
menza
():
sol
=
[]
all_digits
=
[
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
]
for
a
in
range
(
1000
):
for
b
in
range
(
100
):
c
=
a
*
b
c
=
a
*
b
if
c
>
9999
:
digits
=
list
(
"%.3d%.2d%.5d"
%
(
a
,
b
,
c
))
digits
.
sort
()
if
digits
==
all_digits
:
sol
.
append
({
'a'
:
a
,
'b'
:
b
})
sol
.
append
({
"a"
:
a
,
"b"
:
b
})
print
(
"%.3d x %.2d = %.5d"
%
(
a
,
b
,
c
))
return
sol
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
sol
=
menza
()
print
(
len
(
sol
))
examples/money.py
View file @
494f431b
...
...
@@ -22,31 +22,32 @@ from logilab.constraint import *
def
money
(
verbose
=
0
):
"""
SEND
+MORE
-------
MONEY
"""SEND
+MORE
-------
MONEY
"""
digits
=
range
(
10
)
variables
=
list
(
'
sendmory
'
)
variables
=
list
(
"
sendmory
"
)
domains
=
{}
constraints
=
[]
for
v
in
variables
:
domains
[
v
]
=
fd
.
FiniteDomain
(
digits
)
constraints
.
append
(
fd
.
AllDistinct
(
variables
))
constraints
.
append
(
fd
.
NotEquals
(
'm'
,
0
))
constraints
.
append
(
fd
.
NotEquals
(
's'
,
0
))
constraints
.
append
(
fd
.
make_expression
((
's'
,
'm'
,
'o'
),
'(s+m) in (10*m+o,10*m+o-1)'
))
constraints
.
append
(
fd
.
make_expression
((
'd'
,
'e'
,
'y'
),
'(d+e)%10 == y'
))
constraints
.
append
(
fd
.
make_expression
((
'n'
,
'r'
,
'e'
),
'(n+r)%10 in (e,e-1)'
))
constraints
.
append
(
fd
.
make_expression
((
'o'
,
'e'
,
'n'
),
'(o+e)%10 in (n,n-1)'
))
constraints
.
append
(
fd
.
make_expression
(
variables
,
'm*10000+(o-m-s)*1000+(n-o-e)*100+(e-r-n)*10+y-e-d == 0'
))
constraints
.
append
(
fd
.
NotEquals
(
"m"
,
0
))
constraints
.
append
(
fd
.
NotEquals
(
"s"
,
0
))
constraints
.
append
(
fd
.
make_expression
((
"s"
,
"m"
,
"o"
),
"(s+m) in (10*m+o,10*m+o-1)"
)
)
constraints
.
append
(
fd
.
make_expression
((
"d"
,
"e"
,
"y"
),
"(d+e)%10 == y"
))
constraints
.
append
(
fd
.
make_expression
((
"n"
,
"r"
,
"e"
),
"(n+r)%10 in (e,e-1)"
))
constraints
.
append
(
fd
.
make_expression
((
"o"
,
"e"
,
"n"
),
"(o+e)%10 in (n,n-1)"
))
constraints
.
append
(
fd
.
make_expression
(
variables
,
"m*10000+(o-m-s)*1000+(n-o-e)*100+(e-r-n)*10+y-e-d == 0"
)
)
r
=
Repository
(
variables
,
domains
,
constraints
)
s
=
Solver
().
solve_one
(
r
,
verbose
)
return
s
...
...
@@ -54,23 +55,24 @@ def money(verbose=0):
def
display_solution
(
d
):