Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Решатель судоку аналитическими методамиСодержание книги Поиск на нашем сайте TRIPLETS = [[0,1,2],[3,4,5],[6,7,8]]
#Row/ Col /3x3 iteration list, each is nine lists of nine (row, col) pairs ROW_ITER = [[(row,col) for col in range(0,9)] for row in range(0,9)] COL_ITER = [[(row,col) for row in range(0,9)] for col in range(0,9)] TxT_ITER = [[(row,col) for row in rows for col in cols] for rows in TRIPLETS for cols in TRIPLETS]
class sudoku: def __init__ (self, start_grid=None): #Setup list of lists (the rows), each row is a list of 9 cells, which are each a list of integers 1-9 inclusive. self. squares =[ [range(1,10) for col in range(0,9)] for row in range(0,9)]
if start_grid is not None: if len(start_grid)==81: for row in range(0,9): self. set_row(row, start_grid[(row*9):((row+1)*9)]) else: assert len(start_grid)==9, "Bad input!" for row in range(0,9): self. set_row(row, start_grid[row])
#self.check() self. _changed=False
def solved (self): for row in range(0,9): for col in range(0,9): if len(self. squares[row][col]) > 1: return False return True
def copy (self): sudoku_copy = sudoku(None) for row in range(0,9): for col in range(0,9): sudoku_copy.squares[row][col] = self. squares[row][col][:] #copy! sudoku_copy._changed=False return sudoku_copy
def set_row (self,row, x_list): assert len(x_list)==9 for col in range(0,9): try: x = int(x_list[col]) except: x = 0 #self.set_cell(row, col,x) self. set_cell(row,col,x)
def set_cell (self,row,col,x): if self. squares[row][col] == [x]: #Already done! pass elif x not in range(1,9+1): #Set to unknown pass else: assert x in self. squares[row][col], \ "Told to set square (%i,%i) to an impossible entry, %i" % (row,col,x)
self. squares[row][col] = [x] self. update_neighbours(row,col,x) self. _changed=True
def cell_exclude (self, row,col,x): assert x in range(1,9+1) if x in self. squares[row][col]: #Remove it... self. squares[row][col].remove(x) #Should be one or more entries left... assert len(self. squares[row][col]) > 0, \ "Removed last possible entry for square (%i,%i) which was %i" \ % (row, col, x) #Now, has this confirmed the value for this square? if len(self. squares[row][col]) == 1: #This cell is now definate.. #Need to update its friends... #print "After exluding %i, square (%i,%i) must be %i" \ #% (x, self.row, self.col, self[0]) self. _changed=True self. update_neighbours(row,col, self. squares[row][col][0]) else: #Don't need to remove this, already done! pass return
def row_exclude (self, row, x): assert x in range(1,9+1) for col in range(0,9): self. cell_exclude(row,col,x)
def col_exclude (self, col, x): assert x in range(1,9+1) for row in range(0,9): self. cell_exclude(row,col,x)
def update_neighbours (self,set_row,set_col,x): """Call this when the square is set to x, either directly, or as a side effect of an exclude leaving only one entry""" #print "Updating (%i,%i) to be %i..." % (self.row, self.col, x) #Update the possibilies in this row... for row in range(0,9): if row <> set_row: self. cell_exclude(row,set_col,x) #Update the possibilies in this col... for col in range(0,9): if col <> set_col: self. cell_exclude(set_row,col,x) #Update the possibilies in this 3x3 square... for triplet in TRIPLETS: if set_row in triplet: rows = triplet[:] if set_col in triplet: cols = triplet[:] #Only need to do four of the eight possibles (well, 9 if you count the cell itself) #as did two on the row, and two on the col rows.remove(set_row) cols.remove(set_col) for row in rows: for col in cols: assert row <> set_row or col <> set_col #print "Updating (%i,%i) to be %i, excluding %i from (%i, %i)" \ #% (self.row, self.col, x, x, row, col) self. cell_exclude(row,col,x)
def get_cell_int (self,row,col): if len(self. squares[row][col])==1: return int(self. squares[row][col][0]) else: return 0
def get_cell_str (self,row,col): if len(self. squares[row][col])==1: return "(%i,%i) = %i" % (row, col, self. squares[row][col][0]) else: return ("(%i,%i) = " % (row, col)) + ",". join([str(x) for x in self. squares[row][col]])
def get_cell_digit_str (self,row,col): if len(self. squares[row][col])==1: return str(self. squares[row][col][0]) else: return "0"
def as_test_81 (self): """Return a string of 81 digits""" return "". join(self. as_test_list())
def simple_text (self): return "\n". join(self. as_test_list())
def as_test_list (self): return [ ("". join([ self. get_cell_digit_str(row,col) for col in range(0,9)])) for row in range(0,9) ] """ answer=[] for row in range(0,9): line="" for col in range(0,9): line = line + self.get_cell_digit_str(row, col) answer.append(line) return answer """
def __repr__ (self): answer= "[" + ",". join([ \ ("[" + ",". join([ self. get_cell_digit_str(row,col) for col in range(0,9)]) + "]") \ for row in range(0,9) ]) return answer
def __str__ (self): answer = " 123 456 789\n" for row in range(0,9): answer = answer + str(row+1) \ + " [" + "". join([ self. get_cell_digit_str(row,col).replace("0", "?") for col in range(0,3)]) \ + "] [" + "". join([ self. get_cell_digit_str(row,col).replace("0", "?") for col in range(3,6)]) \ + "] [" + "". join([ self. get_cell_digit_str(row,col).replace("0", "?") for col in range(6,9)]) \ + "]\n" if row+1 in [3,6]: answer = answer + " --- --- ---\n" return answer
def retArr (self): data = [] for row in range(0,9): data.append([]) for col in range(0, 9): data[row].append(self. get_cell_digit_str(row,col)) return data
def check (self, level=0): self. _changed=True while self. _changed: #print "checking..." self. _changed=False self. check_for_single_occurances() self. check_for_last_in_row_col_3x3() if level >= 1: self. overlapping_3x3_and_row_or_col() #(aka slicing and dicing) if level >= 2: self. one_level_supposition() if level >= 3: self. two_level_supposition()
#If nothing happened, then self.changed==False (still) #and we break the loop return
def check_for_single_occurances (self): #Want to see if x only occurs once in this row/ col /3x3... for check_type in [ROW_ITER, COL_ITER, TxT_ITER]: for check_list in check_type: for x in range(1,9+1): #1 to 9 inclusive x_in_list = [] for (row,col) in check_list: if x in self. squares[row][col]: x_in_list.append((row,col)) if len(x_in_list)==1: (row,col) = x_in_list[0] #This position MUST be be x if len(self. squares[row][col]) > 1: self. set_cell(row,col,x)
def check_for_last_in_row_col_3x3 (self): #Now, for each row/ col /3x3 want to see if there is a single #unknown entry... for (type_name, check_type) in [("Row",ROW_ITER),(" Col ",COL_ITER),("3x3",TxT_ITER)]: for check_list in check_type: unknown_entries = [] unassigned_values = range(1,9+1) #1-9 inclusive known_values = [] for (row,col) in check_list: if len(self. squares[row][col]) == 1: assert self. squares[row][col][0] not in known_values, \ "Already have %i (%i,%i) in known list [%s] for %s" % (self. squares[row][col][0],row,col, ",". join(map(str,known_values)), type_name)
known_values.append(self. squares[row][col][0])
assert self. squares[row][col][0] in unassigned_values, \ "Expected %i (%i,%i) in list [%s] for %s" % (self. squares[row][col][0],row,col, ",". join(map(str,unassigned_values)), type_name)
unassigned_values.remove(self. squares[row][col][0]) else: unknown_entries.append((row,col)) assert len(unknown_entries) + len(known_values) == 9 assert len(unknown_entries) == len(unassigned_values) if len(unknown_entries) == 1: #This cell must be the only number 1-9 not in known_values x = unassigned_values[0] (row,col) = unknown_entries[0]
#assert x not in known_values
#print "Because its the last cell in its row/ col /3x3 entry (%i,%i) must be %i" \ #% (row, col,x) self. set_cell(row,col,x) """ for row in range(0,9): self.check_row(row) for col in range(0,9): self.check_col(col) #Check the 3x3 squares... for rows in TRIPLETS: for cols in TRIPLETS: for x in range(0,9): x_in_location=[] for row in rows: for col in cols: if x in self.squares[row][ col ]: x_in_location.append((row, col)) if len (x_in_location)==1: (row, col) = x_in_location[0] #This position MUST be be x if len (self.squares[row][ col ]) > 1: self.set_cell(row, col,x) """ return
def diagnosis (self): answer= "" df = long(1) for row in range(0,9): for col in range(0,9): if len(self. squares[row][col]) > 1: answer = answer + str(self. squares[row][col]) + "\n" df = df * len(self. squares[row][col]) answer = answer + "Degrees of freedom: %i" % df return answer
def overlapping_3x3_and_row_or_col (self): """Block and Column / Row Interactions (name from Simon Armstrong)
http://www.simes.clara.co.uk/programs/sudokutechnique3.htm
Also known as 'slicing and dicing' """ #For a given 3x3, and a given digit, want to see if #all the remaining candidates are in a single row or column.. #Want to see if x only occurs once in this row/ col /3x3... for check_list in TxT_ITER: for x in range(1,9+1): #1 to 9 inclusive #print "Checking %i in 3x3" % x, check_list rows_for_x = [] cols_for_x = [] for (row,col) in check_list: if x in self. squares[row][col]: #print "Found possible %i at (%i,%i)" % (x, row, col) if row not in rows_for_x: rows_for_x.append(row) if col not in cols_for_x: cols_for_x.append(col) #Are they all in the same row? if len(rows_for_x)==1 and len(cols_for_x) > 1: #print "%i must be in row %i using cols %s" % (x, rows_for_x[0]+1, ",".join(map(lambda i: str (i+1),cols_for_x))) #print self #This means, we can remove X from all the rest of the row... row = rows_for_x[0] for col in range(0,9): if col not in cols_for_x: self. cell_exclude(row,col,x) #We can also remove x from all the rest of this 3x3... for (row,col) in check_list: if col not in cols_for_x: if row not in rows_for_x: self. cell_exclude(row,col,x) #Are they all in the same col? if len(cols_for_x)==1 and len(rows_for_x) > 1: #print "%i must be in col %i using rows %s" % (x, cols_for_x[0]+1, ",".join(map(lambda i: str (i+1),rows_for_x))) #print self #This means, we can remove X from all the rest of the row... col = cols_for_x[0] for row in range(0,9): if row not in rows_for_x: self. cell_exclude(row,col,x) #We can also remove x from all the rest of this 3x3... for (row,col) in check_list: if col not in cols_for_x: if row not in rows_for_x: self. cell_exclude(row,col,x)
def one_level_supposition (self): """Probably what is known as ' Nishio ', try a number and see if it leads to a dead end. For all the ambigous squares, try each possible each entry and see if its OK, or if it leads to a contradiction. In the case of a contradiction we can remove it as a possibility... Two level suppositions (two guess) may be required for extreme puzzles...""" progress=True while progress: progress=False #print "Doing one level supposition..." for row in range(0,9): for col in range(0,9): if len(self. squares[row][col]) > 1: bad_x = [] for x in self. squares[row][col]: #print "/-- Trying setting (%i,%i) to %i" % (row, col,x) sudoku_copy = self. copy() try: sudoku_copy.set_cell(row,col,x) sudoku_copy.check(level=1) except AssertionError, e: #Leads to an error:) #This means that this square cannot be x #print e #print "%s cannot be %i" % (str (self.squares[row][ col ]), x) bad_x.append(x) del sudoku_copy #print "\-- End of exp " if len(bad_x) == 0: pass elif len(bad_x) < len(self. squares[row][col]): for x in bad_x: self. cell_exclude(row,col,x) self. check() progress=True else: assert False, "Bugger! All possible values for square (%i,%i) fail" \ % (row,col) #print "One level supposition done"
def two_level_supposition (self): progress=True while progress: progress=False #print "Doing two level supposition..." for row in range(0,9): for col in range(0,9): if len(self. squares[row][col]) > 1: bad_x = [] for x in self. squares[row][col]: #print "/-- Trying setting (%i,%i) to %i" % (row, col,x) sudoku_copy = self. copy() try: sudoku_copy.set_cell(row,col,x) #sudoku_copy.check() #sudoku_copy.one_level_supposition() sudoku_copy.check(level=2) except AssertionError, e: bad_x.append(x) del sudoku_copy #print "\-- End of exp " if len(bad_x) == 0: pass elif len(bad_x) < len(self. squares[row][col]): for x in bad_x: self. cell_exclude(row,col,x) self. check() progress=True else: assert False, "Bugger! All possible values for square (%i,%i) fail" \ % (row,col)
|
||
|
Последнее изменение этой страницы: 2016-12-13; просмотров: 280; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.21 (0.008 с.) |