[Archives] Mathématiques pures, physique, chimie, etc. : problèmes d'entraînement cérébral sans rapport avec le commerce. - page 510

 
IgorM:
Je n'aime pas utiliser les opérateurs continue et break, mais ils peuvent peut-être vous aider, d'autant plus qu'un if de 36 sur mql pourrait ne pas fonctionner.
Si ça ne marchait pas, j'utiliserais continuer... Mais je ne veux pas du tout m'en préoccuper. Je préférerais créer un algorithme différent, au moins ce serait intéressant.
 
MaxZ:

Et accélérer Mon code peut être décomposé si, consistant en une condition de contrôle complexe de 36 entrées, en 36 ifs avec une condition simple ! :)))

Je pense que le code serait sensiblement plus rapide, bien que pour en être sûr, il faille comprendre les instructions machine, qui sont le résultat de la compilation.

J'ai exécuté votre code dans MT5. Les évaluations courtes des opérateurs logiques sont déjà implémentées (intégrées), il n'est donc pas nécessaire de décomposer le code en de nombreux ifs.

Dans MT4, c'est différent, cette optimisation a un sens dans ce cas. Mais j'ai fait une évaluation du temps dans MT5, par un schéma court.

 

Accéléré par un facteur de 4. Réécriture de Validate().

Maintenant, c'est comme ça :

bool Validate(int X)
  {
   int XX=0;
   int A[];
   IntToArray(X,A);
   for(int i=5;i>-1;i--)
     {
      XX|=int(1<<A[i]);
     }
   if(XX==0x7E) {return true;}
   return false;
  }
void IntToArray(int X, int &A[])
{
  ArrayResize(A,6);
  for(int i=0;i<6;i++)
    {
     A[i]=X%10; X/=10;
    }
}
WorkTime == 200 ms
 

Horrible, mais il est logique d'optimiser le code de la manière suivante. Plusieurs fois plus rapide ! Et là, MT5 ne sera plus d'aucune aide.

Ce n'est pas une idée, bien sûr. Mais je me demande à quelle vitesse cela va fonctionner ! :))

Dans le code, j'ai également réduit la plage des valeurs du diviseur. 654321/2 = 327160,5...

for (int A6 = 1; A6 <= 6; A6++)
   for (int A5 = 1; A5 <= 6; A5++)
   {
      if (A5 == A6) continue;
      for (int A4 = 1; A4 <= 6; A4++)
      {
         if (A4 == A5 || A4 == A6) continue;
         for (int A3 = 1; A3 <= 6; A3++)
         {
            if (A3 == A4 || A3 == A5 || A3 == A6) continue;
            for (int A2 = 1; A2 <= 6; A2++)
            {
               if (A2 == A3 || A2 == A4 || A2 == A5 || A2 == A6) continue;
               for (int A1 = 1; A1 <= 6; A1++)
               {
                  if (A1 == A2 || A1 == A3 || A1 == A4 || A1 == A5 || A1 == A6) continue;
for (int B6 = 1; B6 <= 3; B6++)
{
   if (B6 == A6) continue;
   for (int B5 = 1; B5 <= 6; B5++)
   {
      if (B6 == 3 && B5 > 2) continue;
      if (B5 == A5) continue;
      if (B5 == B6) continue;
      for (int B4 = 1; B4 <= 6; B4++)
      {
         if (B4 == A4) continue;
         if (B4 == B5 || B4 == B6) continue;
         for (int B3 = 1; B3 <= 6; B3++)
         {
            if (B3 == A3) continue;
            if (B3 == B4 || B3 == B5 || B3 == B6) continue;
            for (int B2 = 1; B2 <= 6; B2++)
            {
               if (B2 == A2) continue;
               if (B2 == B3 || B2 == B4 || B2 == B5 || B2 == B6) continue;
               for (int B1 = 1; B1 <= 6; B1++)
               {
                  if (B1 == A1) continue;
                  if (B1 == B2 || B1 == B3 || B1 == B4 || B1 == B5 || B1 == B6) continue;
                  
                  int A = A6*100000+A5*10000+A4*1000+A3*100+A2*10+A1;
                  int B = B6*100000+B5*10000+B4*1000+B3*100+B2*10+B1;
                  if (MathMod(A, B) == 0)
                  Print(A6,A5,A4,A3,A2,A1,"/",B6,B5,B4,B3,B2,B1,"=",A/B);
               }
            }
         }
      }
   }
}
               }
            }
         }
      }
   }
 
