def n_queens(n: int, *args, **kwargs) -> facile.Solution: queens = [facile.variable(range(n)) for i in range(n)] diag1 = [queens[i] + i for i in range(n)] diag2 = [queens[i] - i for i in range(n)] facile.constraint(facile.alldifferent(queens)) facile.constraint(facile.alldifferent(diag1)) facile.constraint(facile.alldifferent(diag2)) return facile.solve(queens, *args, **kwargs)
def n_queen(n): """Solves the n-queen problem. """ queens = [variable(0, n - 1) for i in range(n)] diag1 = [queens[i] + i for i in range(n)] diag2 = [queens[i] - i for i in range(n)] constraint(alldifferent(queens)) constraint(alldifferent(diag1)) constraint(alldifferent(diag2)) if solve(queens): return [x.value() for x in queens] else: return None
def n_queen(n): """Solves the n-queen problem. """ queens = [variable(0, n-1) for i in range(n)] diag1 = [queens[i] + i for i in range(n)] diag2 = [queens[i] - i for i in range(n)] constraint(alldifferent(queens)) constraint(alldifferent(diag1)) constraint(alldifferent(diag2)) if solve(queens): return [x.value() for x in queens] else: return None
def n_queen(n): """Solves the n-queen problem. """ queens = [variable(range(n)) for i in range(n)] # prepare for animation def on_bt(nb_bt): for i, q in enumerate(queens): print(i, q.domain()) constraint(alldifferent(queens)) constraint(alldifferent(queens[i] - i for i in range(n))) constraint(alldifferent(queens[i] + i for i in range(n))) return solve(queens, strategy=queen_strategy, backtrack=True)
def golomb(n): # On peut majorer la taille de la règle par 2 ** n. En effet, si # ticks[i] vaut 2**i alors tous les ticks[i] - ticks[j] = 2**i - 2**j # = 2**j * (2**(i-j) - 1) qui sont tous différents. # On a donc au moins cette solution. n2 = 2 ** n ticks = [facile.variable(0, n2) for i in range(n)] # First tick at the start of the ruler facile.constraint(ticks[0] == 0) # Ticks are ordered for i in range(n-1): facile.constraint(ticks[i] < ticks[i+1]) # All distances distances = [] for i in range(n-1): for j in range(i + 1, n): distances.append(ticks[j] - ticks[i]) facile.constraint(facile.alldifferent(distances)) for d in distances: facile.constraint(d > 0) # Breaking the symmetry size = len(distances) facile.constraint(distances[size - 1] > distances[0]) return (facile.minimize(ticks, ticks[n-1])[1])
def golomb(n: int) -> facile.Solution: ticks = [facile.variable(range(2**n)) for i in range(n)] # First tick at the start of the ruler facile.constraint(ticks[0] == 0) # Ticks are ordered for i in range(n - 1): facile.constraint(ticks[i] < ticks[i + 1]) # All distances distances = [] for i in range(n - 1): for j in range(i + 1, n): distances.append(facile.variable(ticks[j] - ticks[i])) facile.constraint(facile.alldifferent(distances)) for d in distances: facile.constraint(d > 0) # Breaking the symmetry size = len(distances) facile.constraint(distances[size - 1] > distances[0]) return facile.minimize(ticks, ticks[n - 1], backtrack=True, on_solution=print)
def arithmetic(puzzle="SEND+MORE=MONEY", base=10): problem = re.split("[\s+=]", puzzle) # remove spaces problem = list(filter(lambda w: len(w) > 0, problem)) # letters letters = {l: fcl.variable(range(base)) for l in set("".join(problem))} # expressions expr_pb = [[letters[a] for a in word] for word in problem] words = [reduce(lambda a, b: 10 * a + b, word) for word in expr_pb] # constraints fcl.constraint(fcl.alldifferent(letters.values())) fcl.constraint(sum(words[:-1]) == words[-1]) for word in expr_pb: fcl.constraint(word[0] > 0) assert fcl.solve(letters.values()) # print solutions for word, numbers in zip(problem, expr_pb): strings = [str(n.value()) for n in numbers] print(word + " = " + "".join(strings))
def arithmetic(puzzle="SEND+MORE=MONEY", base=10) -> None: problem = re.split(r"[\s+=]", puzzle) # remove spaces problem = list(filter(lambda w: len(w) > 0, problem)) letters = { letter: facile.variable(range(base)) for letter in set("".join(problem)) } # expressions expr_pb = [[letters[a] for a in word] for word in problem] def horner(a: Expression, b: Expression): return 10 * a + b words = [reduce(horner, word) for word in expr_pb] # constraints facile.constraint(facile.alldifferent(letters.values())) facile.constraint(facile.sum(words[:-1]) == words[-1]) for word in expr_pb: facile.constraint(word[0] > 0) assert facile.solve(letters.values()) # print solutions for word, numbers in zip(problem, expr_pb): strings = [str(n.value()) for n in numbers] print(f"{word} = {''.join(strings)}")
import facile import functools # The list comprehension mechanism is always helpful! [s, e, n, d, m, o, r, y] = [facile.variable(range(10)) for i in range(8)] # A shortcut letters = [s, e, n, d, m, o, r, y] # Constraints facile.constraint(s > 0) facile.constraint(m > 0) facile.constraint(facile.alldifferent(letters)) send = functools.reduce(lambda x, y: 10 * x + y, [s, e, n, d]) more = functools.reduce(lambda x, y: 10 * x + y, [m, o, r, e]) money = functools.reduce(lambda x, y: 10 * x + y, [m, o, n, e, y]) facile.constraint(send + more == money) if facile.solve(letters): [vs, ve, vn, vd, vm, vo, vr, vy] = [x.value() for x in letters] print("Solution found :") print print(" %d%d%d%d" % (vs, ve, vn, vd)) print("+ %d%d%d%d" % (vm, vo, vr, ve)) print("------") print(" %d%d%d%d%d" % (vm, vo, vn, ve, vy)) else: print("No solution found")
# -*- coding: utf-8 -*- """ Basic examples of CSP problems: - a ≠ b - alldifferent(a, b, c) and a + b <= 2c """ from facile import variable, constraint, solve, alldifferent a = variable(0, 1) b = variable(0, 1) constraint(a != b) if solve([a, b]): print("Solution found a=%d and b=%d" % (a.value(), b.value())) a = variable(0, 2) b = variable(0, 2) c = variable(0, 2) constraint(alldifferent([a, b, c])) constraint(a + b <= 2 * c) if solve([a, b, c]): print("Solution found a=%d, b=%d and c=%d" % (a.value(), b.value(), c.value()))
people = [variable(range(1, 6)) for i in range(5)] englishman, spaniard, japanese, ukrainian, norwegian = people names = ["Englishman", "Spaniard", "Japanese", "Ukrainian", "Norwegian"] animals = [variable(range(1, 6)) for i in range(5)] dog, snails, fox, zebra, horse = animals drinks = [variable(range(1, 6)) for i in range(5)] tea, coffee, water, milk, fruit_juice = drinks cigarettes = [variable(range(1, 6)) for i in range(5)] old_gold, kools, chesterfields, lucky_strike, parliaments = cigarettes constraint(alldifferent(colors)) constraint(alldifferent(people)) constraint(alldifferent(animals)) constraint(alldifferent(drinks)) constraint(alldifferent(cigarettes)) constraint(englishman == red) constraint(spaniard == dog) constraint(coffee == green) constraint(ukrainian == tea) constraint(green == ivory + 1) constraint(old_gold == snails) constraint(kools == yellow) constraint(milk == 3) constraint(norwegian == 1) constraint(abs(fox - chesterfields) == 1)
def test_overconstrained() -> None: a, b, c = [facile.variable(0, 1) for _ in range(3)] with pytest.raises(ValueError, match="The problem is overconstrained"): facile.constraint(facile.alldifferent([a, b, c]))
# -*- coding: utf-8 -*- """ Basic examples of CSP problems: - a ≠ b - alldifferent(a, b, c) and a + b <= 2c """ from facile import variable, constraint, solve, alldifferent a = variable(0, 1) b = variable(0, 1) constraint(a != b) if solve([a, b]): print ("Solution found a=%d and b=%d" % (a.value(), b.value())) a = variable(0, 2) b = variable(0, 2) c = variable(0, 2) constraint(alldifferent([a, b, c])) constraint(a + b <= 2 * c) if solve([a, b, c]): print ("Solution found a=%d, b=%d and c=%d" % (a.value(), b.value(), c.value()))