[Archive!] Pure mathematics, physics, chemistry, etc.: brain-training problems not related to trade in any way - page 510

 
IgorM:
I don't like to use continue and break operators, but maybe they can help you, especially since a 36-fold if on mql might not work
If it didn't work, I would use continue... But I don't want to bother with it at all. I'd rather create a different algorithm, at least it would be interesting.
 
MaxZ:

And accelerate My code can be broken down if, consisting of a complex 36-entry check condition, into 36 ifs with a simple condition! :)))

I think the code would speed up noticeably, although to know for sure you need to understand the machine instructions, which are the result of compilation.

I ran your code in MT5. It already has short evaluations of logical operators already implemented (built in), so there's no need to break the code into lots of ifs.

In MT4 it is different, this optimization makes sense there. But I did time evaluation in MT5, by short scheme.

 

Accelerated by a factor of 4. Rewrote Validate().

Now it's like this:

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, but it makes sense to optimise the code in the following way. Many times faster! And here MT5 won't help any more.

It's not an idea of course. But I wonder how fast it will work! :))

Also in the code I reduced the range of the divisor values. 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:

Accelerated by a factor of 4. Rewrote Validate().

Now it looks like this:

WorkTime == 200 ms

It's beautiful! Not like mine.

I have an idea to write a column division algorithm. Divide by digits, write down the remainder of division and when the result is greater than 6, do the continue operation. That's exactly what I did this afternoon, when I was going through the five, I divided everything in columns. But it's a long time coming! :))

It's in the hexadecimal number representation that you need to do the optimization, as you have done.

 
MaxZ:

I have an idea to write a column division algorithm. Divide by digits, write down the remainder of the division and if it matches or the result is greater than 6, do the continue operation. That's exactly what I did this afternoon, when I was going through the five, I divided everything in columns. But it's a long time coming! :))

It's in the representation of six-digit numbers that we need to optimize, as you have done.

О! That's not a bad idea. Rewrote it again. 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:

О! That's not a bad idea. Rewritten it again. WorkTime=125 ms

Now the hockey players will definitely stay happy! :)))) I didn't mean it like that though! ;D


How much does the time counter show by My code?


I understand the changes. I just haven't mastered it yet:

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

"Is "|=" a logical OR? The rest is a dead end...

 
MaxZ:
Now the hockey players will be happy for sure! :))))

Yeah.

Your new code is even faster, but there are some bugs there.

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

The number of curly braces didn't add up. But I think that's nothing, it can be fixed by deleting the last one.

Explain the meaning of the highlighted lines. I don't get it.

 
MetaDriver:

Yeah.

Your new code is even faster, but there are some bugs there.

The number of curly braces didn't add up. But I think it's nothing, it can be fixed by deleting the last one.

Explain the meaning of separated lines. I do not understand.

Exactly... Bullshit! :))) And brackets seem to be ok, I copied from ready-made code.

This is how it should be:

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

Also in MQL5 it will speed up comparison a bit:

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

But 125 ms is clearly not catching up.

 

Or maybe it's all in C++?
.
Validate- one parameter function.
How about the old-fashioned way... allocate memory and cache a bool
for all valid values of the argument?