(我对此还很陌生,因此非常感谢本文的一般形式和我的代码提示!)

我一直在IBM Sandbox中使用Swift进行游戏,但似乎无法解决以下问题:

func fillPossibilityMatrix() {        //it's a 9x9 Matrix
for i in 0...80 {
    let row = (i - (i % 9)) / 9       //-> row is Valid for 0 - 8
    let column = i % 9
    if possibilityMatrix[row, column] == [0] {
        possibilityMatrix[row, column] = possibilities(row, column: column)
    }
}

这给了我132个未知错误!
  • 即使我可以在此处使用的值的每种组合都调用可能性矩阵可能性(),但只要在它们之间加上“=”,事情就会变得很奇怪。
  • 我尝试将值分配给数组/矩阵的无效索引时遇到过132错误,但在这里看不到...

  • --
    以下工作完全正常。 (请注意,“打印 s”而不是“=“)
    func fillPossibilityMatrix() { for i in 0...80 { let row = (i - (i % 9)) / 9 let column = i % 9 if possibilityMatrix[row, column] == [0] { print(possibilityMatrix[row, column]) print(possibilities(row, column: column)) } } }
  • 当我为循环放置不同的范围时,它也可以工作。但是,不是使用某些值还是使用Range的大小来确定是否使用该值。

  • 怎么了我只是愚蠢吗?这是特定于IBM网站吗?

    其余的部分

    (我试图让它解决数独)

    --

    可能性矩阵是这样产生的:
    (此处:字段可能性矩阵)
    struct Matrix {
        let rows: Int, columns: Int
        var grid: [[Int]]
        init(rows: Int, columns: Int) {
            self.rows = rows
            self.columns = columns
            grid = Array(count: rows * columns, repeatedValue: [0])
        }
       func indexIsValidForRow(row: Int, column: Int) -> Bool {
            return row >= 0 && row < rows && column >= 0 && column < columns
        }
        subscript(row: Int, column: Int) -> [Int] {
            get {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                return grid[(row * columns) + column]
            }
            set {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                grid[(row * columns) + column] = newValue
            }
        }
    }
    var inputArray = [Int!] ()
    var input = "003020600900305001001806400008102900700000008006708200002609500800203009005010300"
    var field = Matrix(rows: 9, columns: 9)
    
    for char in input.characters {
        inputArray.append(Int(String(char)))
    }
    func fromInputToField() {
        for i in 0..<inputArray.count {
            let row = (i - (i % 9))/9
            let column = i % 9
            field[row, column][0] = (inputArray[i])
        }
    }
    fromInputToField()
    
    var possibilityMatrix = field
    

    --

    可能性()及其子功能如下:
    func possibilities(row: Int, column: Int) -> [Int] {
        let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        return numbers.filter {
            !rowContains(row, number: $0) && !columnContains(column, number: $0) && !boxContains(row, c: column, number: $0)
        }
    }
    
    
    func rowContains(r: Int, number: Int) -> Bool {
        for i in 0...8 {
            if possibilityMatrix[r, i][0] == number {
                return true
            }
        }
        return false
    }
    func columnContains(c: Int, number: Int) -> Bool {
       for i in 0...8 {
            if possibilityMatrix[i, c][0] == number {
                return true
            }
        }
        return false
    }
    func boxContains (r: Int, c: Int, number: Int) -> Bool {
        let boxLocation = locateBox(r, c: c)
        for x in 0...2 {
            for y in 0...2 {
                if possibilityMatrix[boxLocation.0 + y, boxLocation.1 + x][0] == number {
                    return true
                }
            }
        }
        return false
    }
    
    func locateBox (r: Int, c: Int) -> (upBorder: Int, leftBorder: Int) {
        if r % 3 != 0 {
            return locateBox(r - 1, c: c)
        }
        if c % 3 != 0 {
            return locateBox(r, c: c - 1)
        }
        return (r, c)
    }
    



    用于粘贴粘贴
    struct Matrix {
        let rows: Int, columns: Int
        var grid: [[Int]]
        init(rows: Int, columns: Int) {
            self.rows = rows
            self.columns = columns
            grid = Array(count: rows * columns, repeatedValue: [0])
        }
       func indexIsValidForRow(row: Int, column: Int) -> Bool {
            return row >= 0 && row < rows && column >= 0 && column < columns
        }
        subscript(row: Int, column: Int) -> [Int] {
            get {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                return grid[(row * columns) + column]
            }
            set {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                grid[(row * columns) + column] = newValue
            }
        }
    }
    var inputArray = [Int!] ()
    var input = "003020600900305001001806400008102900700000008006708200002609500800203009005010300"
    var field = Matrix(rows: 9, columns: 9)
    
    for char in input.characters {
        inputArray.append(Int(String(char)))
    }
    func fromInputToField() {
        for i in 0..<inputArray.count {
            let row = (i - (i % 9))/9
            let column = i % 9
            field[row, column][0] = (inputArray[i])
        }
    }
    fromInputToField()
    
    var possibilityMatrix = field
    func possibilities(row: Int, column: Int) -> [Int] {
        let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        return numbers.filter {
            !rowContains(row, number: $0) && !columnContains(column, number: $0) && !boxContains(row, c: column, number: $0)
        }
    }
    
    
    func rowContains(r: Int, number: Int) -> Bool {
        for i in 0...8 {
            if possibilityMatrix[r, i][0] == number {
                return true
            }
        }
        return false
    }
    func columnContains(c: Int, number: Int) -> Bool {
       for i in 0...8 {
            if possibilityMatrix[i, c][0] == number {
                return true
            }
        }
        return false
    }
    func boxContains (r: Int, c: Int, number: Int) -> Bool {
        let boxLocation = locateBox(r, c: c)
        for x in 0...2 {
            for y in 0...2 {
                if possibilityMatrix[boxLocation.0 + y, boxLocation.1 + x][0] == number {
                    return true
                }
            }
        }
        return false
    }
    
    func locateBox (r: Int, c: Int) -> (upBorder: Int, leftBorder: Int) {
        if r % 3 != 0 {
            return locateBox(r - 1, c: c)
        }
        if c % 3 != 0 {
            return locateBox(r, c: c - 1)
        }
        return (r, c)
    }
    func fillPossibilityMatrix() {        //it's a 9x9 Matrix
        for i in 0...80 {
            let row = (i - (i % 9)) / 9       //-> row is Valid for 0 - 8
            let column = i % 9
            if possibilityMatrix[row, column] == [0] {
                possibilityMatrix[row, column] = possibilities(row, column: column)
            }
        }
    }
    fillPossibilityMatrix()
    

    最佳答案

    事实证明,这个问题很简单。这是您可能的功能:

    func rowContains(r: Int, number: Int) -> Bool {
        for i in 0...8 {
            if possibilityMatrix[r, i][0] == number {
                return true
            }
        }
        return false
    }
    func columnContains(c: Int, number: Int) -> Bool {
       for i in 0...8 {
            if possibilityMatrix[i, c][0] == number {
                return true
            }
        }
        return false
    }
    func boxContains (r: Int, c: Int, number: Int) -> Bool {
        let boxLocation = locateBox(r, c: c)
        for x in 0...2 {
            for y in 0...2 {
                if possibilityMatrix[boxLocation.0 + y, boxLocation.1 + x][0] == number {
                    return true
                }
            }
        }
        return false
    }
    

    问题是您正在检查probabilityMatrix以查看数字是否存在-这是您在进行操作时正在修改的变量。因此,如果将probabilityMatrix[0, 0]更改为等于[4, 5],那么当您检查probabilityMatrix[0, 1]时,由于您所做的更改,您的函数将假定4在第一行中。检查的一部分是查看probabilityMatrix[0, 0]的第一个元素4,因此您的代码认为第一行自然包含一个4

    完成这些操作后,您最终将到达一个可能性列表为[]的正方形,因为随着行(或列或框)的行进,错误的数字不断累积,最终所有可能性都消失了。然后在下一遍,类似rowContains的函数将查看该[]并尝试从中获取第一个元素(例如possibilityMatrix[r, i][0]中不存在的元素)。这是导致Index out of range错误的原因。

    解决方案是与field而不是possibilityMatrix进行比较,因为该变量从不更改,并且始终保留原始矩阵。因此,您的函数应如下所示:
    func rowContains(r: Int, number: Int) -> Bool {
        for i in 0...8 {
            if field[r, i][0] == number {
                return true
            }
        }
        return false
    }
    func columnContains(c: Int, number: Int) -> Bool {
       for i in 0...8 {
            if field[i, c][0] == number {
                return true
            }
        }
        return false
    }
    func boxContains (r: Int, c: Int, number: Int) -> Bool {
        let boxLocation = locateBox(r, c: c)
        for x in 0...2 {
            for y in 0...2 {
                if field[boxLocation.0 + y, boxLocation.1 + x][0] == number {
                    return true
                }
            }
        }
        return false
    }
    

    这是在沙盒中实现的工作版本,供您查看:

    http://swiftlang.ng.bluemix.net/#/repl/6fe779409351531ce07d3bc3f0c197639538729b40d5f0f658e4dd53985223fe

    编辑:虽然学习递归是一件好事,但如果可以的话,最好避免这样做,因为它比迭代循环占用更多的资源(因为每次调用函数时,它都放在程序堆栈上并占用资源) 。这是达到相同结果的更快方法:
    func locateBox (r: Int, c: Int) -> (upBorder: Int, leftBorder: Int) {
        return ((r - (r % 3)), (c - (c % 3)))
    }
    

    另外,您的fillPossibilityMatrix()函数可能会更好地作为双循环运行,因为1)除法和余数函数在计算上有些昂贵,并且2)易于阅读。
    func fillPossibilityMatrix() {        //it's a 9x9 Matrix
        for row in 0...8 {
            for column in 0...8 {
                if possibilityMatrix[row, column] == [0] {
                    possibilityMatrix[row, column] = possibilities(row, column: column)
                }
            }
        }
    }
    

    10-06 02:33