main
Matthew Butterick 6 years ago
parent cef3ac0fbe
commit d65248e80c

@ -1,129 +0,0 @@
#lang racket/base
(require racket/class racket/bool sugar/unstable/container sugar/list sugar/debug racket/list "helper.rkt" "variable.rkt")
(provide (all-defined-out))
(define constraint%
(class object%
(super-new)
(define/public (is-true? variables domains assignments [forward-check? #f])
;; Perform the constraint checking
;; If the forwardcheck parameter is not false, besides telling if
;; the constraint is currently broken or not, the constraint
;; implementation may choose to hide values from the domains of
;; unassigned variables to prevent them from being used, and thus
;; prune the search space.
#t)
(define/public (preprocess variables domains constraints vconstraints)
;; todo: functionalize this
;; Preprocess variable domains
;; This method is called before starting to look for solutions,
;; and is used to prune domains with specific constraint logic
;; when possible. For instance, any constraints with a single
;; variable may be applied on all possible values and removed,
;; since they may act on individual values even without further
;; knowledge about other assignments.
(when (= (length variables) 1)
(define variable (car variables))
(define domain (hash-ref domains variable))
(set-field! _list domain
(for/fold ([domain-values (domain)])
([value (in-list (domain))]
#:unless (is-true? variables domains (make-hash (list (cons variable value)))))
(remove value domain-values)))
(set! constraints (remove (list this variables) constraints))
(hash-update! vconstraints variable (λ(val) (remove (list this variables) val)))))
;; Helper method for generic forward checking
;; Currently, this method acts only when there's a single
;; unassigned variable.
(define/public (forward-check variables domains assignments [_unassigned Unassigned])
(define unassigned-variables
(filter-not (λ(v) (hash-has-key? assignments v)) variables))
(cond
;; Remove from the unassigned variable's domain
;; all values that break our variable's constraints.
[(= (length unassigned-variables) 1)
(define unassigned-variable (car unassigned-variables))
(define unassigned-variable-domain (hash-ref domains unassigned-variable))
(for ([value (in-list (unassigned-variable-domain))])
(hash-set! assignments unassigned-variable value)
(unless (is-true? variables domains assignments)
(send unassigned-variable-domain hide-value value)))
(hash-remove! assignments unassigned-variable)
(not (empty? unassigned-variable-domain))] ; if domain had no remaining values, the constraint will be impossible to meet, so return #f
[else #t]))
))
(define constraint%? (is-a?/c constraint%))
(define function-constraint%
(class constraint%
(super-new)
(init-field func [assigned #t])
(field [_func func][_assigned assigned])
(inherit forward-check)
(define/override (is-true? variables domains assignments [forward-check? #f] [_unassigned Unassigned])
(define parms (map (λ(v) (hash-ref assignments v _unassigned)) variables))
(define missing (length (filter (λ(p) (equal? p _unassigned)) parms)))
(if (> missing 0)
(and (or _assigned (apply _func parms))
(or (not forward-check?) (not (= missing 1))
(forward-check variables domains assignments)))
(apply _func parms)))))
(define function-constraint%? (is-a?/c function-constraint%))
;; Constraint enforcing that values of all given variables are different
(define all-different-constraint%
(class constraint%
(super-new)
(define/override (is-true? variables domains assignments [forward-check? #f] [_unassigned Unassigned])
(define-values (assigned-vars unassigned-vars)
(partition (λ(var) (hash-has-key? assignments var)) variables))
(define assigned-values (map (λ(var) (hash-ref assignments var)) assigned-vars))
(cond
[(not (members-unique? assigned-values)) #f] ; constraint failed because they're not all different
[(and forward-check?
(for*/or ([unassigned-var-domain (in-list (map (λ(uv) (hash-ref domains uv)) unassigned-vars))]
[assigned-value (in-list assigned-values)]
#:when (member assigned-value (unassigned-var-domain)))
(send unassigned-var-domain hide-value assigned-value)
(empty? unassigned-var-domain))) #f] ; if domain had no remaining values, the constraint will be impossible to meet, so return #f
[else #t]))))
(define all-different-constraint%? (is-a?/c all-different-constraint%))
;; Constraint enforcing that values of all given variables are different
(define all-equal-constraint%
(class constraint%
(super-new)
(define/override (is-true? variables domains assignments [forward-check? #f] [_unassigned Unassigned])
(define-values (assigned-vars unassigned-vars)
(partition (λ(var) (hash-has-key? assignments var)) variables))
(define assigned-values (map (λ(var) (hash-ref assignments var)) assigned-vars))
(define single-value (if (not (empty? assigned-values))
(car assigned-values)
_unassigned))
(cond
[(not (andmap (λ(v) (equal? single-value v)) assigned-values)) #f] ; constraint broken: not all values the same
[(and forward-check? (not (equal? single-value _unassigned)))
(for/and ([unassigned-var-domain (in-list (map (λ(uv) (hash-ref domains uv)) unassigned-vars))])
;; if single-value is not a member of each domain, constraint will be broken later, so bail out
(and (member single-value (unassigned-var-domain))
(for ([value (in-list (unassigned-var-domain))]
#:unless (equal? value single-value))
(send unassigned-var-domain hide-value value))))] ; otherwise hide nonconforming values
[else #t]))))
(define all-equal-constraint%? (is-a?/c all-equal-constraint%))

@ -1,63 +0,0 @@
#lang racket/base
(require racket/class racket/list "helper.rkt")
(provide (all-defined-out))
;; 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.
(define domain%
(class* object% (printable<%> (make-proc<%> get-values))
(super-new)
(init-field set)
(field [_list set][_hidden null][_states null])
(define (repr) (format "<domain% ~v>" _list))
(define/public (custom-print out quoting-depth) (print (repr) out))
(define/public (custom-display out) (displayln (repr) out))
(define/public (custom-write out) (write (repr) out))
(define/public (reset-state)
;; Reset to the original domain state, including all possible values
(py-extend! _list _hidden)
(set! _hidden null)
(set! _states null))
(define/public (push-state)
;; Save current domain state
;; Variables hidden after that call are restored when that state
;; is popped from the stack.
(py-append! _states (length _list)))
(define/public (pop-state)
;; Restore domain state from the top of the stack
;; Variables hidden since the last popped state are then available
;; again.
(define diff (- (py-pop! _states) (length _list)))
(when (not (= 0 diff))
(py-extend! _list (take-right _hidden diff))
(set! _hidden (take _hidden (- (length _hidden) diff)))))
(define/public (hide-value value)
;; Hide the given value from the domain
;; After that call the given value won't be seen as a possible value
;; on that domain anymore. The hidden value will be restored when the
;; previous saved state is popped.
(set! _list (remove value _list))
(py-append! _hidden value))
(define/public (get-values)
_list)
(define/public (domain-pop!)
(py-pop! _list))
(define/public (copy)
(define copied-domain (new domain% [set _list]))
(set-field! _hidden copied-domain _hidden)
(set-field! _states copied-domain _states)
copied-domain)))
(define domain%? (is-a?/c domain%))

@ -1,83 +0,0 @@
#lang racket/base
(require racket/class racket/list (for-syntax racket/base racket/syntax))
(provide (all-defined-out))
(require rackunit)
(define-syntax-rule (forever expr ...)
(for ([i (in-naturals)])
expr ...))
(define-syntax-rule (forever/until expr ...)
(for/or ([i (in-naturals)])
expr ...))
(define-syntax-rule (for-each-send proc objects)
(for-each (λ(o) (send o proc)) objects))
(define-syntax-rule (make-proc<%> proc-name)
(interface* ()
([prop:procedure
(λ(this . args)
(send/apply this proc-name args))])
proc-name))
(define-simple-check (check-hash-items h1 h2)
(for/and ([(k1 v1) (in-hash h1)])
(equal? (hash-ref h2 k1) v1)))
(define (list-comparator xs ys)
;; For use in sort. Compares two lists element by element.
(cond
[(equal? xs ys) #f] ; elements are same, so no sort preference
[(and (null? xs) (not (null? ys))) #t] ; ys is longer, so #t
[(and (not (null? xs)) (null? ys)) #f] ; xs is longer, so #f makes it sort later
[else (let ([x (car xs)][y (car ys)])
(cond
[(equal? x y) (list-comparator (cdr xs) (cdr ys))]
[(and (real? x) (real? y)) (< x y)]
[(and (symbol? x) (symbol? y)) (apply string<? (map symbol->string (list x y)))]
[(and (string? x) (string? y)) (string<? x y)]
[else (error 'list-comparator (format "Cant compare ~v and ~v" x y))]))]))
(module+ test
(check-false (list-comparator null null))
(check-false (list-comparator (range 2) (range 2)))
(check-true (list-comparator (range 2) (range 4)))
(check-false (list-comparator (range 4) (range 2)))
(check-true (list-comparator '(1 1 "a") '(1 1 "b")))
(check-true (list-comparator '(1 1 a) '(1 1 b))))
(define-syntax-rule (car-pop! xs)
(let ([i (car xs)])
(set! xs (cdr xs))
i))
(define-syntax-rule (py-pop! xs)
(let ([i (last xs)])
(set! xs (drop-right xs 1))
i))
(module+ test
(let ([xs '(1 2 3)])
(check-equal? (py-pop! xs) 3)
(check-equal? xs '(1 2))))
(define-syntax-rule (py-append! xs x)
(set! xs `(,@xs ,x)))
(define-syntax-rule (py-extend! xs x)
(set! xs `(,@xs ,@x)))
(module+ test
(let ([xs '(1 2 3)])
(py-append! xs (range 2))
(check-equal? xs '(1 2 3 (0 1))))
(let ([xs '(1 2 3)])
(py-extend! xs (range 2))
(check-equal? xs '(1 2 3 0 1))))
(define (word-value . xs)
(let ([xs (reverse xs)])
(for/sum ([i (in-range (length xs))])
(* (list-ref xs i) (expt 10 i)))))

@ -1,13 +0,0 @@
#lang racket/base
(require
"problem.rkt"
"constraint.rkt"
"solver.rkt"
"helper.rkt")
(provide (all-from-out
"problem.rkt"
"constraint.rkt"
"solver.rkt"
"helper.rkt"))

@ -1,118 +0,0 @@
#lang racket/base
(require racket/class sugar/unstable/container sugar/debug racket/contract racket/match racket/generator racket/list)
(require "domain.rkt" "helper.rkt" "constraint.rkt" "solver.rkt")
(provide (all-defined-out))
;; Class used to define a problem and retrieve solutions
(define/contract problem%
(class/c [reset (->m void?)]
[set-solver (solver%? . ->m . void?)]
[get-solver (->m solver%?)]
[add-variable (any/c (or/c list? domain%?) . ->m . void?)]
[add-variables ((listof any/c) (or/c list? domain%?) . ->m . void?)]
[add-constraint (((or/c constraint%? procedure?)) ((listof any/c)) . ->*m . void?)]
[get-solution (->m any/c)]
[get-solutions (->m list?)])
(class* object% (printable<%>)
(super-new)
(init-field [solver #f])
(field [_solver (or solver (new backtracking-solver%))]
[_constraints #f]
[_variable-domains #f])
(reset) ; use method rather than manually set up fields
;; implement object printing
(define (repr) (format "<problem% ~a>" (hash-keys _variable-domains)))
(define/public (custom-print out quoting-depth) (print (repr) out))
(define/public (custom-display out) (displayln (repr) out))
(define/public (custom-write out) (write (repr) out))
;; Reset the current problem definition
(define/public (reset)
(set! _constraints null)
(set! _variable-domains (make-hash)))
;; Set the problem solver currently in use
(define/public (set-solver solver)
(set! _solver solver))
;; Get the problem solver currently in use
(define/public (get-solver)
_solver)
;; Add a variable to the problem
;; Contract insures input is Domain object or list of values.
(define/public (add-variable variable domain-or-values)
(when (hash-has-key? _variable-domains variable)
(error 'add-variable (format "Tried to insert duplicated variable ~a" variable)))
(define domain (if (domain%? domain-or-values)
(send domain-or-values copy)
(new domain% [set domain-or-values])))
(when (null? (domain))
(error 'add-variable "domain value is null"))
(hash-set! _variable-domains variable domain))
;; Add one or more variables to the problem
(define/public (add-variables variables domain)
(define in-thing (cond
[(string? variables) in-string]
[(list? variables) in-list]
[else (error 'add-variables (format "Dont know what to do with ~a" variables))]))
(for ([var (in-thing variables)])
(add-variable var domain)))
;; Add a constraint to the problem
;; contract guarantees input is procedure or constraint% object
(define/public (add-constraint constraint-or-proc [variables null])
(define constraint (if (procedure? constraint-or-proc)
(new function-constraint% [func constraint-or-proc])
constraint-or-proc))
(py-append! _constraints (list constraint variables)))
(define-syntax-rule (solution-macro solution-proc null-proc)
(begin
(define-values (domains constraints vconstraints) (get-args))
(if (null? domains)
(if null-proc (null-proc null) null)
(send _solver solution-proc domains constraints vconstraints))))
;; Find and return a solution to the problem
(define/public (get-solution)
(solution-macro get-solution #f))
;; Find and return all solutions to the problem
(define/public (get-solutions)
(solution-macro get-solutions #f))
;; Return an iterator to the solutions of the problem
(define/public (get-solution-iter)
(solution-macro get-solution-iter yield))
(define/private (get-args)
(define variable-domains (hash-copy _variable-domains))
(define constraints
(let ([all-variables (hash-keys variable-domains)])
(for/list ([(constraint variables) (in-parallel (map first _constraints) (map second _constraints))])
(list constraint (if (null? variables) all-variables variables)))))
(define vconstraints
(hash-copy ; converts for/hash to mutable hash
(for/hash ([variable (in-hash-keys variable-domains)])
(values variable null))))
(for* ([(constraint variables) (in-parallel (map first constraints) (map second constraints))]
[variable (in-list variables)])
(hash-update! vconstraints variable (λ(val) (cons (list constraint variables) val))))
(for ([(constraint variables) (in-parallel (map first constraints) (map second constraints))])
(send constraint preprocess variables variable-domains constraints vconstraints))
(if (for/or ([domain (in-hash-values variable-domains)])
(send domain reset-state)
(null? (domain)))
(values null null null)
(values variable-domains constraints vconstraints)))))

@ -1,120 +0,0 @@
#lang racket/base
(require racket/class sugar/unstable/container sugar/debug racket/list
racket/bool racket/generator racket/match "helper.rkt")
(provide (all-defined-out))
(define solver%
;; Abstract base class for solvers
(class object%
(super-new)
(abstract get-solution)
(abstract get-solutions)
(abstract get-solution-iter)))
(define solver%? (is-a?/c solver%))
(struct vvp (variable values pushdomains))
(define-syntax-rule (pop-vvp-values! vvps)
(if (empty? vvps)
(error 'pop-vvp-values! (format "~a is null" vvps))
(let ([vvp (car vvps)])
(set! vvps (cdr vvps))
(values (vvp-variable vvp) (vvp-values vvp) (vvp-pushdomains vvp)))))
#|
(define (recursive-backtracking assignment csp)
(if (complete? assignment)
assignment
(let ([var (select-unassigned-variable csp-variables, assignment, csp)])
(for/or ([value (in-list (order-domain-values var assignment csp))])
if ((value . consistent-with? . assignment csp-constraints))
(add-to assignment var value)
(define result (recursive-backtracking assignment csp))
(when result
(and result (remove-from assignment var value)))
#f))))
|#
(define backtracking-solver%
;; Problem solver with backtracking capabilities
(class solver%
(super-new)
(init-field [forwardcheck #t])
(field [_forwardcheck forwardcheck])
(define/override (get-solution-iter domains constraints vconstraints)
(define sorted-variables (sort (hash-keys domains) list-comparator
#:key (λ(var)
(list (- (length (hash-ref vconstraints var)))
(length ((hash-ref domains var)))
var))))
;; state-retention variables
(define possible-solution (make-hash))
(define variable-queue null)
(define variable #f)
(define values null)
(define pushdomains null)
(define (get-next-unassigned-variable)
(for/first ([sorted-variable (in-list sorted-variables)]
#:unless (hash-has-key? possible-solution sorted-variable))
(set! variable sorted-variable)
(set! values ((hash-ref domains variable)))
(set! pushdomains
(if _forwardcheck
(for/list ([(var domain) (in-hash domains)]
#:unless (and (equal? variable var)
(hash-has-key? possible-solution var)))
domain)
null))
variable))
(define (set!-previous-variable)
(set!-values (variable values pushdomains) (pop-vvp-values! variable-queue))
(for-each-send pop-state pushdomains))
(let/ec exit-k
;; mix the degree and minimum-remaining-values (MRV) heuristics
(forever
(unless (get-next-unassigned-variable)
(yield (hash-copy possible-solution)) ; if there are no unassigned variables, solution is complete.
(if (empty? variable-queue)
(exit-k) ; all done, no other solutions possible.
(set!-previous-variable))) ; otherwise return to previous variable
(let value-checking-loop () ; we have a variable. Do we have any values left?
(when (empty? values) ; no, so try going back to last variable and getting some values
(forever/until
(when (empty? variable-queue) (exit-k)) ; no variables left, so solver is done
(hash-remove! possible-solution variable)
(set!-previous-variable)
(not (empty? values))))
;; Got a value. Check it.
(hash-set! possible-solution variable (car-pop! values))
(for-each-send push-state pushdomains)
(unless (for/and ([constraint+variables (in-list (hash-ref vconstraints variable))])
(let ([constraint (car constraint+variables)]
[variables (cadr constraint+variables)])
(send constraint is-true? variables domains possible-solution pushdomains)))
;; constraint failed, so try again
(for-each-send pop-state pushdomains)
(value-checking-loop)))
;; Push state before looking for next variable.
(set! variable-queue (cons (vvp variable values pushdomains) variable-queue)))
(error 'get-solution-iter "impossible to reach this"))
(void))
(define (call-solution-generator domains constraints vconstraints #:first-only [first-only #f])
(for/list ([solution (in-generator (get-solution-iter domains constraints vconstraints))] #:final first-only)
solution))
(define/override (get-solution . args)
(car (apply call-solution-generator #:first-only #t args)))
(define/override (get-solutions . args)
(apply call-solution-generator args))))
(define backtracking-solver%? (is-a?/c backtracking-solver%))

@ -1,74 +0,0 @@
#lang racket
(require rackunit "main.rkt")
;; Problem: fields
(check-equal? (get-field _solver (new problem% [solver 'solver-in])) 'solver-in)
(check-equal? (get-field _constraints (new problem%)) null)
(check-equal? (get-field _variable-domains (new problem%)) (make-hash))
(define problem null)
;; Problem: reset
(set! problem (new problem%))
(define early-solutions (send problem get-solutions))
(send problem add-variable "a" (range 3))
(check-not-equal? (send problem get-solutions) early-solutions)
(send problem reset)
(check-equal? (send problem get-solutions) early-solutions)
;; Problem: setSolver & get-solver
(define solver (new backtracking-solver%))
(set! problem (new problem% [solver solver]))
(check-true (solver%? (send problem get-solver)))
;; Problem: add-variable
(set! problem (new problem%))
(send problem add-variable "a" '(1 2))
(check-true (or (= (hash-ref (send problem get-solution) "a") 1)
(= (hash-ref (send problem get-solution) "a") 2)))
(check-exn exn:fail? (λ () (send problem add-variable "b" null))) ;; empty domain
;; Problem: add-variables
(set! problem (new problem%))
(send problem add-variables '("a" "b") '(1 2 3))
(check-equal? (length (send problem get-solutions)) 9)
;; Problem: add-constraint
(set! problem (new problem%))
(send problem add-variables '("a" "b") '(1 2 3))
(send problem add-constraint (λ(a b) (= a (add1 b))))
(check-equal? (length (send problem get-solutions)) 2)
;; FunctionConstraint, two ways: implicit and explicit
(send problem reset)
(send problem add-variables '(a b) '(1 2))
(send problem add-constraint <) ; implicit
(check-true (let ([s (sort (hash->list (send problem get-solution)) #:key cdr <)])
(or (equal? s '((a . 1) (b . 2))) (equal? s '((b . 1) (a . 2))))))
(send problem reset)
(send problem add-variables '(a b) '(1 2))
(send problem add-constraint (new function-constraint% [func <])) ; explicit
(check-true (let ([s (sort (hash->list (send problem get-solution)) #:key cdr <)])
(or (equal? s '((a . 1) (b . 2))) (equal? s '((b . 1) (a . 2))))))
;; AllDifferentConstraint
(send problem reset)
(send problem add-variables '(a b) '(1 2))
(send problem add-constraint (new all-different-constraint%))
(let ([solutions (send problem get-solutions)])
(check-equal? (hash-ref (first solutions) 'a) (hash-ref (second solutions) 'b))
(check-equal? (hash-ref (second solutions) 'a) (hash-ref (first solutions) 'b)))
;; AllEqualConstraint
(send problem reset)
(send problem add-variables '(a b) '(1 2))
(send problem add-constraint (new all-equal-constraint%))
(let ([solutions (send problem get-solutions)])
(check-equal? (hash-ref (first solutions) 'a) (hash-ref (first solutions) 'b))
(check-equal? (hash-ref (second solutions) 'a) (hash-ref (second solutions) 'b)))

@ -1,168 +0,0 @@
#lang racket
(require "problem.rkt" "constraint.rkt" sugar/debug)
#|
# 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.
|#
(define ep (new problem%))
(for ([idx '(1 2 3 4 5)])
(send ep add-variable (format "color~a" idx) '("red" "ivory" "green" "yellow" "blue"))
(send ep add-variable (format "nationality~a" idx) '("englishman" "spaniard" "ukrainian" "norwegian" "japanese"))
(send ep add-variable (format "drink~a" idx) '("tea" "coffee" "milk" "orangejuice" "water"))
(send ep add-variable (format "smoke~a" idx) '("oldgold" "kools" "chesterfields" "luckystrike" "parliaments"))
(send ep add-variable (format "pet~a" idx) '("dogs" "snails" "foxes" "horses" "zebra")))
(for ([name '("color" "nationality" "drink" "smoke" "pet")])
(send ep add-constraint (new all-different-constraint%)
(map (λ(idx) (format "~a~a" name idx)) '(1 2 3 4 5))))
(for ([idx '(1 2 3 4 5)])
(send ep add-constraint
(λ(n c) (or (not (equal? n "englishman")) (equal? c "red")))
(list (format "nationality~a" idx) (format "color~a" idx)))
(send ep add-constraint
(λ(n p) (or (not (equal? n "spaniard")) (equal? p "dogs")))
(list (format "nationality~a" idx) (format "pet~a" idx)))
(send ep add-constraint
(λ(n d) (or (not (equal? n "ukrainian")) (equal? d "tea")))
(list (format "nationality~a" idx) (format "drink~a" idx)))
(if (< idx 5)
(send ep add-constraint
(λ(ca cb) (or (not (equal? ca "green")) (equal? cb "ivory")))
(list (format "color~a" idx) (format "color~a" (add1 idx))))
(send ep add-constraint
(λ(c) (not (equal? c "green")))
(list (format "color~a" idx))))
(send ep add-constraint
(λ(c d) (or (not (equal? c "green")) (equal? d "coffee")))
(list (format "color~a" idx) (format "drink~a" idx)))
(send ep add-constraint
(λ(s p) (or (not (equal? s "oldgold")) (equal? p "snails")))
(list (format "smoke~a" idx) (format "pet~a" idx)))
(send ep add-constraint
(λ(c s) (or (not (equal? c "yellow")) (equal? s "kools")))
(list (format "color~a" idx) (format "smoke~a" idx)))
(when (= idx 3)
(send ep add-constraint
(λ(d) (equal? d "milk"))
(list (format "drink~a" idx))))
(when (= idx 1)
(send ep add-constraint
(λ(n) (equal? n "norwegian"))
(list (format "nationality~a" idx))))
(if (< 1 idx 5)
(send ep add-constraint
(λ(s pa pb) (or (not (equal? s "chesterfields")) (equal? pa "foxes") (equal? pb "foxes")))
(list (format "smoke~a" idx) (format "pet~a" (add1 idx)) (format "pet~a" (sub1 idx))))
(send ep add-constraint
(λ(s p) (or (not (equal? s "chesterfields")) (equal? p "foxes")))
(list (format "smoke~a" idx) (format "pet~a" (if (= idx 1) 2 4)))))
(if (< 1 idx 5)
(send ep add-constraint
(λ(p sa sb) (or (not (equal? p "horses")) (equal? sa "kools") (equal? sb "kools")))
(list (format "pet~a" idx) (format "smoke~a" (add1 idx)) (format "smoke~a" (sub1 idx))))
(send ep add-constraint
(λ(p s) (or (not (equal? p "horses")) (equal? s "kools")))
(list (format "pet~a" idx) (format "smoke~a" (if (= idx 1) 2 4)))))
(send ep add-constraint
(λ(s d) (or (not (equal? s "luckystrike")) (equal? d "orangejuice")))
(list (format "smoke~a" idx) (format "drink~a" idx)))
(send ep add-constraint
(λ(n s) (or (not (equal? n "japanese")) (equal? s "parliaments")))
(list (format "nationality~a" idx) (format "smoke~a" idx)))
(if (< 1 idx 5)
(send ep add-constraint
(λ(n ca cb) (or (not (equal? n "norwegian")) (equal? ca "blue") (equal? cb "blue")))
(list (format "nationality~a" idx) (format "color~a" (add1 idx)) (format "color~a" (sub1 idx))))
(send ep add-constraint
(λ(n c) (or (not (equal? n "norwegian")) (equal? c "blue")))
(list (format "nationality~a" idx) (format "color~a" (if (= idx 1) 2 4)))))
)
(module+ main
(require rackunit)
(define s (time (send ep get-solution)))
(define result
(for*/list ([idx '(1 2 3 4 5)]
[name '("nationality" "color" "drink" "smoke" "pet")])
(define key (format "~a~a" name idx))
(format "~a ~a" key (hash-ref s key))))
(check-equal? result '("nationality1 norwegian"
"color1 yellow"
"drink1 water"
"smoke1 kools"
"pet1 foxes"
"nationality2 ukrainian"
"color2 blue"
"drink2 tea"
"smoke2 chesterfields"
"pet2 horses"
"nationality3 englishman"
"color3 red"
"drink3 milk"
"smoke3 oldgold"
"pet3 snails"
"nationality4 japanese"
"color4 green"
"drink4 coffee"
"smoke4 parliaments"
"pet4 zebra"
"nationality5 spaniard"
"color5 ivory"
"drink5 orangejuice"
"smoke5 luckystrike"
"pet5 dogs")))

@ -1,152 +0,0 @@
#lang racket
(require "main.rkt" "test-classes.rkt")
(require rackunit)
;; ABC problem:
;; what is the minimum value of
;; ABC
;; -------
;; A+B+C
(define abc-problem (new problem%))
(send abc-problem add-variables '("a" "b" "c") (range 1 10))
(define (test-solution s) (let ([a (hash-ref s "a")]
[b (hash-ref s "b")]
[c (hash-ref s "c")])
(/ (+ (* 100 a) (* 10 b) c) (+ a b c))))
(check-hash-items (argmin test-solution (send abc-problem get-solutions))
#hash(("c" . 9) ("b" . 9) ("a" . 1)))
;; quarter problem:
;; 26 coins, dollars and quarters
;; that add up to $17.
(define quarter-problem (new problem%))
(send quarter-problem add-variables '("dollars" "quarters") (range 1 27))
(send quarter-problem add-constraint (λ(d q) (= 17 (+ d (* 0.25 q)))) '("dollars" "quarters"))
(send quarter-problem add-constraint (λ(d q) (= 26 (+ d q))) '("dollars" "quarters"))
(check-hash-items (send quarter-problem get-solution) '#hash(("dollars" . 14) ("quarters" . 12)))
;; coin problem 2
#|
A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?
|#
(define nickel-problem (new problem%))
(send nickel-problem add-variables '(nickels dimes quarters) (range 1 34))
(send nickel-problem add-constraint (λ(n d q) (= 33 (+ n d q))) '(nickels dimes quarters))
(send nickel-problem add-constraint (λ(n d q) (= 3.30 (+ (* 0.05 n) (* 0.1 d) (* 0.25 q)))) '(nickels dimes quarters))
(send nickel-problem add-constraint (λ(n q) (= n (* 3 q))) '(nickels quarters))
(send nickel-problem add-constraint (λ(d n) (= n (* 2 d))) '(dimes nickels))
(check-hash-items (send nickel-problem get-solution) #hash((nickels . 18) (quarters . 6) (dimes . 9)))
;; word math
#|
# Assign equal values to equal letters, and different values to
# different letters, in a way that satisfies the following sum:
#
# TWO
# + TWO
# -----
# FOUR
|#
(define two-four-problem (new problem%))
(send two-four-problem add-variables '(t w o f u r) (range 10))
(send two-four-problem add-constraint (new all-different-constraint%))
(send two-four-problem add-constraint (λ(t w o) (> (word-value t w o) 99)) '(t w o))
(send two-four-problem add-constraint (λ(f o u r) (> (word-value f o u r) 999)) '(f o u r))
(send two-four-problem add-constraint
(λ (t w o f u r)
(let ([two (word-value t w o)]
[four (word-value f o u r)])
((two . + . two) . = . four))) '(t w o f u r))
(check-equal? (length (send two-four-problem get-solutions)) 7)
(send two-four-problem add-constraint (λ(r) (= r 0)) '(r))
(check-hash-items (send two-four-problem get-solution) #hash((o . 5) (w . 6) (u . 3) (f . 1) (r . 0) (t . 7)))
;; xsum
#|
# 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
#
|#
(define xsum (new problem%))
(send xsum add-variables '(l1 l2 l3 l4 r1 r2 r3 r4 x) (range 10))
(send xsum add-constraint (λ (l1 l2 l3 l4 x)
(and (< l1 l2 l3 l4)
(= 27 (+ l1 l2 l3 l4 x)))) '(l1 l2 l3 l4 x))
(send xsum add-constraint (λ (r1 r2 r3 r4 x)
(and (< r1 r2 r3 r4)
(= 27 (+ r1 r2 r3 r4 x)))) '(r1 r2 r3 r4 x))
(send xsum add-constraint (new all-different-constraint%))
(check-equal? (length (send xsum get-solutions)) 8)
;; send more money problem
#|
# Assign equal values to equal letters, and different values to
# different letters, in a way that satisfies the following sum:
#
# SEND
# + MORE
# ------
# MONEY
|#
(define smm (new problem%))
(send smm add-variables '(s e n d m o r y) (range 10))
(send smm add-constraint (λ(x) (> x 0)) '(s))
(send smm add-constraint (λ(x) (> x 0)) '(m))
(send smm add-constraint (λ(d e y) (= (modulo (+ d e) 10) y)) '(d e y))
(send smm add-constraint (λ(n d r e y)
(= (modulo (+ (word-value n d) (word-value r e)) 100)
(word-value e y))) '(n d r e y))
(send smm add-constraint (λ(e n d o r y)
(= (modulo (+ (word-value e n d) (word-value o r e)) 1000) (word-value n e y))) '(e n d o r y))
(send smm add-constraint (λ(s e n d m o r y) (=
(+ (word-value s e n d)
(word-value m o r e))
(word-value m o n e y))) '(s e n d m o r y))
#;(send smm add-constraint (new all-different-constraint%))
(send smm add-constraint (λ xs (= (length (remove-duplicates xs)) (length xs))) '(s e n d m o r y))
(check-hash-items (send smm get-solution) '#hash((m . 1) (e . 5) (r . 8) (n . 6) (y . 2) (o . 0) (d . 7) (s . 9)))
;; queens problem
;; place queens on chessboard so they do not intersect
(define queens-problem (new problem%))
(define cols (range 8))
(define rows (range 8))
(send queens-problem add-variables cols rows)
(for* ([col1 (in-list cols)] [col2 (in-list cols)] #:when (< col1 col2))
(send queens-problem add-constraint (λ(row1 row2 [col1 col1][col2 col2])
(and
;; test if two cells are on a diagonal
(not (= (abs (- row1 row2)) (abs (- col1 col2))))
;; test if two cells are in same row
(not (= row1 row2)))) (list col1 col2)))
(check-equal? (length (send queens-problem get-solutions)) 92)
(module+ main
(displayln "Tests passed"))

@ -1,17 +0,0 @@
#lang racket/base
(require racket/class "helper.rkt")
(provide (all-defined-out))
(define variable%
(class* object% (printable<%>)
(super-new)
(define (repr) (format "<variable% ~a>" _name))
(define/public (custom-print out quoting-depth) (print (repr) out))
(define/public (custom-display out) (displayln (repr) out))
(define/public (custom-write out) (write (repr) out))
(init-field name)
(field [_name name])))
(define variable%? (is-a?/c variable%))
(define Unassigned (new variable% [name "Unassigned"]))

@ -1,8 +0,0 @@
<?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>

@ -1,23 +0,0 @@
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.

@ -1,2 +0,0 @@
include constraint.py setup.py setup.cfg README LICENSE MANIFEST.in
recursive-include examples *.py *.mask

@ -1,13 +0,0 @@
Metadata-Version: 1.0
Name: python-constraint
Version: 1.2
Summary: Python module for handling Constraint Solving Problems
Home-page: http://labix.org/python-constraint
Author: Gustavo Niemeyer
Author-email: gustavo@niemeyer.net
License: Simplified BSD
Description:
python-constraint is a module implementing support for handling CSPs
(Constraint Solving Problems) over finite domains.
Platform: UNKNOWN

@ -1 +0,0 @@
See http://labix.org/constraint

File diff suppressed because it is too large Load Diff

@ -1,30 +0,0 @@
#!/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))
print min(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 minvalue
print minsolution
if __name__ == "__main__":
main()

@ -1,30 +0,0 @@
#!/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.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()
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()

@ -1,153 +0,0 @@
#!/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]))

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

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

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

@ -1,8 +0,0 @@
#
#
#########
# #
# # # #
##### # #
# # #
#########

@ -1,201 +0,0 @@
#!/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()

@ -1,190 +0,0 @@
#!/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()

@ -1,47 +0,0 @@
#!/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)

@ -1,49 +0,0 @@
#!/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)

@ -1,39 +0,0 @@
#!/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()

@ -1,61 +0,0 @@
#
# 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

@ -1,32 +0,0 @@
#!/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()

@ -1,34 +0,0 @@
#!/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()

@ -1,28 +0,0 @@
#!/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()

@ -1,37 +0,0 @@
#!/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()

@ -1,6 +0,0 @@
[bdist_rpm]
doc_files = README
use_bzip2 = 1
[sdist]
formats = bztar

@ -1,21 +0,0 @@
#!/usr/bin/python
from distutils.core import setup
import os
if os.path.isfile("MANIFEST"):
os.unlink("MANIFEST")
setup(name="python-constraint",
version = "1.2",
description = "Python module for handling Constraint Solving Problems",
author = "Gustavo Niemeyer",
author_email = "gustavo@niemeyer.net",
url = "http://labix.org/python-constraint",
license = "Simplified BSD",
long_description =
"""
python-constraint is a module implementing support for handling CSPs
(Constraint Solving Problems) over finite domains.
""",
py_modules = ["constraint"],
)

@ -1,13 +0,0 @@
#!/usr/bin/python
from constraint import *
#p = Problem()
#p.addVariable("ab", [1, 2])
#p.addVariable("c", [3])
#print p.getSolutions()
problem = Problem()
problem.addVariables(["a", "b"], [1, 2])
problem.addConstraint(AllDifferentConstraint())
print problem.getSolutions()

@ -1,29 +0,0 @@
#!/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))
results = []
for solution in problem.getSolutions():
a = solution["a"]
b = solution["b"]
c = solution["c"]
results.append((((a*100) + (b*10) + c) / (a + b + c + 0.0), (a*100) + (b*10) + c))
results.sort()
print results[0]
if __name__ == "__main__":
main()

@ -1,30 +0,0 @@
#!/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

@ -1,153 +0,0 @@
#!/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]))

@ -1,201 +0,0 @@
#!/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()

@ -1,190 +0,0 @@
#!/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()

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

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

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

@ -1,47 +0,0 @@
#!/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)

@ -1,49 +0,0 @@
#!/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)

@ -1,32 +0,0 @@
#!/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()

@ -1,34 +0,0 @@
#!/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()

@ -1,8 +0,0 @@
#
#
#########
# #
# # # #
##### # #
# # #
#########

@ -1,39 +0,0 @@
#!/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()

@ -1,61 +0,0 @@
#
# 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

@ -1,28 +0,0 @@
#!/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()

@ -1,37 +0,0 @@
#!/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