def find_rule3(self, board, do_all = False): naked_solver = NakedSolver(Solver.DOUBLE) for row in range(board.N): for floor in naked_solver.find_in_list(board.get_row(row)): for i, f1 in enumerate(floor): for j, f2 in enumerate(floor): ceils1 = [cell for cell in board.get_col(f1.j) if i != j and cell != f1 and len(set([f1.k, f2.k, cell.k])) == 2 and cell.c.issuperset(f1.c) and len(cell.c - f1.c) == 1] for ceil1 in ceils1: cell = board.get(ceil1.i, f2.j) ceil2 = cell if cell.c.issuperset(f1.c) and len(cell.c - f1.c) == 1 and not cell.c.issuperset(ceil1.c) else None if ceil2: pair = [cell for cell in visible_intersection(board,[ceil1,ceil2]) if cell != f1 and cell != f2 and cell.c == ceil1.c ^ ceil2.c ] if pair: remove = [cell for cell in visible_intersection(board,[ceil1,ceil2,pair[0]]) if cell != f1 and cell != f2 and cell.check_remove(pair[0].c)] if remove: return [SolvedSet(UniqueRectangleSolver(0, Solver.TYPE3), [f1,f2,ceil1,ceil2,pair[0]], pair[0].c, remove)] for col in range(board.N): for floor in naked_solver.find_in_list(board.get_col(col)): for i, f1 in enumerate(floor): for j, f2 in enumerate(floor): ceils1 = [cell for cell in board.get_row(f1.i) if i != j and cell != f1 and len(set([f1.k, f2.k, cell.k])) == 2 and cell.c.issuperset(f1.c) and len(cell.c - f1.c) == 1] for ceil1 in ceils1: cell = board.get(f2.i, ceil1.j) ceil2 = cell if cell.c.issuperset(f1.c) and len(cell.c - f1.c) == 1 and not cell.c.issuperset(ceil1.c) else None if ceil2: pair = [cell for cell in visible_intersection(board,[ceil1,ceil2]) if cell != f1 and cell != f2 and cell.c == ceil1.c ^ ceil2.c ] if pair: remove = [cell for cell in visible_intersection(board,[ceil1,ceil2,pair[0]]) if cell != f1 and cell != f2 and cell.check_remove(pair[0].c)] if remove: return [SolvedSet(UniqueRectangleSolver(0, Solver.TYPE3), [f1,f2,ceil1,ceil2,pair[0]], pair[0].c, remove)] return []
def find_rule5(self, board, chain): ''' twice in a unit ''' for v in chain.root.c: possible = chain.paths[v].subnodes() for i,node1 in enumerate(possible): for j,node2 in enumerate(possible): if j > i and node1.cell != node2.cell and node1.value == node2.value and node1.state != node2.state: removed = [cell for cell in visible_intersection(board, [node1.cell,node2.cell]) if cell.check_remove(set([node1.value]))] if removed: return [SolvedSet(Medusa3DSolver(0, Solver.TYPE5), [node1.cell, node2.cell], set([node1.value]) ,removed)] return []
def find_rule5(self, board, chain): ''' two colors elsewhere ''' for v in chain.root.c: possible = chain.paths[v].subnodes() for i,node1 in enumerate(possible): for j,node2 in enumerate(possible): if j > i and node1.state != node2.state and node1.cell != node2.cell: removed = [cell for cell in visible_intersection(board, [node1.cell,node2.cell]) if cell.check_remove(set([v]))] if removed: return [SolvedSet(SimpleColoringSolver(0, Solver.TYPE5), [node1.cell, node2.cell], set([v]), removed)] return []
def find(self, board, do_all=False): solved_sets = [] possible = has_size(board.as_list(), 2, 2) ywings = [ (pivot, cell1, cell2) for i, cell1 in enumerate(possible) for j, cell2 in enumerate(possible) for pivot in visible_intersection(board, [cell1, cell2]) if j > i and pivot.c == cell1.c ^ cell2.c and len(cell1.c & cell2.c) == 1 ] for pivot, cell1, cell2 in ywings: remove = [ cell for cell in visible_intersection(board, [cell1, cell2]) if cell != pivot and cell.check_remove(cell1.c & cell2.c) ] if remove: solved_sets += [SolvedSet(self, [pivot, cell1, cell2], cell1.c & cell2.c, remove)] if not do_all: return solved_sets return solved_sets
def find_rule1(self, board, chain): '''Continuous Alternating Nice Loop - Weak link => off-chain candidates in same unit are OFF ''' for value in chain.root.c: for leaf in chain.paths[value].get_leaves(): if chain.paths[value].state == leaf.state and leaf.cell == chain.root: solved_sets = [] for node in leaf.supernodes(): if node.parent != None and share_unit(node.cell,node.parent.cell): removed = [cell for cell in visible_intersection(board,[node.cell,node.parent.cell]) if cell.check_remove(set([value]))] if removed: solved_sets += [SolvedSet(XCycleSolver(0, Solver.TYPE1), [node.cell, node.parent.cell], set([value]), removed)] return solved_sets return []
def extend(self, board, root): for leaf in root.get_leaves(): if len(leaf.cell.c) == 2 and not (leaf.value == root.value and leaf.state == 1 and len(visible_intersection(board,[leaf.cell,self.root])) > 0): if not (leaf.parent != None and leaf.cell == root.cell and leaf.value == root.value): if (leaf.parent == None or leaf.parent.cell != leaf.cell): bivalue = (leaf.cell.c - set([leaf.value])).pop() child = Node(leaf.cell, bivalue, (1,0)[leaf.state == 1]) leaf.add_child(child) else: links = [] if leaf.state == 0: links += strong_links(board, leaf.cell, 2, leaf.value) if leaf.state == 1: links += weak_links(board, leaf.cell, leaf.value) links = list(set([cell for cell in links if len(cell.c) == 2])) links = [cell for cell in links if root.value in cell.c]+[cell for cell in links if root.value not in cell.c] for cell in links: if not (leaf.parent != None and leaf.parent.cell == cell): child = Node(cell, leaf.value, (1,0)[leaf.state == 1]) leaf.add_child(child)