グラフは、再帰的関数dropNum(index: Int)が呼ばれたときのindexの値を示しています。初期状態では、52個の埋めるべき空白があることに注意して下さい。
func dropNum(index: Int) { var place = emptyPlaces[index] for num in 1...9 { if isSafeForNum(place: place, num: num) { table[place.row][place.col] = num putCount += 1 if putCount == nplaces { return } dropNum(index: index+1) if putCount != nplaces { place = emptyPlaces[index] table[place.row][place.col] = 0 putCount -= 1 } } } }
あなたは以下の95行をコピー・ペーストして、IBM Swift Sandboxというサイトで、このプログラムを試してみることができます。
struct Place { var row: Int = -1 var col: Int = -1 } class NumBoard { var table = [[Int]]() var emptyPlaces = [Place]() var place = Place() let nplaces : Int var putCount: Int init() { table = [[7,0,3, 0,0,0, 0,0,0], [0,5,1, 3,7,0, 4,0,0], [6,0,0, 0,1,0, 0,2,0], [0,0,4, 6,0,0, 0,0,0], [0,0,0, 0,0,7, 0,8,0], [5,0,0, 2,3,1, 9,0,0], [3,0,0, 0,2,4, 0,9,1], [0,0,0, 0,0,0, 8,4,0], [0,0,7, 0,9,0, 2,0,0]] for rr in 0...8 { for cc in 0...8 { if table[rr][cc] == 0 { place.row = rr place.col = cc emptyPlaces.append(place) } } } putCount = 0 nplaces = emptyPlaces.count myprint(table: table) print("nplaces = \(nplaces)") } func myprint(table: [[Int]]) { print("-----------------") for rr in 0...8 { for cc in 0...8 { if table[rr][cc] == 0 { print(".", terminator: " ") } else { print(table[rr][cc], terminator: " ") } } print("") } print("-----------------") } func isSafeForNum(place: Place, num: Int) -> Bool { for rr in 0...8 { if num == table[rr][place.col] { return false } } for cc in 0...8 { if num == table[place.row][cc] { return false } } let rowBase = (place.row / 3) * 3 let colBase = (place.col / 3) * 3 for rr in 0...2 { for cc in 0...2 { if num == table[rowBase+rr][colBase+cc] { return false } } } return true } func dropNum(index: Int) { var place = emptyPlaces[index] for num in 1...9 { if isSafeForNum(place: place, num: num) { table[place.row][place.col] = num putCount += 1 if putCount == nplaces { return } dropNum(index: index+1) if putCount != nplaces { place = emptyPlaces[index] table[place.row][place.col] = 0 putCount -= 1 } } } } func play() { dropNum(index: 0) myprint(table: table) } } // main program let myboard = NumBoard() myboard.play()