[Arşiv] Ticaretle ilgisi olmayan saf matematik, fizik, kimya vb. beyin jimnastiği bulmacaları - sayfa 510

 
MaxZ :

Ve 36 katlı karmaşık bir test koşulundan oluşan if'yi basit bir koşulla 36 if'ye bölerek kodumu hızlandırabilirsiniz! :)))

Kodun gözle görülür şekilde hızlanacağını düşünüyorum, ancak kesin olarak bilmek için derlemeden kaynaklanan makine talimatlarını anlamanız gerekir.

Kodunuzu MT5'te çalıştırdım. İçinde, mantıksal operatörlerin kısa hesaplamaları zaten uygulanmaktadır (yerleşik), bu nedenle kodu birçok if'ye bölmenin bir anlamı yoktur.

MT4'te bu optimizasyonun anlamlı olduğu farklı bir konudur. Ancak kısa bir şemaya göre MT5'te zaman tahmini harcadım.

 

4 kez hızlandırıldı. Validate()'i yeniden yazdı.

Şimdi böyle:

 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 ;
    }
}
Çalışma Süresi == 200ms
 

Korkunç, ancak kodu aşağıdaki gibi optimize etmek mantıklı. Birçok kez daha hızlı! Ve burada MT5 yardımcı olmayacak.

Kesinlikle bir fikir değil. Ama ne kadar hızlı çalıştığı ilginç! :))

Ayrıca kodda bölen değerlerinin aralığını azalttım . 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 :

4 kez hızlandırıldı. Validate()'i yeniden yazdı.

Şimdi böyle:

Çalışma Süresi == 200ms

Güzel çıktı! Benim gibi değil.

Bir sütuna bölme algoritması yazma fikri var. Parça parça bölün, bölmenin kalanını yazın ve sonuç eşleşirse veya sonuç 6'dan büyükse devam işlemini yapın. Bu öğleden sonra, beşten geçerken her şeyi bir sütuna böldüğümde tam olarak bunu yaptım. Ama uzun zamandır! :))

Altı basamaklı sayıların gösteriminde sizin tarafınızdan yapıldığı gibi optimizasyon yapılması gerekmektedir.

 
MaxZ :

Bir sütuna bölme algoritması yazma fikri var. Parça parça bölün, bölmenin kalanını yazın ve sonuç eşleşirse veya sonuç 6'dan büyükse devam işlemini yapın. Bu öğleden sonra, beşi sıraladığımda, her şeyi bir sütuna böldüğümde tam olarak bunu yaptım. Ama uzun zamandır! :))

Altı basamaklı sayıların gösteriminde sizin tarafınızdan yapıldığı gibi optimizasyon yapılması gerekmektedir.

Ö! Fikir güzel. Yeniden yazdı. Çalışma Süresi=125ms

 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 :

Ö! Fikir güzel. Yeniden yazdı. Çalışma Süresi=125ms

Şimdi hokey oyuncuları kesinlikle mutlu olacak! :)))) Gerçi tam olarak bunu demek istemedim! ;D


Ve koduma göre zaman sayacı ne kadar gösteriyor?


Değişiklikleri anlıyorum. Henüz ona ulaşamadım:

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

"|=" - mantıksal "VEYA"? Ve sonra tam bir karmaşa...

 
MaxZ :
Şimdi hokey oyuncuları kesinlikle mutlu olacak! :))))

Evet.

Yeni kodunuz daha da hızlı ama hatalar var.

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

Kıvrımlı parantezlerin sayısı eşleşmedi. Ama çöp gibi görünüyor, ikincisi kaldırılarak tedavi ediliyor.

Vurgulanan satırların anlamını açıklayın. yakalayamıyorum.

 
MetaDriver :

Evet.

Yeni kodunuz daha da hızlı ama hatalar var.

Kıvrımlı parantezlerin sayısı eşleşmedi. Ama çöp gibi görünüyor, ikincisi kaldırılarak tedavi ediliyor.

Vurgulanan satırların anlamını açıklayın. yakalayamıyorum.

Kesinlikle... Brad! :))) Ve norm gibi parantezlerle bitmiş koddan kopyaladım.

Bunun gibi olmalı:

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

Ayrıca MQL5'te karşılaştırmayı biraz hızlandıracaktır:

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

Ama 125 ms kesinlikle yetişmek değil.

 

Ya da belki C++?
.
Validate, tek bir parametre işlevidir.
Belki eski moda yol ... bellek tahsis et ve bool önbelleğini al
tüm geçerli argüman değerleri için?

 

MaxZ :

Değişiklikleri anlıyorum. Henüz ona ulaşamadım:

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

"|=" - mantıksal "VEYA"? Ve sonra tam bir karmaşa...

"|=" - bu durumda bit düzeyinde "veya". Bu şey, A[i]'ye eşit konumlarda bitleri XX kadar yükseltir.

Ve döngüden sonra, birinciden altıncıya kadar olan tüm bitler 1'e eşit olursa, bu, 1'den 6'ya kadar olan tüm rakamların X sayısında tam olarak bir kez buluştuğu anlamına gelir.

0x7E - 1111110 ikili sayısının onaltılık gösterimi. (sağ bit sıfırdır)