2009-02-20 8 views
1

SquareExp2 peuvent être 9 ou 16Comment simplifier ce code Sodoku?

place peut être 3 ou 4

La longueur du tableau de gridbox et gridbox1 peut être 0 à 80 ou de 0 à 255

(vous voyez le modèle maintenant)

Ce code est exécuté une seule fois, au début du programme.

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 

L'objectif du code ci-dessus est de déplacer le code de

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 

* modifier *

à la fin

  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 

Mise à jour peu de suivi, quelques mois plus tard.

Il était un programme de sudoku et vous pouvez trouver où il utilisé here

+0

pourquoi la demande de fermeture? – Fredou

+0

Qu'est-ce que * fait *? – Tomalak

+0

c'est quelque chose qui est utilisé dans un programme de sudoku pour trouver tous les autres nombres dans une "boîte" sans faire une double boucle chaque fois qu'il en a besoin, il est calculé au moment de l'exécution – Fredou

Répondre

2

Éditer: la réponse finale pour la vraie puissance ultime!

Donc pour gridbox, vous prenez essentiellement i et j et entrelacez leurs chiffres en base (carré). Par exemple, étant donné i et j dans la base (échelle), il est Computing:

i (2) j (2) i (1) j (1)

où (n) représente la base de chiffres (échelle).

Donc, c'est assez facile pour accélérer: il suffit de conserver un contrôle automatique de la contribution de chaque chiffre à la valeur finale de gridbox (...).

Accélérer gridbox1 (...) est encore plus simple. En gros, vous calculez:

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

Maintenant, (j Mod Square) développe à (j - j\Square*Square) qui réduit le dessus:

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

ce qui simplifie à:

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

ce qui simplifie à:

Square * Square * (j) 

Voici la dernière boucle:

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 
+0

ne vous inquiétez pas sur la syntaxe, quand il est fait, je vais essayer et de le corriger si nécessaire et je vous dirai si ça marche, comme je l'ai fait avec l'autre – Fredou

+0

question, est i2_interleaved_offset une faute de frappe de j2_interleaved_offset? – Fredou

+0

Non. Fondamentalement, il est là pour prendre i2i1 et j2j1 et les fusionner pour former j2 i2 j1 i1. – MSN

2

Si je ne me trompe pas, cela devrait faire la même chose:

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 
+0

celui-ci fonctionne, je vais attendre 1-2 heures avant de marquer la réponse – Fredou

+0

dans une boucle pour 10sec, je peut exécuter ce code 8,3 millions de temps – Fredou

2

Il ressemble à ceci est pour générer une table de remappage de l'adresse linéaire à l'offset dans les mêmes données dans l'ordre morton. gridbox(y*squareExp2+x) est le décalage dans les données swizzled, et gridbox1(x) est le décalage du bloc. Ce type de chose est habituellement exprimé sous la forme d'une séquence d'opérations au niveau du bit, mais cela ne généralise pas les blocs de toute dimension (par exemple, 3x3).

Je ne connais aucun moyen plus simple de le faire pour des tailles de bloc arbitraires. La coordonnée du bloc doit être connue ((i\square,j\square)), les coordonnées du bloc doivent être connues ((i mod square,j mod square)), chaque partie de la coordonnée du bloc doit être mise à l'échelle par la taille du bloc dans cette dimension (squareExp2*square, j-wards, et squareExp2, i-wards), et la coordonnée à l'intérieur du bloc doit être mise à l'échelle dans la direction j par la foulée du bloc (square). Donc, s'il n'y a pas plus que ces calculs impliqués (et il semble qu'il n'y en a pas, même si je me suis peut-être trompé!) Alors je ne suis pas sûr qu'il y ait autre chose qui puisse être évincé.

+0

vous venez de me donner quelques choses à lire, l'ordre morton et les données swizzled. Je ne connaissais pas ces définitions. Merci! – Fredou

+0

résultat de ma question peut être trouvé ici http://www.codeproject.com/KB/vb/CodeBehindSudoku.aspx, merci! – Fredou