MetaDriver:

Accéléré par un facteur de 4. Réécriture de Validate().

Maintenant, ça ressemble à ça :

WorkTime == 200 ms

C'est magnifique ! Pas comme la mienne.

J'ai l'idée d'écrire un algorithme de division de colonnes. Divisez par des chiffres, écrivez le reste de la division et lorsque le résultat est supérieur à 6, faites une opération de continuation. C'est exactement ce que j'ai fait cet après-midi, quand j'ai passé en revue les cinq, j'ai tout divisé en colonnes. Mais ça fait longtemps que ça dure ! :))

C'est dans la représentation numérique hexadécimale qu'il faut faire l'optimisation, comme vous l'avez fait.

 
MaxZ:

J'ai l'idée d'écrire un algorithme de division de colonnes. Divisez par des chiffres, écrivez le reste de la division et s'il correspond ou si le résultat est supérieur à 6, faites l'opération suivante. C'est exactement ce que j'ai fait cet après-midi, quand j'ai passé en revue les cinq, j'ai tout divisé en colonnes. Mais ça fait longtemps que ça dure ! :))

C'est dans la représentation des nombres à six chiffres qu'il faut optimiser, comme vous l'avez fait.

О ! Ce n'est pas une mauvaise idée. Je l'ai encore réécrit. Temps de travail = 125 ms.

bool Validate(int X)
  {
   int XX=0;
   int A[];
   if(!IntToArray(X,A)) return false; // изменено здесь тоже, но основное ниже
   for(int i=5;i>-1;i--)
     {
      XX|=int(1<<A[i]);
     }
   if(XX==0x7E) {return true;}
   return false;
  }
bool IntToArray(int X,int &A[])
  {
   ArrayResize(A,6);
   int x=X%10;
   if(x==0 || x>6) return false;  // главное изменение
   else A[0]=x;
   for(int i=1;i<6;i++)
     {
      X/=10;
      x=X%10;
      if(x==0 || x>6) return false;  // главное изменение
      else A[i]=x;
     }
    return true;
  }
 
MetaDriver:

О ! Ce n'est pas une mauvaise idée. Je l'ai encore réécrit. Temps de travail = 125 ms

Maintenant, les joueurs de hockey vont certainement rester heureux ! :)))) Mais ce n'est pas ce que je voulais dire ! ;D


Combien le compteur de temps indique-t-il par Mon code ?


Je comprends les changements. Je ne l'ai juste pas encore maîtrisé :

   for(int i=5;i>-1;i--)
     {
      XX|=int(1<<A[i]);
     }
   if(XX==0x7E) {return true;}

"Est-ce que "|=" est un OU logique ? Le reste est une impasse...

 
MaxZ:
Maintenant, les joueurs de hockey seront heureux, c'est sûr ! :))))

Oui.

Votre nouveau code est encore plus rapide, mais il y a quelques bogues.

for (int A6 = 1; A6 <= 6; A6++)
   for (int A5 = 1; A5 <= 6; A5++)
   {
      if (A5 == A6) continue;
      for (int A4 = 1; A4 <= 6; A4++)
      {
         if (A4 == A5 || A4 == A6) continue;
         for (int A3 = 1; A3 <= 6; A3++)
         {
            if (A3 == A4 || A3 == A5 || A3 == A6) continue;
            for (int A2 = 1; A2 <= 6; A2++)
            {
               if (A2 == A3 || A2 == A4 || A2 == A5 || A2 == A6) continue;
               for (int A1 = 1; A1 <= 6; A1++)
               {
                  if (A1 == A2 || A1 == A3 || A1 == A4 || A1 == A5 || A1 == A6) continue;
for (int B6 = 1; B6 <= 3; B6++)
{
   if (B6 == A6) continue;
   for (int B5 = 1; B5 <= 6; B5++)
   {
      if (B6 == 3 && B5 > 2) continue;
      if (B5 == A5) continue;
      if (B5 == B6) continue;
      for (int B4 = 1; B4 <= 6; B4++)
      {
         if (B4 == A4) continue;
         if (B4 == B5 || B4 == B6) continue;
         for (int B3 = 1; B3 <= 6; B3++)
         {
            if (B3 == A3) continue;
            if (B3 == B4 || B3 == B5 || B3 == B6) continue;
            for (int B2 = 1; B2 <= 6; B2++)
            {
               if (B2 == A2) continue;
               if (B2 == B3 || B2 == B4 || B2 == B5 || B2 == B6) continue;
               for (int B1 = 1; B1 <= 6; B1++)
               {
                  if (B1 == A1) continue;
                  if (B1 == B2 || B1 == B3 || B1 == B4 || B1 == B5 || B1 == B6) continue;
                  
                  int A = A6*100000+A5*10000+A4*1000+A3*100+A2*10+A1;
                  int B = B6*100000+B5*10000+B4*1000+B3*100+B2*10+B1;
                  if (MathMod(A, B) == 0)
                  Print(A6,A5,A4,A3,A2,A1,"/",B6,B5,B4,B3,B2,B1,"=",A/B);
               }
            }
         }
      }
   }
}
               }
            }
         }
      }
   }

