Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- #iichan sudoku generator
- #v 1.0.0
- import random
- class Matrix(object): #класс матрицы
- def __init__(self, cols, rows):
- self.cols = cols
- self.rows = rows
- self.matrix = []
- for i in range(rows):
- ea_row = []
- for j in range(cols):
- ea_row.append("")
- self.matrix.append(ea_row)
- def setitem(self, col, row, v):
- self.matrix[col-1][row-1] = v
- def getitem(self, col, row):
- return self.matrix[col-1][row-1]
- def __repr__(self): # ,
- outStr = ""
- for i in range(self.rows):
- outStr += 'Row %s = %s\n' % (i+1, str(self.matrix[i]))
- return outStr
- def Number(i, j):
- Number = (i-1)*9 + j #это порядковый номер текущего элемента в матрице
- NumberTransp = (j-1)*9 + i #порядковый номер в транспорированной матрице
- a = (Number -1)/27 #27- число элементов в трёх строках, т.е. в трёх блоках
- b = (NumberTransp -1)/27
- NumberBlock = a*3 + (b+1) #формула получена эмпирическим путём :3
- return NumberBlock
- Sudoku = Matrix(9, 9) #создаём матрицу 9х9
- #и словари из пустых списков для всех вертикалей, горизонталей
- #и блоков- областей 3х3 в которых не должны повторятся числа
- ListHor = {}
- ListVer = {}
- ListBlock = {}
- for i in range(1, 10):
- ListHor[i] = []
- ListVer[i] = []
- ListBlock[i] = []
- #лист в котором будут хранится числа из которых можно случайно выбрать одно для
- #каждой конкретной ячейки, т.е. уже возможные (не повторяющиеся по соответствующим
- #вертикалям, горизонталям и блокам) числа
- List = []
- List = list(range(1, 10))
- #итератор для верхнего цикла while (перебор строк матрицы)
- i = 1
- flag = False
- while i < 10: #перебор строк
- j = 1 #итератор для вложенного цикла while
- while j < 10:
- #если в текущей горизонтали уже есть какие то числа, то
- #вычитаем их из List (в котором просто числа 1..9)
- if len(ListHor[i]) > 0:
- for n in range(0, len(ListHor[i])):
- if List.count(ListHor[i][n]) > 0:
- List.remove(ListHor[i][n])
- #аналогично для текущей вертикали
- if len(ListVer[j]) > 0:
- for n in range(0, len(ListVer[j])):
- if List.count(ListVer[j][n]) > 0:
- List.remove(ListVer[j][n])
- #для того, чтобы сделать ту же операцию для текущего блока,
- #необходимо вычислить его номер (блоки пронумерованы начиная
- #с верхнего левого слева направо)
- NumberBlock = Number(i, j) #формула получена эмпирическим путём :3
- #зная номер текущего блока, можем провести известную операцию
- if len(ListBlock[NumberBlock]) > 0:
- for n in range(0, len(ListBlock[NumberBlock])):
- if List.count(ListBlock[NumberBlock][n]) > 0:
- List.remove(ListBlock[NumberBlock][n])
- #если List пуст (т.е. текущая строка заполнена неверно)
- #возвращаемся на первый элемент строки, стираем элементы из списка
- #текущей горизонтали, последние элементы соответсвующих девяти вертикалей
- #и некоторые элементы из трех соответствующих блоков. Затем проходим строку заново
- #и надеемся что на этот раз заполнится как следует
- if List == []:
- List = list(range(1, 10))
- Choice = random.choice(List)
- for k in range(1, j):
- ListVer[k].pop()
- ListHor[i].pop()
- NumBl = Number(i, k)
- ListBlock[NumBl].remove(Sudoku.getitem(i, k))
- i = i - 1
- break #прерывание цикла- всё что дальше, уже не исполняется!
- Choice = random.choice(List) #выбираем один из элементов List рандомом
- #если в List только один элемент, его и выбираем
- if len(List) == 1:
- Choice = List[0]
- #добавляем в соответствующие списки выбранное число
- ListHor[i].append(Choice)
- ListVer[j].append(Choice)
- ListBlock[NumberBlock].append(Choice)
- #наконец то вносим выбранное число в матрицу
- Sudoku.setitem(i, j, Choice)
- #обновляем List
- List = list(range(1, 10))
- #...и итераторы
- j += 1
- i += 1
- #выводим результат
- print Sudoku
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement