def solve_grid(grid, unknownVariableSymbol=0): """ Function to solve a sudoku grid with constraint logic programming. Only supports classic sudoku grids. :param grid: (np.array(9,9)) the sudoku grid to be solved. :param unknownVariableSymbol: (str, or 0) the symbol that was used to indicate an unknown value in the sudoku grid. :return: a numpy array of shape (9,9), i.e. the solved sudoku grid. """ # Sanity checks assert type( grid ) == np.ndarray, '\'grid\' should be a numpy.ndarray of shape (9,9)' assert grid.shape == ( 9, 9), '\'grid\' should be a numpy.ndarray of shape (9,9)' if type(unknownVariableSymbol) == int: assert not 1 <= unknownVariableSymbol <= 9, '\'unknownVariableSymbol\' should not be between 1 and 9' if unknownVariableSymbol != 0: grid[grid == unknownVariableSymbol] = 0 grid = grid.astype(int) sudoku = clp.Problem() # Introducing 81 variables. Each variable is represented by a number between [1; 81] and # can take a value between [1; 9]. variablesGrid = np.arange(1, 82).reshape((9, 9)) possibleValues = np.arange(1, 10, dtype=int) sudoku.addVariables(variablesGrid.flatten(), possibleValues.tolist()) # Fix values for known variables knownVariables = np.nonzero(grid) for i, j in zip(knownVariables[0], knownVariables[1]): sudoku._variables.pop(variablesGrid[i][j]) sudoku.addVariable(variablesGrid[i][j], [grid[i][j]]) # Adding constraints for each row for row in variablesGrid: sudoku.addConstraint(clp.AllDifferentConstraint(), row.tolist()) # Adding constraints for each column for col in variablesGrid.T: sudoku.addConstraint(clp.AllDifferentConstraint(), col.tolist()) # Adding constraints for each sub-grid for i in range(0, 7, 3): for j in range(0, 7, 3): sudoku.addConstraint( clp.AllDifferentConstraint(), variablesGrid[i:i + 3, j:j + 3].flatten().tolist()) # The solution is returned as a dictionary where each (key, value) pair is a (Variable, Value) pair solutionDic = sudoku.getSolution() solution = [solutionDic[key] for key in variablesGrid.flatten()] return np.reshape(solution, (9, 9))
def findmatch(self): solutions = [] for i in range(len(self.date)): temp = [] var = [] for man in self.workers: if man.day.__contains__(i + 1): rank = [j for j in man.regions] var += [(str(man._index) + "," + str(i + 1), rank)] # getting permutation of worker. # for example for 10 worker and 6 regions we will check all combination of 6 from 10. comb = combinations(var, len(self.regions)) for p in comb: problem = constraint.Problem() for permutation in p: problem.addVariable(permutation[0], permutation[1]) problem.addConstraint(constraint.AllDifferentConstraint()) temp += problem.getSolutions() if len(temp) == 0: return None solutions += [temp] if len(solutions) == 0: return None return self._find_opt(solutions)
def buildProblem(N): problem = constraint.Problem() problem.addVariables(range(1, N + 1), range(1, N + 1)) problem.addConstraint(constraint.AllDifferentConstraint()) addDiagonalConstraints(problem, xrange(1, N + 1)) return problem
def p2(): valid_tickets = [ list(map(int, x.split(','))) for x in near_tx[1:] if is_valid(x)[0] ] field_names = list(validators.keys()) W = len(field_names) p = constraint.Problem() p.addVariables(["col_" + str(i) for i in range(W)], range(W)) p.addConstraint(constraint.AllDifferentConstraint()) for col in range(W): p.addConstraint(AllValidConstraint(valid_tickets, col), ["col_" + str(col)]) soln = p.getSolution() def sorter(kv): return int(kv[0].split('_')[1]) your_t = 1 your_ticket = map(int, your_tx[1].split(',')) for val, (col, field) in zip(your_ticket, sorted(soln.items(), key=sorter)): if field_names[field].startswith('departure'): # print(f'({col})', field_names[field], '=', val) your_t *= val print(your_t) return your_t
def single_1d_gray_code(n=DEFAULT_N, m=None, do_print=True, looping=True): """return a single length-n code of m-bit binary numbers such that each adjacent numbers in the code share all but one bit in their binary representations, i.e. are valid Gray code transitions""" if m is None: m = n all_keys = get_unique_variables(n) format_flag = '0%ib' % m problem = constraint.Problem() problem.addVariables(all_keys[:2**n], range(2**m)) problem.addConstraint(constraint.AllDifferentConstraint()) for i in range(2**n - 1): problem.addConstraint(lambda a, b: valid_neighbors(a, b, format_flag), (all_keys[i], all_keys[i + 1])) problem.addConstraint(lambda a: a == 0, (all_keys[0])) if looping: # only one bit switch from last to first code value problem.addConstraint(lambda a, b: valid_neighbors(a, b, format_flag), (all_keys[0], all_keys[2**n - 1])) else: # go from start to end of range, e.g., 000 --- 111 problem.addConstraint(lambda a: a == 2**n - 1, (all_keys[2**n - 1])) soln = problem.getSolution() if do_print: print('soln') for i, key in enumerate(soln.keys()): print('%i | %s' % (i, format(soln[all_keys[i]], format_flag))) return numeric_soln(soln, all_keys)
def solve(S): problem = constraint.Problem() #name the circles as A,B,C,D,E,F FROM 1-6 problem.addVariable(("A"), range(1, 7)) problem.addVariable(("B"), range(1, 7)) problem.addVariable(("C"), range(1, 7)) problem.addVariable(("D"), range(1, 7)) problem.addVariable(("E"), range(1, 7)) problem.addVariable(("F"), range(1, 7)) #this method is used for sum of each side so that each side has same sum def sum1(a, b, c, d, e, f): if (a + b + c == c + d + e == S and c + d + e == e + f + a == S and a + b + c == e + f + a == S): return True problem.addConstraint(sum1, "ABCDEF") problem.addConstraint( constraint.AllDifferentConstraint()) #each circle got distinct number solutions = problem.getSolutions() #get solution return solutions
def solve(self): """ Solves the sudoku. This will replace the empty cells in this sudoku with the solutions. """ problem = constraint.Problem() all_different = constraint.AllDifferentConstraint() for i, n in enumerate(self.grid): problem.addVariable(i, range(1, self.size + 1) if n == 0 else [n]) _s = Sudoku(range(len(self.grid))) for row in _s.rows: problem.addConstraint(all_different, row) for col in _s.columns: problem.addConstraint(all_different, col) for block in _s.blocks: problem.addConstraint(all_different, block) solution = problem.getSolution() if solution: self.grid = solution.values() else: raise ValueError('No solutions found')
def p(n): p = constraint.Problem() p.addVariables(range(n), N) p.addConstraint(constraint.AllDifferentConstraint()) p.addConstraint(constraint.ExactSumConstraint(2020)) try: print(prod(p.getSolution().values())) except: print("")
def __createBasicCSP(self): self.__cspVariablesStrings = [] cspProblem = constraint.Problem() cspVariablesIntervals = list(range(self.__numberOfColors)) for count in range(self.__lengthOfGuess): newVariable = "c_" + str(count) self.__cspVariablesStrings.append(newVariable) cspProblem.addVariable(newVariable, cspVariablesIntervals) cspProblem.addConstraint(constraint.AllDifferentConstraint()) cspProblem.setSolver(self.cspSolvingStrategy) return cspProblem
def create_add_problem(addend, summ): if type(addend) is not list or type(addend[0]) is not str: raise TypeError('addend must be a list of strings') problem = constraint.Problem() variables = _get_variable_list(addend, summ) problem = _add_vars_to_problem(problem, variables) problem.addConstraint(constraint.AllDifferentConstraint()) problem = _generate_constraints(problem, addend, summ) return problem
def __init__(self, graph, list_assignment): """ XXX doc XXX """ self.graph = graph self.list_assignment = list_assignment self.problem = constraint.Problem() for node in self.graph.nodes(): self.problem.addVariable(node, self.list_assignment.get(node)) for edge in self.graph.edges(): self.problem.addConstraint(constraint.AllDifferentConstraint(), edge)
def q2(): n = 4 p = constraint.Problem() var_names = list(range(1, n + 1)) var_domaines = ["rouge", "vert", "bleu"] p.addVariables(var_names, var_domaines) adjacences = [(1, 2), (1, 3), (1, 4), (2, 3), (3, 4)] for x, y in adjacences: p.addConstraint(constraint.AllDifferentConstraint(), [x, y]) return p.getSolutions()
def cstAdd(problem, grid, domains, psize): # -------------------- # Your code # print grid, psize numCol = grid.shape[0] numRow = grid.shape[1] # For Row Constraint for row in range(numRow): rowConstraintMatrix = [grid[row, i] for i in range(numCol)] # print rowConstraintMatrix problem.addConstraint(constraint.AllDifferentConstraint(), rowConstraintMatrix) # For Column Constraints for col in range(numCol): colConstraintMatrix = [grid[i, col] for i in range(numRow)] # print colConstraintMatrix problem.addConstraint(constraint.AllDifferentConstraint(), colConstraintMatrix) # For Box Constraitns using step feature in range(i,j,step) for row in range(0, numRow, psize): for col in range(0, numCol, psize): boxConstraintMatrix = [grid[i, j] for i in range(row, row + psize) for j in range(col, col + psize)] # print boxConstraintMatrix problem.addConstraint(constraint.AllDifferentConstraint(), boxConstraintMatrix) pass
def create_csp_problem(self, solver=constraint.BacktrackingSolver(), symmetry_break=False): p = constraint.Problem(solver) p.addVariables(self.rows(), self.cols()) p.addConstraint(constraint.AllDifferentConstraint(), self.rows()) self.add_diag_left_constraints(p) self.add_diag_right_constraints(p) if symmetry_break: #self.add_axes_sym_constraints(p) #self.add_rotation_sym_constraints(p) self.sym_constraints(p) return p
def decompose(self): def sum_eq(a, b, c): return tuple(map(add, a, b)) == c length = ceil(log(len(self.P), 2)) configs = cartesian([0, 1], repeat=length) prob = constraint.Problem() prob.addVariables(self.P, list(configs)) prob.addConstraint(constraint.AllDifferentConstraint()) for p1 in self.table: for p2 in self.table[p1]: prob.addConstraint(sum_eq, (p1, p2, self.table[p1][p2])) return prob.getSolution()
def main(): ops = [addi, addr, muli, mulr, banr, bani, borr, bori, setr, seti, gtir, gtri, gtrr, eqir, eqri, eqrr, ] opcodesp1 = {opcode: ops[:] for opcode in range(16)} opcodes = {opcode: ops[:] for opcode in range(16)} lines = list(fileinput.input())[::-1] lines = [line[:-1] for line in lines] p1 = 0 while lines: beforeline = lines.pop() if not beforeline: break before = literal_eval(''.join(beforeline.split()[1:])) regline = lines.pop() op = list(map(int, regline.split(' '))) afterline = lines.pop() after = literal_eval(''.join(afterline.split()[1:])) lines.pop() # delimiting blank line opcodes[op[0]] = limitop(opcodes[op[0]], before, op, after) remaining = opcodesp1[op[0]] if len(remaining) >= 3: p1 += 1 p = constraint.Problem() p.addConstraint(constraint.AllDifferentConstraint()) for opcode, ops in opcodes.items(): p.addVariable(opcode, ops) opcodes = p.getSolution() print('part1:', p1) while not lines[-1]: lines.pop() instructions = lines[::-1] reg = [0, 0, 0, 0] for ins in instructions: opcode, a, b, c = map(int, ins.split(' ')) opcodes[opcode](reg, a, b, c) print('part2:', reg)
def calculate(connections): g = nx.DiGraph(name='Connections') edges = [(src[0], dst[0]) for (dst, src) in connections.items()] g.add_edges_from(edges) def other_bigger(this, *others): return all(this < other for other in others) def other_bigger_or_smaller(this, *others): otherSmaller = all(this > other for other in others) return otherSmaller or other_bigger(this, *others) problem = constraint.Problem() variables = g.nodes() problem.addVariables(variables, range(len(variables))) problem.addConstraint(constraint.AllDifferentConstraint()) others = [this for this in variables if g.in_edges(this)] for this in variables: if not g.in_edges(this): problem.addConstraint(other_bigger, [this] + others) for this in variables: others = [other for other, _ in g.in_edges(this)] problem.addConstraint(other_bigger_or_smaller, [this] + others) solutions = problem.getSolutions() def feedback(solution): return tuple((src, dst) for src, dst in g.edges() if solution[src] > solution[dst]) feedbacks = map(feedback, solutions) minFeedback = min(map(len, feedbacks)) uniqueFeedbacks = set(feedback for feedback in feedbacks if len(feedback) == minFeedback) filteredSolutions = [] for feedback in uniqueFeedbacks: idx = feedbacks.index(feedback) solution = sorted(solutions[idx].items(), key=itemgetter(1)) filteredSolutions.append(tuple(map(itemgetter(0), solution))) return filteredSolutions
def p4(): # CRASH + ERROR + REBOOT = HACKER problem = constraint.Problem() problem.addVariables("CERH", range(1, 10)) problem.addVariables("ASOBTK", range(10)) def sum_constraints(c, r, a, s, h, e, o, b, t, k): if (10000 * c + 1000 * r + 100 * a + 10 * s + h + 10000 * e + 1000 * r + 100 * r + 10 * o + r + 100000 * r + 10000 * e + 1000 * b + 100 * o + 10 * o + t == 100000 * h + 10000 * a + 1000 * c + 100 * k + 10 * e + r): return True problem.addConstraint(sum_constraints, "CRASHEOBTK") problem.addConstraint(constraint.AllDifferentConstraint()) solutions = problem.getSolution() # .getSolutions() returns a dictionary print(*solutions.items(), sep='\n') return solutions
def p2(): # two + two = four problem = constraint.Problem() problem.addVariables("TF", range(1, 10)) problem.addVariables("WOUR", range(10)) # Telling Python that we need TWO + TWO = FOUR def sum_constraint(t, w, o, f, u, r): if 2 * (t * 100 + w * 10 + o) == f * 1000 + o * 100 + u * 10 + r: return True problem.addConstraint(sum_constraint, "TWOFUR") problem.addConstraint(constraint.AllDifferentConstraint()) solutions = problem.getSolutions() print("Number of solutions found: {}\n".format(len(solutions))) # .getSolutions() returns a dictionary for s in solutions: print("T = {}, W = {}, O = {}, F = {}, U = {}, R = {}".format( s['T'], s['W'], s['O'], s['F'], s['U'], s['R']))
def single_2d_gray_code(n=DEFAULT_N, m=None, do_print=True, looping=True): """return a single n-by-n code of m-bit binary numbers such that each adjacent numbers in the n-by-n square share all but one bit in their binary representations, i.e. are valid Gray code transitions""" if m is None: m = n format_flag = '0%ib' % m problem = constraint.Problem() symbols, values = square_variables(n=n, m=m) problem.addVariables(symbols.values(), values) problem.addConstraint(constraint.AllDifferentConstraint()) constrs = square_constraints(symbols=symbols, n=n, format_flag=format_flag) for constr in constrs: problem.addConstraint(*constr) soln = problem.getSolution() if do_print: print('soln') for i in range(n): for j in range(n): key = '(%i, %i)' % (i, j) print('%s | %s' % (key, format(soln[key], format_flag))) return soln
def pick_correct_long_note_candidates( arrow_to_note_candidates: Candidates, bloc: List[List[str]], ) -> Solution: """Believe it or not, assigning each arrow to a valid note candidate involves whipping out a CSP solver. Returns an arrow_pos -> note_pos mapping """ problem = constraint.Problem() for arrow_pos, note_candidates in arrow_to_note_candidates.items(): problem.addVariable(arrow_pos, list(note_candidates)) problem.addConstraint(constraint.AllDifferentConstraint()) solutions: List[Solution] = problem.getSolutions() if not solutions: raise SyntaxError("Impossible arrow pattern found in block :\n" + "\n".join("".join(line) for line in bloc)) solution = min(solutions, key=long_note_solution_heuristic) if len(solutions) > 1 and not is_simple_solution(solution, arrow_to_note_candidates): warnings.warn("Ambiguous arrow pattern in bloc :\n" + "\n".join("".join(line) for line in bloc) + "\n" "The resulting long notes might not be what you expect") return solution
def add_col_constraints(problem, boxsize): """add_col_constraints(problem, boxsize) Adds to constraint problem 'problem', all_different constraints on columns.""" for col in cells_by_col(boxsize): problem.addConstraint(constraint.AllDifferentConstraint(), col)
def add_row_constraints(problem, boxsize): """add_row_constraints(problem, boxsize) Adds to constraint problem 'problem', all_different constraints on rows.""" for row in cells_by_row(boxsize): problem.addConstraint(constraint.AllDifferentConstraint(), row)
def ensure_unique_values(varnames): # we don't want variable names to interfere with values, # so we convert them to strings problem.addConstraint(constraint.AllDifferentConstraint(), map(str, varnames))
# Insert all elements of both dictionaries with its corresponding domains into the python constraint problem for key, value in subjects.items(): problem.addVariable(key, value) for key, value in teachers.items(): problem.addVariable(key, value) # Avoid duplication of solutions problem.addConstraint(no_duplicated_subjects, ('NSC1', 'NSC2', 'HSC1', 'HSC2', 'SP1', 'SP2', 'MAT1', 'MAT2', 'EN1', 'EN2', 'EN3')) problem.addConstraint(no_duplicated_teachers, ('AND1', 'AND2', 'JUA1', 'JUA2', 'LUC1', 'LUC2')) # All subjects must be in different time slots problem.addConstraint(constraint.AllDifferentConstraint(), [*subjects.keys()]) # Human & social science class must be consecutive problem.addConstraint(is_consecutive, ('HSC1', 'HSC2')) # MAT-NSC & MAT-EN cannot be taught on the same day problem.addConstraint(is_not_on_the_same_day, ('MAT1', 'MAT2', 'NSC1', 'NSC2', 'EN1', 'EN2', 'EN3')) # English classes can't be on the same day problem.addConstraint(en_is_not_on_the_same_day, ('EN1', 'EN2', 'EN3')) # All teachers must lecture different subjects problem.addConstraint(constraint.AllDifferentConstraint(), [*teachers.keys()]) # LUC will lecture HSC provided that AND takes care of PE
def add_edge_constraint(self, problem): for i, j in self.edges: problem.addConstraint(constraint.AllDifferentConstraint(), [i, j])
import constraint problem = constraint.Problem() problem.addVariables('TF', range(1, 10)) problem.addVariables('WOUR', range(10)) problem.addConstraint(constraint.AllDifferentConstraint()) problem.addConstraint( lambda t, f, w, o, u, r: 2*(100*t + 10*w + o) == 1000*f + 100*o + 10*u + r, 'TFWOUR' ) for solution in problem.getSolutions(): print(solution)
def add_box_constraints(problem, boxsize): """add_box_constraints(problem, boxsize) Adds to constraint problem 'problem', all_different constraints on boxes.""" for box in cells_by_box(boxsize): problem.addConstraint(constraint.AllDifferentConstraint(), box)
# 1 - - - - - - - - - # 1 2 3 4 5 6 7 8 9 # import constraint import json problem = constraint.Problem() # Dodajemo promenljive za svaki red i njihove vrednosti 1-9 for i in range(1, 10): problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10)) # Dodajemo ogranicenja da se u svakoj vrsti nalaze razlicite vrednosti for i in range(1, 10): problem.addConstraint(constraint.AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10)) # Dodajemo ogranicenja da se u svakoj koloni nalaze razlicite vrednosti for i in range(1, 10): problem.addConstraint(constraint.AllDifferentConstraint(), range(10 + i, 100 + i, 10)) # Dodajemo ogranicenja da svaki podkvadrat od 3x3 promenljive ima razlicite vrednosti for i in [1,4,7]: for j in [1,4,7]: pozicije = [10*i+j,10*i+j+1,10*i+j+2,10*(i+1)+j,10*(i+1)+j+1,10*(i+1)+j+2,10*(i+2)+j,10*(i+2)+j+1,10*(i+2)+j+2] problem.addConstraint(constraint.AllDifferentConstraint(),pozicije) ime_datoteke = input("Unesite ime datoteke sa tablom za sudoku: ") f = open(ime_datoteke, "r") tabla = json.load(f)
# 9 - - - - - - - - - # 1 2 3 4 5 6 7 8 9 import constraint import json problem = constraint.Problem() # We're letting VARIABLES 11 through 99 have an interval of [1..9] for i in range(1, 10): problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10)) # We're adding the constraint that all values in a row must be different # 11 through 19 must be different, 21 through 29 must be all different,... for i in range(1, 10): problem.addConstraint(constraint.AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10)) # Also all values in a column must be different # 11,21,31...91 must be different, also 12,22,32...92 must be different,... for i in range(1, 10): problem.addConstraint(constraint.AllDifferentConstraint(), range(10 + i, 100 + i, 10)) # The last rule in a sudoku 9x9 puzzle is that those nine 3x3 squares must have all different values, # we start off by noting that each square "starts" at row indices 1, 4, 7 for i in [1, 4, 7]: # Then we note that it's the same for columns, the squares start at indices 1, 4, 7 as well # basically one square starts at 11, the other at 14, another at 41, etc for j in [1, 4, 7]: square = [