Le nombre d'accolades ne correspondait pas. Mais je pense que ce n'est rien, ça peut être réglé en supprimant le dernier.

Expliquez la signification des lignes surlignées. Je ne comprends pas.

 
MetaDriver:

Ouais.

Votre nouveau code est encore plus rapide, mais il y a quelques bogues.

Le nombre d'accolades ne correspondait pas. Mais je pense que ce n'est rien, ça peut être réparé en supprimant le dernier.

Expliquez la signification des lignes séparées. Je ne comprends pas.

Exactement... Conneries ! :))) Et les parenthèses semblent être correctes, j'ai copié du code prêt à l'emploi.

C'est comme ça que ça devrait être :

for (int A6 = 1; A6 <= 6; A6++)
   for (int A5 = 1; A5 <= 6; A5++)
   {
      if (A5 == A6) continue;
      for (int A4 = 1; A4 <= 6; A4++)
      {
         if (A4 == A5 || A4 == A6) continue;
         for (int A3 = 1; A3 <= 6; A3++)
         {
            if (A3 == A4 || A3 == A5 || A3 == A6) continue;
            for (int A2 = 1; A2 <= 6; A2++)
            {
               if (A2 == A3 || A2 == A4 || A2 == A5 || A2 == A6) continue;
               for (int A1 = 1; A1 <= 6; A1++)
               {
                  if (A1 == A2 || A1 == A3 || A1 == A4 || A1 == A5 || A1 == A6) continue;
for (int B6 = 1; B6 <= 3; B6++)
   for (int B5 = 1; B5 <= 6; B5++)
   {
      if (B6 == 3 && B5 > 2) continue;
      if (B5 == B6) continue;
      for (int B4 = 1; B4 <= 6; B4++)
      {
         if (B4 == B5 || B4 == B6) continue;
         for (int B3 = 1; B3 <= 6; B3++)
         {
            if (B3 == B4 || B3 == B5 || B3 == B6) continue;
            for (int B2 = 1; B2 <= 6; B2++)
            {
               if (B2 == B3 || B2 == B4 || B2 == B5 || B2 == B6) continue;
               for (int B1 = 1; B1 <= 6; B1++)
               {
                  if (B1 == B2 || B1 == B3 || B1 == B4 || B1 == B5 || B1 == B6) continue;
                  if (A6 != B6 && A5 != B5 && A4 != B4 && A3 != B3 && A2 != B2 && A1 != B1)
                  {
                     int A = A6*100000+A5*10000+A4*1000+A3*100+A2*10+A1;
                     int B = B6*100000+B5*10000+B4*1000+B3*100+B2*10+B1;
                     if (MathMod(A, B) == 0)
                        Print(A6,A5,A4,A3,A2,A1,"/",B6,B5,B4,B3,B2,B1,"=",A/B);
                  }
               }
            }
         }
      }
   }
               }
            }
         }
      }
   }

De plus, dans MQL5, il accélère un peu la comparaison :

                     if (A > B && MathMod(A, B) == 0)

Mais il est clair que le 125 ms ne rattrape pas son retard.

 

Ou peut-être que tout est en C++ ?
.
Valider la fonction d'un paramètre.
Et si on utilisait la bonne vieille méthode... allouer de la mémoire et mettre en cache un bool
pour toutes les valeurs valides de l'argument ?