""" 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...')
""" 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)
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)
""" 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...')
""" 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):
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...')
""" 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