[Archivo] Matemáticas puras, física, química, etc.: problemas de entrenamiento cerebral no relacionados con el comercio de ninguna manera - página 510

 
IgorM:
No me gusta usar los operadores continue y break, pero quizás puedan ayudarte, sobre todo porque un 36-fold if en mql podría no funcionar
Si no funcionara, usaría continuar... Pero no quiero molestarme en absoluto. Preferiría crear un algoritmo diferente, al menos sería interesante.
 
MaxZ:

¡Y acelera Mi código se puede descomponer si, consistente en una compleja condición de comprobación de 36 entradas, en 36 ifs con una simple condición! :)))

Creo que el código se acelerará notablemente, aunque para saberlo con seguridad hay que entender las instrucciones de la máquina, que son el resultado de la compilación.

He ejecutado tu código en MT5. Ya tiene implementadas las evaluaciones cortas de los operadores lógicos (incorporados), por lo que no hay necesidad de romper el código en un montón de ifs.

En MT4 es diferente, esta optimización tiene sentido allí. Pero hice la evaluación del tiempo en MT5, por el esquema corto.

 

Acelerado por un factor de 4. Reescribir Validar().

Ahora es así:

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, pero tiene sentido optimizar el código de la siguiente manera. Muchas veces más rápido. Y aquí MT5 ya no ayuda.

No es una idea, por supuesto. Pero me pregunto cómo de rápido funcionará. :))

También en el código he reducido el rango de los valores del divisor. 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:

Acelerado por un factor de 4. Reescribir Validar().

Ahora se ve así:

WorkTime == 200 ms

¡Es hermoso! No como el mío.

Tengo una idea para escribir un algoritmo de división de columnas. Divide entre dígitos, escribe el resto de la división y cuando el resultado sea mayor que 6, haz la operación de continuar. Eso es exactamente lo que he hecho esta tarde, cuando estaba revisando los cinco, he dividido todo en columnas. ¡Pero si hace falta mucho tiempo! :))

Es en la representación numérica hexadecimal donde hay que hacer la optimización, como tú has hecho.

 
MaxZ:

Tengo una idea para escribir un algoritmo de división de columnas. Divide entre dígitos, escribe el resto de la división y si coincide o el resultado es mayor que 6, haz la operación de continuar. Eso es exactamente lo que he hecho esta tarde, cuando estaba revisando los cinco, he dividido todo en columnas. ¡Pero si hace falta mucho tiempo! :))

Es en la representación de los números de seis dígitos donde hay que optimizar, como tú has hecho.

¡О! No es una mala idea. Lo volví a escribir. WorkTime=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:

¡О! No es una mala idea. Vuelve a escribirlo. Tiempo de trabajo=125 ms

¡Ahora los jugadores de hockey estarán definitivamente contentos! :)))) ¡Pero no quería decir eso! ;D


¿Cuánto muestra el contador de tiempo por Mi código?


Entiendo los cambios. Pero aún no lo domino:

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

"¿Es "|=" un OR lógico? El resto es un callejón sin salida...

 
MaxZ:
¡Ahora los jugadores de hockey estarán contentos seguro! :))))

Sí.

Su nuevo código es aún más rápido, pero hay algunos errores.

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);
               }
            }
         }
      }
   }
}
               }
            }
         }
      }
   }

El número de llaves rizadas no cuadra. Pero creo que no es nada, se puede arreglar borrando el último.

Explica el significado de las líneas resaltadas. No lo entiendo.

 
MetaDriver:

Sí.

Su nuevo código es aún más rápido, pero hay algunos errores.

El número de llaves rizadas no cuadra. Pero creo que no es nada, se puede arreglar borrando el último.

Explica el significado de las líneas separadas. No lo entiendo.

Exactamente... ¡Mentira! :))) Y los paréntesis parecen estar bien, he copiado de un código ya hecho.

Así es como debe ser:

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);
                  }
               }
            }
         }
      }
   }
               }
            }
         }
      }
   }

También en MQL5 acelerará un poco la comparación:

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

Pero está claro que 125 ms no está al día.

 

¿O tal vez todo esté en C++?
.
Función de validación de un parámetro.
¿Qué tal a la antigua usanza...? asignar memoria y almacenar en caché un bool
para todos los valores válidos del argumento?