示例#1
0
"""
See http://en.wikibooks.org/wiki/Puzzles/Arithmetical_puzzles/Digits_of_the_Square

There is one four-digit whole number x, such that the last four digits of x^2
are in fact the original number x. What is it?
"""

import satx

satx.engine(30, cnf_path='aux.cnf')

# x is the number we look for
x = satx.integer()

# d[i] is the ith digit of x
d = satx.vector(size=4)

satx.apply_single(d, lambda t: t.is_in(range(10)))

assert 1000 <= x < 10000
assert satx.dot(d, [1000, 100, 10, 1]) == x
assert (x * x) % 10000 == x

if satx.satisfy('slime'):
    print(x, d)
else:
    print('Infeasible...')
示例#2
0
"""
Dad wants one-cent, two-cent, three-cent, five-cent, and ten-cent stamps.
He said to get four each of two sorts and three each of the others, but I've
forgotten which. He gave me exactly enough to buy them; just these dimes."
How many stamps of each type does Dad want? A dime is worth ten cents.
-- J.A.H. Hunter
"""

import satx

satx.engine(10, cnf_path='aux.cnf')

# x is the number of dimes
x = satx.integer()

# s[i] is the number of stamps of value 1, 2, 3, 5 and 10 according to i
s = satx.vector(size=5)

satx.apply_single(s, lambda t: t.is_in([3, 4]))

# 26 is a safe upper bound
assert x <= 26

assert satx.dot(s, [1, 2, 3, 5, 10]) == x * 10

while satx.satisfy('slime'):
    print(s, x)
示例#3
0
There are 5 non trivial numbers for base 10, and the highest such number is formed of 5 digits.
Below, the model is given for base 10.
"""

from math import ceil

import satx

# for base 10
n_digits = 5

satx.engine((10**n_digits).bit_length(), cnf_path='aux.cnf')

# n is a (non-trivial) Dudeney number
n = satx.integer()
# s is the perfect cubic root of n
s = satx.integer()
# d[i] is the ith digit of the Dudeney number
d = satx.vector(size=n_digits)

satx.apply_single(d, lambda t: t < 10)

assert 2 <= n < 10**n_digits
assert s < ceil((10**n_digits)**(1 / 3)) + 1
assert n == s * s * s
assert sum(d) == s
assert satx.dot(d, [10**(n_digits - i - 1) for i in range(n_digits)]) == n

while satx.satisfy('slime'):
    print(n, s, d)
示例#4
0
"""
See https://en.wikipedia.org/wiki/Verbal_arithmetic

A model for a general form of this problem is in CryptoPuzzle.py
"""

import satx

satx.engine(16, cnf_path='aux.cnf')

# letters[i] is the digit of the ith letter involved in the equation
s, e, n, d, m, o, r, y = letters = satx.vector(size=8)

satx.apply_single(letters, lambda t: t < 10)

# letters are given different values
satx.all_different(letters)

# words cannot start with 0
assert s > 0
assert m > 0

# respecting the mathematical equation
assert satx.dot([s, e, n, d], [1000, 100, 10, 1]) + satx.dot([m, o, r, e], [1000, 100, 10, 1]) == satx.dot([m, o, n, e, y], [10000, 1000, 100, 10, 1])

if satx.satisfy('slime'):
    print(letters)
else:
    print('Infeasible...')
示例#5
0
"""
Problem 016 on CSPLib
"""

import satx

satx.engine(32, cnf_path='aux.cnf')

mapping = {1: 'r', 2: 'ry', 3: 'g', 4: 'y'}

R, RY, G, Y = 1, 2, 3, 4

table = [(R, R, G, G), (RY, R, Y, R), (G, G, R, R), (Y, R, RY, R)]

# v[i] is the color for the ith vehicle traffic light
v = satx.vector(size=4)
# p[i] is the color for the ith pedestrian traffic light
p = satx.vector(size=4)

satx.apply_single(v, lambda t: t.is_in([R, RY, G, Y]))
satx.apply_single(p, lambda t: t.is_in([R, G]))

for i in range(4):
    assert satx.dot([v[i], p[i], v[(i + 1) % 4], p[(i + 1) % 4]],
                    [1, 10, 100, 1000]) == satx.one_of(
                        [satx.dot(t, [1, 10, 100, 1000]) for t in table])

while satx.satisfy('kissat'):
    vv = [mapping[t.value] for t in v]
    pp = [mapping[t.value] for t in p]
    for a, b in zip(vv, pp):
示例#6
0
       d4 - d6   =   d7
  d1 * d2 * d3   =   d8 + d9
  d2 + d3 + d6   <   d8
            d9   <   d8
  d1 <> 1, d2 <> 2, ..., d9 <> 9

Can you find the correct combination?
"""

import satx

satx.engine(10, cnf_path='aux.cnf')

# x[i] is the i(+1)th digit
x = satx.vector(size=9)

satx.apply_single(x, lambda t: t.is_in(range(10)))

satx.all_different(x)

assert x[3] - x[5] == x[6]
assert x[0] * x[1] * x[2] == x[7] + x[8]
assert x[1] + x[2] + x[5] < x[7]
assert x[8] < x[7]

if satx.satisfy('slime'):
    print(x)
else:
    print('Infeasible...')
示例#7
0
"""
See https://en.wikipedia.org/wiki/Change-making_problem
"""

import satx

k = 13
coins = [1, 5, 10, 20, 50, 100, 200]

opt = k
while True:
    satx.engine(sum(coins).bit_length(), cnf_path='aux.cnf')

    x = satx.vector(size=len(coins))

    assert satx.dot(x, coins) == k

    assert sum(x) < opt

    if satx.satisfy('slime'):
        opt = sum(x)
        print(opt, x)
    else:
        break