如何简化这个Sodoku代码?

时间:2009-02-20 23:07:16

标签: vb.net math

SquareExp2可以是9或16

Square可以是3或4

gridbox和gridbox1数组的长度可以是0到80或0到255

(你现在看到了模式)

此代码仅在程序开始时运行一次。

 For j = 0 To squareExp2 - 1
     For i = 0 To squareExp2 - 1
         box = (j * squareExp2) + i

         gridbox(box) = ((j \ Square) * squareExp2 * Square) + ((j Mod Square) * Square) + (i \ Square) * squareExp2 + (i Mod Square)
         gridbox1(gridbox(box)) = ((j \ Square) * squareExp2 * Square) + (((j Mod Square) * Square) * Square)
     Next
 Next

上面代码的目标是从

移动代码
    k = (gridRow(pos) \ iSquare) * iSquare
    l = (gridCol(pos) \ iSquare) * iSquare

    For i = l To l + iSquare - 1
        For j = k To k + iSquare - 1
            box = (j * squareExp2) + i
            foundNumber(grid(box)) = grid(box)
        Next
    Next

   j = myGridbox1(i)
   For x = j To j + squareExp2 - 1
       foundNumber(grid(myGridbox(x))) = grid(myGridbox(x))
   Next

*编辑*

最后

            Dim Square2 As Integer = iSquare * iSquare
            Dim Square3 As Integer = Square2 * iSquare
            Dim Square4 As Integer = Square2 * Square2

            Dim j2_offset As Integer = 0
            For j2 As Integer = 0 To iSquare - 1
                Dim j1_offset As Integer = 0
                Dim j1_interleaved_offset As Integer = 0
                For j1 As Integer = 0 To iSquare - 1
                    Dim i2_offset As Integer = 0
                    Dim i2_interleaved_offset As Integer = 0
                    Dim j_offset_value As Integer = j2_offset + j1_offset
                    For i2 As Integer = 0 To iSquare - 1
                        Dim offset_value As Integer = j_offset_value + i2_offset
                        Dim interleaved_value As Integer = j2_offset + i2_interleaved_offset + j1_interleaved_offset
                        For i1 As Integer = 0 To iSquare - 1
                            box = offset_value + i1
                            gridbox(box) = interleaved_value + i1
                            gridbox1(gridbox(box)) = j_offset_value
                        Next
                        i2_offset += iSquare
                        i2_interleaved_offset += Square2
                    Next
                    j1_offset += Square2
                    j1_interleaved_offset += iSquare
                Next
                j2_offset += Square3
            Next

更新 几个月之后,几乎没有跟进。

这是一个数独计划,您可以找到它的使用位置here

3 个答案:

答案 0 :(得分:2)

如果我做得对,那应该这样做:

For j1 = 0 To square - 1
  For j2 = 0 To square - 1
    j = j1 * square + j2
    For i1 = 0 To square - 1
      For i2 = 0 To square - 1
        box = (j * squareExp2) + i1 * square + i2
        gridbox(box) = (((j1 * square + i1) * square + j2) * square) + i2
        gridbox1(gridbox(box)) = j * squareExp2
      Next
    Next
  Next
Next

答案 1 :(得分:2)

看起来这是用于从线性地址生成重映射表以在morton顺序中以相同数据偏移。 gridbox(y*squareExp2+x)是调整数据的偏移量,gridbox1(x)是块的偏移量。

这种事情通常表示为一系列按位运算,但这并不概括为任何维度的块(例如,3x3)。

我不知道为任意块大小做任何更简洁的方法。必须知道块的坐标(它是(i\square,j\square)),块中的坐标必须是已知的(它是(i mod square,j mod square)),块的坐标的每个部分都必须按块大小进行缩放。维度(squareExp2*square,j-wards和squareExp2,i-wards),并且块内的坐标必须通过块的步幅(square)在j方向上缩放。因此,如果只涉及这些计算(并且看起来没有,尽管我可能错了!)然后我不确定还有什么可以被挤出来。

答案 2 :(得分:2)

编辑:真正终极力量的最终答案!

因此对于gridbox,你基本上是把i和j交叉在基数(正方形)中。例如,给定i和j in base(scale),你正在计算:

I(2).J(2)I(1)Ĵ(1)

其中(n)表示数字基数(比例)。

所以这很容易加速:只需保持每个数字对gridbox(...)最终值的贡献的运行记录。

加速gridbox1(...)更加容易。基本上,你在计算:

Square * Square *(j\Square * Square + (j Mod Square))

现在,(j Mod Square)扩展为(j - j\Square*Square),将上述内容缩小为:

Square * Square *(j\Square * Square + (j - j\Square*Square))

简化为:

Square * Square *(j\Square * Square + j - j\Square*Square)

简化为:

Square * Square * (j)

这是最后一个循环:

Dim Square2 = Square * Square
Dim Square3 = Square2 * Square
Dim Square4 = Square2 * Square2

Dim j2_offset = 0
Dim j2_interleaved_offset = 0
Dim j2_value_offset= 0
For j2 = 0 To Square - 1
    Dim j1_offset = 0
    Dim j1_interleaved_offset = 0
    For j1 = 0 To Square - 1
        Dim i2_offset = 0
        Dim i1_interleaved_offset = 0
        For i2 = 0 To Square - 1
            For i1 = 0 To Square - 1
                Dim box = j2_offset + j1_offset + i2_offset + i1
                gridbox(box) = j2_interleaved_offset + i2_interleaved_offset + j1_interleaved_offset + i1
                gridbox1(gridbox(box)) = j2_offset + j1_offset
            Next
            i2_offset += Square
            i2_interleaved_offset += Square2
        Next
        j1_offset += Square2
        j1_interleaved_offset += Square
    Next
    j2_offset += Square3
    j2_interleaved_offset += Square3
Next