Как упростить этот Кодекс Содоку? - PullRequest
1 голос
/ 21 февраля 2009

SquareExp2 может быть 9 или 16

Площадь может быть 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

Обновление небольшое наблюдение, несколько месяцев спустя.

Это было для программы судоку, и вы можете найти, где она используется здесь

Ответы [ 3 ]

2 голосов
/ 21 февраля 2009

Похоже, что это для генерации таблицы переназначения от линейного адреса до смещения в тех же данных в порядке следования. gridbox(y*squareExp2+x) - это смещение в закрученных данных, а gridbox1(x) - это смещение блока.

Такого рода вещи обычно выражаются в виде последовательности побитовых операций, но это не обобщается на блоки любого измерения (например, 3x3).

Я не знаю ни одного более аккуратного способа сделать это для блоков произвольного размера. Координата блока должна быть известна (это (i\square,j\square)), координата в пределах блока должна быть известна (это (i mod square,j mod square)), каждая часть координаты блока должна быть масштабирована до размера блока в этом измерении (squareExp2*square, j-wards и squareExp2, i-wards), а координата в пределах блока должна масштабироваться в направлении j по шагу блока (square). Так что, если в расчет вовлечены только эти вычисления (и, похоже, их нет, хотя я мог ошибиться!), Я не уверен, что есть что-то, что можно выжать.

2 голосов
/ 21 февраля 2009

Редактировать: окончательный ответ для реальной предельной силы!

Так что для gridbox вы берете i и j и чередуете их цифры в основании (квадрат). Например, учитывая i и j в основании (масштабе), вы вычисляете:

я (2) J (2) я (1) J (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
2 голосов
/ 21 февраля 2009

Если я только правильно понял, это должно сделать то же самое:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...