[Archiv!] Reine Mathematik, Physik, Chemie usw.: Gehirntrainingsprobleme, die in keiner Weise mit dem Handel zusammenhängen - Seite 510

 
IgorM:
Ich verwende nicht gerne continue- und break-Operatoren, aber vielleicht können sie Ihnen helfen, zumal eine 36-fache Verschachtelung von if in mql möglicherweise nicht "funktioniert".
Wenn es nicht funktionieren würde, würde ich continue... Aber ich will mich gar nicht damit befassen. Ich würde lieber einen anderen Algorithmus entwickeln, das wäre zumindest interessant.
 
MaxZ:

Und beschleunigen Mein Code kann wenn, bestehend aus einer komplexen 36-Eingabe-Prüfbedingung, in 36 ifs mit einer einfachen Bedingung zerlegt werden! :)))

Ich denke, der Code wird sich merklich beschleunigen, aber um das sicher zu wissen, muss man die Maschinenbefehle verstehen, die das Ergebnis der Kompilierung sind.

Ich habe Ihren Code in MT5 ausgeführt. Kurze Auswertungen von logischen Operatoren sind bereits implementiert (eingebaut), so dass es nicht nötig ist, den Code in viele ifs aufzuteilen.

Im MT4 ist das anders, dort macht diese Optimierung Sinn. Aber ich habe die Zeitauswertung im MT5 nach einem kurzen Schema durchgeführt.

 

Um den Faktor 4 beschleunigt. Validate() umgeschrieben.

Jetzt ist es so:

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
 

Schrecklich, aber es macht Sinn, den Code auf folgende Weise zu optimieren. Um ein Vielfaches schneller! Und hier wird MT5 nicht mehr helfen.

Das ist natürlich keine Idee. Aber ich frage mich, wie schnell das funktionieren wird! :))

Außerdem habe ich im Code den Bereich der Divisorwerte verringert. 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:

Um den Faktor 4 beschleunigt. Validate() umgeschrieben.

Jetzt sieht es so aus:

WorkTime == 200 ms

Es ist wunderschön! Nicht wie meine.

Ich habe die Idee, einen Algorithmus zur Spaltenteilung zu schreiben. Dividiere durch Ziffern, schreibe den Rest der Division auf und wenn das Ergebnis größer als 6 ist, führe die Fortsetzungsoperation aus. Das ist genau das, was ich heute Nachmittag gemacht habe, als ich die fünf durchgegangen bin, ich habe alles in Spalten aufgeteilt. Aber es hat lange gedauert! :))

Bei der hexadezimalen Zahlendarstellung müssen Sie die Optimierung vornehmen, wie Sie es getan haben.

 
MaxZ:

Ich habe die Idee, einen Algorithmus zur Spaltenteilung zu schreiben. Dividiere durch Ziffern, schreibe den Rest der Division auf und wenn er übereinstimmt oder das Ergebnis größer als 6 ist, führe die Fortsetzungsoperation aus. Das ist genau das, was ich heute Nachmittag gemacht habe, als ich die fünf durchgegangen bin, ich habe alles in Spalten aufgeteilt. Aber es hat lange gedauert! :))

Es ist die Darstellung von sechsstelligen Zahlen, die wir optimieren müssen, wie Sie es getan haben.

О! Das ist keine schlechte Idee. Ich habe es noch einmal umgeschrieben. 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:

О! Das ist keine schlechte Idee. Ich habe es noch einmal umgeschrieben. WorkTime=125 ms

Jetzt werden die Eishockeyspieler bestimmt glücklich sein! :)))) So habe ich es aber nicht gemeint! ;D


Wie viel zeigt der Zeitzähler von My code an?


Ich verstehe die Änderungen. Ich habe es nur noch nicht gemeistert:

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

"Ist "|=" ein logisches ODER? Der Rest ist eine Sackgasse...

 
MaxZ:
Jetzt werden sich die Eishockeyspieler sicher freuen! :))))

Ja, ja.

Ihr neuer Code ist sogar noch schneller, aber er enthält noch einige Bugs.

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

Die Anzahl der geschweiften Klammern stimmte nicht überein. Aber ich denke, das ist kein Problem, es kann durch Löschen des letzten Eintrags behoben werden.

Erklären Sie die Bedeutung der hervorgehobenen Zeilen. Das verstehe ich nicht.

 
MetaDriver:

Ja, ja.

Ihr neuer Code ist sogar noch schneller, aber er enthält noch einige Bugs.

Die Anzahl der geschweiften Klammern stimmte nicht überein. Aber ich denke, es ist nichts, es kann durch Löschen des letzten Eintrags behoben werden.

Erklären Sie die Bedeutung der getrennten Linien. Das verstehe ich nicht.

Ganz genau... Blödsinn! :))) Und die Klammern scheinen in Ordnung zu sein, ich habe von fertigem Code kopiert.

So sollte es sein:

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

Auch in MQL5 wird es den Vergleich etwas beschleunigen:

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

Aber 125 ms sind eindeutig nicht aufholbar.

 

Oder ist vielleicht alles in C++?
.
Validieren - Funktion mit einem Parameter.
Wie wäre es mit der altmodischen Methode... Speicher zuweisen und einen bool zwischenspeichern
für alle gültigen Werte des Arguments?