Because I was interested in the algorithm and wondered if this object-oriented code with the fancy yield command could also be programmed procedurally, I tried to recreate it in Hollywood. The Sudoku solver works, and that's good enough for me. The Sudoku generator shouldn't be as problematic, since the solve() function might have been the hardest to port. I replaced the yield command of the Python program by putting the results into a list, and because a Python generator continues to work with the current values from the point where the yield is triggered, I use these as arguments when recursively calling the function.
So if anyone is interested, here is the script to solve a Sudoku.
The (very good) German description is unfortunately behind a paywall for c't customers, the original Python code (GPL 3) is here.
Code: Select all
columns=8 ; (9-1, index beginnt mit 0)
rows=8
Function p_Reset()
Local i,j
board=Nil
board=CreateList()
For j=0 To columns
board[j]=CreateList()
For i=0 To rows
board[j][i]=0
Next
Next
results=Nil
results=CreateList() ; Liste zum Sammeln der Ergebnisse
EndFunction
Function p_print(pboard)
Local i,j
For j=0 To columns
Local output$
For i=0 To rows
output$=output$.." "..ToString(pboard[j][i])
Next
DebugPrint(ReplaceStr(output$, "0", "."))
Next
DebugPrint("")
EndFunction
;prüft, ob eine Zahl num bereits in einer Reihe row oder Spalte column steht:
Function p_number_is_valid(row, column, num)
For i=0 To 8
If board[row][i]=num Or board[i][column]=num Then Return(False)
Next
start_column = column\3*3
start_row = row\3*3
For i=0 To 2
For j=0 To 2
If board[i + start_row][j + start_column] = num Then Return(False)
Next
Next
Return(True)
EndFunction
Function p_solve(r0,c0)
reclevel=reclevel+1
Local r,c,n
; suche ein leeres Feld
For Local r=r0 To 8
For Local c=c0 To 8
If board[r][c] = 0
; wenn frei
For Local n=1 To 9
If p_number_is_valid(r, c, n)
; wenn die Zahl hier paßt, einsetzen und
; rekursiv nachsehen, ob das zur Lösung führt
board[r][c] = n
p_solve(r,c)
board[r][c] = 0 ; wieder freigeben und mit nächster
; Ziffer oder neuer Position weiter im Suchbaum
EndIf
Next
reclevel=reclevel-1
Return(False)
EndIf
Next
c0=0
Next
; hier angekommen, sind alle Felder ausgefüllt und eine Lösung ist gefunden
; Lösung in die Liste eintragen
InsertItem(results, {})
results[ListItems(results)-1] = CopyTable(board)
reclevel=reclevel-1
Return(True)
EndFunction
;--------------------------------------------------
p_Reset()
; zu lösendes Beispiel, es gibt 4 Lösungen
board = {{0, 7, 6, 0, 1, 3, 0, 0, 0},
{0, 4, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 8, 6, 9, 0, 7, 0, 0},
{0, 5, 0, 0, 6, 9, 0, 3, 0},
{0, 0, 0, 0, 0, 0, 5, 4, 0},
{0, 8, 0, 7, 3, 0, 0, 0, 0},
{5, 1, 0, 0, 2, 6, 8, 0, 0},
{0, 0, 7, 1, 0, 0, 9, 0, 0},
{0, 0, 0, 0, 4, 0, 0, 6, 0}}
p_solve(0,0)
suffix="en"
If ListItems(results)=1 Then suffix=""
DebugPrint("Es gibt",ListItems(results),"Lösung"..suffix..":\n")
For i=0 To ListItems(results)-1
DebugPrint("Lösung",i+1)
p_print(results[i])
Next