2016-06-08 5 views
2

Я пишу сценарий для эффективного решения головоломки sudoku, но есть одна часть моего кода, которая, по моему мнению, крайне уродлива и хочу оптимизировать.Python - Streamlining sudoku solver code

def square(cell): 

    rows='ABCDEFGHI' 
    cols='123456789' 

    cell_row = cell[0][0] 
    cell_col = cell[0][1] 

    if cell_row in rows[0:3]: 
     x = 'A' 
    if cell_row in rows[3:6]: 
     x = 'B' 
    if cell_row in rows[6:9]: 
     x = 'C' 
    if cell_col in cols[0:3]: 
     y = 'a' 
    if cell_col in cols[3:6]: 
     y = 'b' 
    if cell_col in cols[6:9]: 
     y = 'c' 

    return (['Aa','Ab','Ac','Ba','Bb','Bc','Ca','Cb','Cc'].index(x+y))+1 

Учитывая, что судоку плата состоит из 9 3x3 квадратов цель этой функции взять координаты ячейки на доске и возвращает количество 3х3 площади, к которой принадлежит ячейка (где квадрат в верхнем левом углу - номер 1, а нижний правый - номер 9). Входная ячейка находится в форме ['A5', 6], где A обозначает строку, 5 - столбец и 6 - значение ячейки.

Код, который у меня есть, но есть более эффективный или презентабельный способ сделать это. Я был бы признателен за любые предложения.

ответ

1

Лично я не думаю, что магические числа, как «65» и «97» сделать раствор более презентабельный! Как насчет:

def square(cell): 
    rows = 'ABCDEFGHI' 

    cell_row = rows.index(cell[0][0]) 
    cell_col = int(cell[0][1]) - 1 

    return 3 * (cell_row // 3) + cell_col // 3 + 1 
+0

Это замечательно, презентабельно! – ggordon

1

Я смог сделать значительно упрощенную версию вашей формулы. Я начал с назначения как строки, так и столбца индексу на основе 0. Затем я использовал целочисленное деление, чтобы получить информацию о том, что такое 3-блочный квадрат. Поскольку перемещение вниз по 3-блоку строк увеличивает индекс на 3 при перемещении вправо, только увеличивает его на 1, я умножаю индекс строки на 3 после деления. Вот готовая функция:

def square(cell): 
    coords = (ord(cell[0][0]) - 65,int(cell[0][1]) - 1) 
    return 3 * (coords[0] // 3) + coords[1] // 3 + 1 
0

Edit: Фиксированное смещение на 1 - хотя я предпочел бы начать с 0, как вы, вероятно, захотите использовать возвращаемое значение как индекс для другого (суб-) массива ,

И поскольку я не могу комментировать другие ответы, но только мои 2 цента здесь: Ответ cdlane немного медленнее, чем представленный здесь. Если вы избавитесь от .lower() (я предполагаю, что на данный момент вы не заботитесь об отказоустойчивых сейфах), и используйте ответ Brien, вы получаете еще одно небольшое повышение производительности. Я не знаю, как часто вы будете оценивать квадрат(), но, возможно, стоит обратить внимание на производительность;)

Я думаю, что прилагаемый фрагмент должен сделать трюк.

def square(cell): 
    # http://www.asciitable.com/ 
    # https://docs.python.org/3/library/functions.html#ord 
    row = ord(cell[0][0].lower()) - 97 
    column = int(cell[0][1])-1 
    return 3*(row//3) + column//3 + 1