Bücher online kostenlos Kostenlos Online Lesen
Die Programmiersprache Ruby (German Edition)

Die Programmiersprache Ruby (German Edition)

Titel: Die Programmiersprache Ruby (German Edition)
Autoren: David Flanagan , Yukihiro Matsumoto
Vom Netzwerk:
angegebenen Zeile zurückgeben
    def rowdigits(row)
     # Das Teil-Array extrahieren, das die Zeile darstellt, und alle
     # Nullen entfernen. Array-Subtraktion bildet eine Mengendifferenz
     # mit Entfernung von Duplikaten.
     @grid[row*9,9] - [0]
    end

    # Ein Array aller bekannten Werte in der angegebenen Spalte
    # zurückgeben
    def coldigits(col)
     result = [] # Mit einem leeren Array beginnen
     col.step(80, 9) {|i| # Schleife von col bis 80 in Neunerschritten
     v = @grid[i] # Wert der Zelle bei diesem Index ermitteln
     result << v if (v != 0) # Ans Array anfügen, falls nicht 0
     }
     result # Das Array zurückgeben
    end

    # Boxnummer dem Index der linken oberen Ecke der Box zuordnen
    BoxToIndex = [0, 3, 6, 27, 30, 33, 54, 57, 60].freeze

    # Array aller bekannten Werte in der angegebenen Box zurückgeben
    def boxdigits(b)
     # Boxnummer in den Index der linken oberen Ecke der Box konvertieren
     i = BoxToIndex[b]
     # Ein Array von Werten ohne 0-Elemente zurückgeben
     [
     @grid[i], @grid[i+1], @grid[i+2],
     @grid[i+9], @grid[i+10], @grid[i+11],
     @grid[i+18], @grid[i+19], @grid[i+20]
     ] - [0]
    end
end # Dies ist das Ende der Klasse Puzzle.

# Eine Ausnahme dieser Klasse zeigt ungültige Eingaben an.
class Invalid < StandardError
end

# Eine Ausnahme dieser Klasse zeigt an, dass ein Puzzle übermäßig
# beschränkt ist, so dass keine Lösung möglich ist.
class Impossible < StandardError
end

#
# Diese Methode scannt ein Puzzle und sucht nach unbekannten Zellen, die
# nur einen einzigen möglichen Wert haben. Wenn sie welche findet, setzt
# sie ihre Werte. Da das Ändern einer Zelle die möglichen Werte für andere
# Zellen verändert, fährt sie mit dem Scannen fort, bis sie das ganze
# Puzzle gescannt hat, ohne Zellen zu finden, deren Wert sie setzen kann.
#
# Diese Methode gibt drei Werte zurück. Wenn sie das Puzzle löst, sind
# alle drei Werte nil. Andernfalls sind die ersten beiden Rückgabewerte
# die Zeile und Spalte einer Zelle, deren Wert noch unbekannt ist. Der
# dritte Wert ist die Menge der möglichen Werte für diese Zeile und
# Spalte. Das ist eine Mindestmenge möglicher Werte: Es gibt keine
# Zelle im Puzzle, die weniger mögliche Werte hat. Dieser komplexe Rück-
# gabewert ermöglicht praktische Heuristik in der Methode solve(): Diese
# Methode kann Werte für Zellen so erraten, dass der erratene Wert
# mit größtmöglicher Wahrscheinlichkeit korrekt ist.
#
# Diese Methode löst Impossible aus, wenn sie eine Zelle findet, für
# die es keine möglichen Werte gibt. Das kann geschehen, wenn das
# Puzzle übermäßig beschränkt ist oder wenn die untenstehende Methode
# solve() falsch geraten hat.
#
# Diese Methode modifiziert das angegebene Puzzle-Objekt selbst.
# Wenn has_duplicates? beim Einstieg false ist, ist es auch beim
# Ausstieg false.
#
def Sudoku.scan(puzzle)
    unchanged = false # Dies ist unsere Schleifenvariable.

    # Schleife, bis wir das ganze Spielfeld ohne Änderung gescannt haben
    until unchanged
     unchanged = true # Annahme: Diesmal werden keine Zellen geändert
     rmin,cmin,pmin = nil # Zelle mit kleinster möglicher Menge
     min = 10 # Mehr als die maximale Anzahl Möglichkeiten

     # Schleife über die Zellen mit unbekanntem Wert
     puzzle.each_unknown do |row, col, box|
     # Menge der Werte finden, die in diese Zelle passen könnten
     p = puzzle.possible(row, col, box)

     # Je nach Größe der Menge p verzweigen
     # Wir beachten drei Fälle: p.size==0, p.size==1 und p.size > 1.
     case p.size
     when 0 # Keine möglichen Werte: Puzzle übermäßig beschränkt
     raise Impossible
     when 1 # Eindeutiger Wert gefunden, im Gitter setzen
     puzzle[row,col] = p[0] # Position im Gitter auf den Wert setzen
     unchanged = false # Änderung kennzeichnen
     else # Für jede andere Anzahl von Möglichkeiten
     # Die kleinste mögliche Menge von Möglichkeiten merken
     # Aber nicht darum kümmern, ob wir diese Schleife wiederholen
     if unchanged && p.size < min
     min = p.size # Aktuelle kleinste Menge
     rmin, cmin, pmin = row, col, p # Parallele Wertzuweisung
     end
     end
     end
    end

    # Zelle mit der kleinsten Menge von Möglichkeiten zurückgeben
    # Beachten Sie mehrere Rückgabewerte.
    return rmin, cmin, pmin
end

# Ein Sudoku-Puzzle lösen, wenn möglich mit einfacher Logik, aber wenn
# nötig mit Brute-Force. Dies ist eine rekursive Methode. Sie gibt ent-
# weder eine Lösung zurück oder löst eine Ausnahme aus. Die Lösung wird
# als neues Puzzle-Objekt ohne
Vom Netzwerk:

Weitere Kostenlose Bücher