2016-06-08 21 views
2

Ich schreibe ein Skript, um effizient ein Sudoku-Rätsel zu lösen, aber es gibt einen Teil meines Codes, den ich denke, ist extrem hässlich und möchte straffen.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 

Da ein sudoku Bord von 9 3x3 Quadrate der Zweck dieser Funktion auf der Platine, die Koordinaten einer Zelle zu übernehmen ist, besteht und die Anzahl der 3x3 Quadrat zurück zu der die Zelle (wo die angehört Quadrat oben links ist Nummer 1, und unten rechts ist Nummer 9). Die Eingabe 'Zelle' hat die Form ['A5', 6] wobei A die Zeile, 5 die Spalte und 6 den Wert der Zelle angibt.

Der Code, den ich habe funktioniert, aber es muss eine viel effizientere oder vorzeigbarer Weg, es zu tun. Ich wäre dankbar für irgendwelche Vorschläge.

Antwort

1

Ich persönlich glaube nicht, magische Zahlen wie ‚65‘ und ‚97‘ die Lösung mehr vorzeigbar machen! Wie wäre es mit:

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

Das ist großartig, vorzeigbar! – ggordon

1

Ich konnte eine stark vereinfachte Version Ihrer Formel erstellen. Ich begann damit, dass ich sowohl der Zeile als auch der Spalte einen 0-basierten Index zuordnete. Dann benutzte ich die Integer-Division, um nur die Information darüber zu erhalten, in welchem ​​3-Block das Quadrat liegt. Da ein 3-Block von Reihen den Index um 3 erhöht, während er nach rechts nur um 1 erhöht wird, multipliziere ich den Zeilenindex um 3 nach der Teilung. Hier ist die fertige Funktion:

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

bearbeiten: Fest Offset von 1 - obwohl ich eher bei 0 beginnen würde wie Sie wahrscheinlich den zurückgegebenen Wert als Index für einen anderen (Teil-) Array wollen werde verwenden .

Und da ich andere Antworten noch nicht kommentieren kann, nur meine 2 Cent hier: cdlane's Antwort ist etwas langsamer als die hier präsentierte. Wenn Sie den .lower() loswerden (ich nehme an, Sie interessieren sich nicht für Fail Safes an diesem Punkt) und verwenden Sie Briens Antwort, erhalten Sie einen weiteren leichten Leistungsschub. Ich weiß nicht, wie oft du Square() auswerten willst, aber vielleicht lohnt es sich, die Lesbarkeit für die Performance zu verringern;)

Ich denke, das angehängte Snippet sollte den Trick machen.

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