tribulations

main
Matthew Butterick 10 years ago
parent 998d4830e9
commit 6fd2aea9d2

@ -227,6 +227,7 @@ def min_conflicts(csp, max_steps=1000000):
csp.assign(var, val, current)
# Now repeapedly choose a random conflicted variable and change it
for i in range(max_steps):
print i
conflicted = csp.conflicted_vars(current)
if not conflicted:
return current
@ -447,4 +448,4 @@ def solve_zebra(algorithm=min_conflicts, **args):
print
return ans['Zebra'], ans['Water'], z.nassigns, ans,
solve_zebra()

@ -0,0 +1,167 @@
#lang racket/base
(require racket/class racket/contract racket/match)
(require sugar/container sugar/debug)
(module+ test (require rackunit))
;; Adapted from work by Gustavo Niemeyer
#|
# 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.
|#
(provide (all-defined-out))
;(provide Problem Variable Domain Unassigned Solver BacktrackingSolver RecursiveBacktrackingSolver MinConflictsSolver Constraint FunctionConstraint AllDifferentConstraint AllEqualConstraint MaxSumConstraint ExactSumConstraint MinSumConstraint InSetConstraint NotInSetConstraint SomeInSetConstraint SomeNotInSetConstraint)
;(define Problem/c (λ(x) (is-a x Problem)))
(define/contract Problem
;; Class used to define a problem and retrieve solutions
(class/c [reset (->m void?)]
;; todo: tighten `object?` contracts
[setSolver (object? . ->m . void?)]
[getSolver (->m object?)]
;; todo: tighten `object?` contract
[addVariable (any/c (or/c list? object?) . ->m . void?)]
[getSolutions (->m list?)])
(class object%
(super-new)
(init-field [solver #f])
(field [_solver (or solver (new BacktrackingSolver))]
[_constraints null]
[_variables (make-hash)])
(define/public (reset)
;; Reset the current problem definition
(set! _constraints null)
(hash-clear! _variables))
(define/public (setSolver solver)
;; Change the problem solver currently in use
(set! _solver solver))
(define/public (getSolver)
;; Obtain the problem solver currently in use
_solver)
(define/public (addVariable variable domain)
;; Add a variable to the problem
(when (variable . in? . _variables)
(error 'addVariable (format "Tried to insert duplicated variable ~a" variable)))
(cond
[(list? domain) (report domain) (set! domain (new Domain [set domain]))]
;; todo: test for `instance-of-Domain?` ; how to copy domain?
[(object? domain) (report 'foo) (report domain) (set! domain '(copy.copy domain))]
[else (error 'addVariable "Domains must be instances of subclasses of Domain")])
(when (not domain) ; todo: check this test
(error 'addVariable "Domain is empty"))
(hash-set! _variables variable (get-field _list domain)))
(define/public (addVariables variables domain)
;; Add one or more variables to the problem
(for-each (λ(var) (addVariable var domain)) variables))
(define/public (getSolutions)
;; Find and return all solutions to the problem
(define-values (domains constraints vconstraints) (_getArgs))
(if (not domains)
null
(send _solver getSolutions domains constraints vconstraints)))
(define/public (_getArgs)
(define domains (hash-copy _variables))
(define allvariables (hash-keys domains))
(define constraints null)
(for ([constraint-variables-pair (in-list _constraints)])
(match-define (cons constraint variables) constraint-variables-pair)
(when (not variables)
(set! variables allvariables))
(set! constraints (append constraints (list (cons constraint variables)))))
(define vconstraints (make-hash))
(for ([variable (in-hash-keys domains)])
(hash-set! vconstraints variable null))
(for ([constraint-variables-pair (in-list constraints)])
(match-define (cons constraint variables) constraint-variables-pair)
(for ([variable (in-list variables)])
(hash-update! vconstraints variable (λ(val) (append val (list (cons constraint variables)))))))
(for ([constraint-variables-pair (in-list constraints)])
(match-define (cons constraint variables) constraint-variables-pair)
(send constraint preProcess variables domains constraints vconstraints))
(define result #f)
(let/ec done
(for ([domain (in-list (hash-values domains))])
(send domain resetState)
(when (not domain)
(set! result (values null null null))
(done)))
(set! result (values domains constraints vconstraints)))
result)
))
(module+ test
(check-equal? (get-field _solver (new Problem [solver 'solver-in])) 'solver-in)
(check-equal? (get-field _constraints (new Problem)) null)
(check-equal? (get-field _variables (new Problem)) (make-hash))
(define problem (new Problem))
(send problem addVariable "a" '(1 2))
(check-equal? (hash-ref (get-field _variables problem) "a") '(1 2))
(send problem reset)
(check-equal? (get-field _variables problem) (make-hash))
(send problem addVariables '("a" "b") '(1 2 3))
(check-equal? (hash-ref (get-field _variables problem) "a") '(1 2 3))
(check-equal? (hash-ref (get-field _variables problem) "b") '(1 2 3))
(get-field _variables problem)
(send problem getSolutions)
)
(define BacktrackingSolver
(class object%
(super-new)))
;; ----------------------------------------------------------------------
;; Domains
;; ----------------------------------------------------------------------
(define Domain
;; Class used to control possible values for variables
;; When list or tuples are used as domains, they are automatically
;; converted to an instance of that class.
(class object%
(super-new)
(init-field set)
(field [_list set])))
(module+ main
(define p (new Problem))
(define d (new Domain [set '(1 2)]))
)

@ -4,6 +4,7 @@
;; http://aima-python.googlecode.com/svn/trunk/csp.py
(require racket/list racket/bool racket/contract racket/class racket/match racket/generator racket/string)
(require sugar/debug)
(require "utils.rkt" "search.rkt")
(module+ test (require rackunit))
@ -310,9 +311,9 @@ Set up to do recursive backtracking search. Allow the following options:
[A (in-list type)]
[B (in-list type)])
(when (not (equal? A B))
(when (not (memq B (hash-ref neighbors A)))
(when (not (member B (report (hash-ref neighbors A))))
(hash-update! neighbors A (λ(v) (append v B))))
(when (not (memq A (hash-ref neighbors B)))
(when (not (member A (hash-ref neighbors B)))
(hash-update! neighbors B (λ(v) (append v A))))))
(define (zebra_constraint A a B b [recurse 0])

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>URL</key>
<string>http://labix.org/doc/constraint/</string>
</dict>
</plist>

@ -0,0 +1,30 @@
#!/usr/bin/python
#
# What's the minimum value for:
#
# ABC
# -------
# A+B+C
#
# From http://www.umassd.edu/mathcontest/abc.cfm
#
from constraint import *
def main():
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
print (minsolution["a"]*100+minsolution["b"]*10+minsolution["c"])/(minsolution["a"]+minsolution["b"]+minsolution["c"])
print minsolution
if __name__ == "__main__":
main()

@ -0,0 +1,30 @@
#!/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 *
import sys
def main():
problem = Problem()
total = 5.00
variables = ("0.01", "0.05", "0.10", "0.25")
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()
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()

File diff suppressed because it is too large Load Diff

@ -0,0 +1,153 @@
#!/usr/bin/python
from constraint import *
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()
l = len(line)
if l in wordsbylen:
wordsbylen[l].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,201 @@
#!/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 *
# Check http://www.csc.fi/oppaat/f95/python/talot.py
def main():
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()
print "Found %d solution(s)!" % len(solutions)
print
for solution in solutions:
showSolution(solution)
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
if __name__ == "__main__":
main()

@ -0,0 +1,190 @@
#!/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 zebra?
#
# HINTS
#
# 1. The englishman lives in a red house.
# 2. The spaniard keeps dogs as pets.
# 5. The owner of the Green house drinks coffee.
# 3. The ukrainian drinks tea.
# 4. The Green house is on the left of the ivory house.
# 6. The person who smokes oldgold rears snails.
# 7. The owner of the Yellow house smokes kools.
# 8. The man living in the centre house drinks milk.
# 9. The Norwegian lives in the first house.
# 10. The man who smokes chesterfields lives next to the one who keeps foxes.
# 11. The man who keeps horses lives next to the man who smokes kools.
# 12. The man who smokes luckystrike drinks orangejuice.
# 13. The japanese smokes parliaments.
# 14. The Norwegian lives next to the blue house.
# 15. The man who smokes chesterfields 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 *
# Check http://www.csc.fi/oppaat/f95/python/talot.py
def main():
problem = Problem()
for i in range(1,6):
problem.addVariable("color%d" % i,
["red", "ivory", "green", "yellow", "blue"])
problem.addVariable("nationality%d" % i,
["englishman", "spaniard", "ukrainian", "norwegian", "japanese"])
problem.addVariable("drink%d" % i,
["tea", "coffee", "milk", "orangejuice", "water"])
problem.addVariable("smoke%d" % i,
["oldgold", "kools", "chesterfields",
"luckystrike", "parliaments"])
problem.addVariable("pet%d" % i,
["dogs", "snails", "foxes", "horses", "zebra"])
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 != "englishman" or color == "red",
("nationality%d" % i, "color%d" % i))
# Hint 2
problem.addConstraint(lambda nationality, pet:
nationality != "spaniard" or pet == "dogs",
("nationality%d" % i, "pet%d" % i))
# Hint 3
problem.addConstraint(lambda nationality, drink:
nationality != "ukrainian" or drink == "tea",
("nationality%d" % i, "drink%d" % i))
# Hint 4
if i < 5:
problem.addConstraint(lambda colora, colorb:
colora != "green" or colorb == "ivory",
("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 != "oldgold" or pet == "snails",
("smoke%d" % i, "pet%d" % i))
# Hint 7
problem.addConstraint(lambda color, smoke:
color != "yellow" or smoke == "kools",
("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 != "chesterfields" or peta == "foxes" or
petb == "foxes",
("smoke%d" % i, "pet%d" % (i-1),
"pet%d" % (i+1)))
else:
problem.addConstraint(lambda smoke, pet:
smoke != "chesterfields" or pet == "foxes",
("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 == "kools" or
smokeb == "kools",
("pet%d" % i, "smoke%d" % (i-1),
"smoke%d" % (i+1)))
else:
problem.addConstraint(lambda pet, smoke:
pet != "horses" or smoke == "kools",
("pet%d" % i,
"smoke%d" % (i == 1 and 2 or 4)))
# Hint 12
problem.addConstraint(lambda smoke, drink:
smoke != "luckystrike" or drink == "orangejuice",
("smoke%d" % i, "drink%d" % i))
# Hint 13
problem.addConstraint(lambda nationality, smoke:
nationality != "japanese" or smoke == "parliaments",
("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)))
solutions = problem.getSolutions()
print "Found %d solution(s)!" % len(solutions)
print
for solution in solutions:
showSolution(solution)
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
if __name__ == "__main__":
main()

@ -0,0 +1,27 @@
# ######## #
# # # # #
######## # #
# # # # #
# # ########
# # # # # #
######## # #
# # # # # #
# # #
######## # #
# # # # #
# ########
# # # # #
# # ########
# # # # # #
# # ########
# # # #
######## # #
# # # # # #
# # # # # #
######## # #
# # # #
# ########
# # # #
######## # #

@ -0,0 +1,19 @@
#
#########
# # #
# # ######
# # #
# # # #
# # # #
######## #
# # #
# # #
#########
# # #
#########
# # #
# #
#######
#

@ -0,0 +1,8 @@
P
Y
####T####
# H #
# O #
####N #
# #
#########

@ -0,0 +1,47 @@
#!/usr/bin/python
#
# http://mathworld.wolfram.com/QueensProblem.html
#
from constraint import *
import sys
def main(show=False):
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()
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: queens.py [-s]")
main(show)

@ -0,0 +1,49 @@
#!/usr/bin/python
#
# http://mathworld.wolfram.com/RooksProblem.html
#
from constraint import *
import sys
def factorial(x): return x == 1 or factorial(x-1)*x
def main(show=False):
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: row1 != row2,
(col1, col2))
solutions = problem.getSolutions()
print "Found %d solution(s)!" % len(solutions)
assert len(solutions) == factorial(size)
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,32 @@
#!/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 *
def main():
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())
print "SEIS+SEIS=DOZE"
for s in problem.getSolutions():
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,34 @@
#!/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 *
def main():
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())
print "SEND+MORE=MONEY"
for s in problem.getSolutions():
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,8 @@
#
#
#########
# #
# # # #
##### # #
# # #
#########

@ -0,0 +1,39 @@
#!/usr/bin/python
#
# http://home.chello.no/~dudley/
#
from constraint import *
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 main():
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)
showSolution(problem.getSolution())
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,61 @@
#
# Sudoku puzzle solver by by Luigi Poderico (www.poderico.it).
#
from constraint import *
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()
# Print the solutions
for solution in solutions:
for i in range(1, 10):
for j in range(1, 10):
index = i*10+j
print solution[index],
print
print

@ -0,0 +1,28 @@
#!/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 *
def main():
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())
print "TWO+TWO=FOUR"
for s in problem.getSolutions():
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,37 @@
#!/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 *
def main():
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()
print "Found %d solutions!" % len(solutions)
showSolutions(solutions)
def showSolutions(solutions):
for solution in solutions:
print " %d %d" % (solution["a"], solution["e"])
print " %d %d " % (solution["b"], solution["f"])
print " %d " % (solution["x"],)
print " %d %d " % (solution["g"], solution["c"])
print " %d %d" % (solution["h"], solution["d"])
print
if __name__ == "__main__":
main()
Loading…
Cancel
Save