开发者

Optimization of program used for ProjectEuler problem 11

I've been learning to program for quite a bit and it seems that one of the greatest competitions between programmers is how few lines one can do a procedure in. Noticing this trend, I'd like to learn to make my programs a bit tighter, cleaner, and preferring functionality without excess. Here's the code I used to solve ProjectEuler problem 11. It's quite large which kinda worries me when I see code a fourth of its size doing the same thing, hehe.

#include <iostream>

using namespace std;

int array[20][20] = {{8,2,22,97,38,15,0,40,0,75,4,5,7,78,52,12,50,77,91,8},
                        {49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,4,56,62,0},
                        {81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,3,49,13,36,65},
                        {52,70,95,23,4,60,11,42,69,24,68,56,1,32,56,71,37,2,36,91},
                        {22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80},
                        {24,47,32,60,99,3,45,2,44,75,33,53,78,36,84,20,35,17,12,50},
                        {32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70},
                        {67,26,20,68,2,62,12,20,95,63,94,39,63,8,40,91,66,49,94,21},
                        {24,55,58,5,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72},
                        {21,36,23,9,75,0,76,44,20,45,35,14,0,61,33,97,34,31,33,95},
                        {78,17,53,28,22,75,31,67,15,94,3,80,4,62,16,14,9,53,56,92},
          开发者_运维知识库              {16,39,5,42,96,35,31,47,55,58,88,24,0,17,54,24,36,29,85,57},
                        {86,56,0,48,35,71,89,7,5,44,44,37,44,60,21,58,51,54,17,58},
                        {19,80,81,68,5,94,47,69,28,73,92,13,86,52,17,77,4,89,55,40},
                        {4,52,8,83,97,35,99,16,7,97,57,32,16,26,26,79,33,27,98,66},
                        {88,36,68,87,57,62,20,72,3,46,33,67,46,55,12,32,63,93,53,69},
                        {4,42,16,73,38,25,39,11,24,94,72,18,8,46,29,32,40,62,76,36},
                        {20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,4,36,16},
                        {20,73,35,29,78,31,90,1,74,31,49,71,48,86,81,16,23,57,5,54},
                        {1,70,54,71,83,51,54,69,16,92,33,48,61,43,52,1,89,19,67,48},
                        };

int s = 0;

int right()
{
    int a = 1;
    int i = 0;
    int n = 0;
    int r = 0;
    int c = 0;

    for(n = 0;n <= 359;n++)
    {
        if(c <= 16)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[r][(c + i)] << " ";
                a *= array[r][(c + i)];
            };
            //cout << a << " ";
            i = 0; c++;
            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0; r++;};
    };

    return s;
};

int left()
{
    int a = 1;
    int i = 0;
    int n = 0;
    int r = 0;
    int c = 19;

    for(n = 0;n <= 359;n++)
    {
        if(c >= 3)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[r][(c - i)] << " ";
                a *= array[r][(c - i)];
            };
            //cout << a << " ";
            i = 0; c--;
            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 19; r++;};
    };

    return s;
};

int down()
{
    int n = 0;
    int i = 0;
    int r = 0;
    int c = 0;
    int a = 1;

    for(n = 0;n <= 356;n++)
    {
        if(c <= 19)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r + i)][c] << " ";
                a *= array[(r + i)][c];
            };
            //cout << a << " ";
            i = 0; c++;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0;
                if(r <= 16){
                    r++;
                    }else{break;};
        };
    };

    return s;
};

int up()
{
    int n = 0;
    int i = 0;
    int r = 19;
    int c = 0;
    int a = 1;

    for(n = 0;n <= 356;n++)
    {
        if(c <= 19)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r - i)][c] << " ";
                a *= array[(r - i)][c];
            };
            //cout << a << " ";
            i = 0; c++;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0;
                if(r >= 3){
                    r--;
                    }else{break;};
        };
    };

    return s;
};

int diag_left_up()
{
    int n = 0;
    int i = 0;
    int r = 19;
    int c = 19;
    int a = 1;

    for(n = 0;n <= 304;n++)
    {
        if(c >= 3 && r >= 3)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r - i)][(c - i)] << " ";
                a *= array[(r - i)][(c - i)];
            };
           //cout << a << " ";
            i = 0; c--;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 19;
                if(r >= 3){
                    r--;
                    }else{break;};
        };
    };

    return s;
};

int diag_left_down()
{
    int n = 0;
    int i = 0;
    int r = 0;
    int c = 19;
    int a = 1;

    for(n = 0;n <= 304;n++)
    {
        if(c >= 3 && r <= 16)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r + i)][(c - i)] << " ";
                a *= array[(r + i)][(c - i)];
            };
            //cout << a << " ";
            i = 0; c--;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 19;
                if(r <= 16){
                    r++;
                    }else{break;};
        };
    };

    return s;
};

int diag_right_up()
{
    int n = 0;
    int i = 0;
    int r = 19;
    int c = 0;
    int a = 1;

    for(n = 0;n <= 304;n++)
    {
        if(c <= 16 && r >= 3)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r - i)][(c + i)] << " ";
                a *= array[(r - i)][(c + i)];
            };
            //cout << a << " ";
            i = 0; c++;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0;
                if(r >= 3){
                    r--;
                    }else{break;};
        };
    };

    return s;
};

int diag_right_down()
{
    int n = 0;
    int i = 0;
    int r = 0;
    int c = 0;
    int a = 1;

    for(n = 0;n <= 304;n++)
    {
        if(c <= 16 && r <= 16)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r + i)][(c + i)] << " ";
                a *= array[(r + i)][(c + i)];
            };
            //cout << a << " ";
            i = 0; c++;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0;
                if(r <= 16){
                    r++;
                    }else{break;};
        };
    };

    return s;
};

int main()
{
    cout << "Result from right():" << '\t' << right();
    cout << endl;
    cout << "Result from left():" << '\t' << left();
    cout << endl;
    cout << "Result from down():" << '\t' << down();
    cout << endl;
    cout << "Result from up():" << '\t' << up();
    cout << endl;
    cout << "Result from diag_right_up(): " << '\t' << diag_right_up();
    cout << endl;
    cout << "Result from diag_right_down(): " << '\t' << diag_right_down();
    cout << endl;
    cout << "Result from diag_left_up(): " << '\t' << diag_left_up();
    cout << endl;
    cout << "Result from diag_left_down(): " << '\t' << diag_left_down();

    cout << endl << endl << "Greatest result: " << s;

    return 0;
}


The first thing I notice is that you've got a lot of functions that do basically the same thing (with some numbers different). I would investigate adding a couple of parameters to that function, so that you can describe the direction you're going. So for example, instead of calling right() you might call traverse(1, 0) and traverse(0, -1) instead of up().

Your traverse() function declaration might look like:

int traverse(int dx, int dy)

with the appropriate changes inside to adapt its behaviour for different values of dx and dy.


Well, for starters, you only need four of those directions: right/left, up/down, right-up/down-left and right-down/up-left. Multiplication is commutative, so it doesn't matter which direction you go from a given pair (if you find "a b c d" in one direction, you'll find "d c b a" in the opposite direction, and you get the same result when multiplying those numbers together).

Secondly, use more descriptive variable names. A variable name like s is meaningless; something like maximum is better, because that tells you what that variable is for. That doesn't mean you should never ever use a single-character variable name - e.g., using i as a for-loop counter is perfectly fine, and if you're dealing with coordinates, x and y can also be just fine, but when at all possible, you should use a descriptive name to make the code more self-documenting.

Thirdly, you can look into what Greg suggests and refactor your methods to take a direction instead. This would allow you to ditch all of the similar methods (and just call that one method 4 times with different parameters to cover all of the necessary directions).

And finally, you may want to be more consistent about your formatting - I know that can be hard to start doing, but it helps you in the long run. To understand what I mean here, take a good look at this snippet, taken from your down() method:

        if(c <= 19)
        {
            for(i = 0;i <= 3;i++)
            {
                //cout << " " << array[(r + i)][c] << " ";
                a *= array[(r + i)][c];
            };
            //cout << a << " ";
            i = 0; c++;

            if(a > s)
            {
                s = a;
                a = 1;
            };
            //cout << s << " " << endl;
            a = 1;
        }else{c = 0;
                if(r <= 16){
                    r++;
                    }else{break;};
        };

Notice how you place a line break before the opening curly bracket of your ifs, but write }else{ on a single line. Additionally, inside the first else, you have another if-block where you don't place a line break before the curly bracket, and the closing bracket has the same indent level as the block content (r++;). This is quite inconsistent, and makes it harder to read.


static void largestProduct11() {
    int[][] arr = {
        {8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
        {49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 
 62, 0},
        {81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 
 36, 65},
        {52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 
 91},
        {22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 
 13, 80},
        {24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 
 12, 50},
        {32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 
 64, 70},
        {67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 
  21},
        {24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 
 63, 72},
        {21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 
  95},
        {78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 
  92},
        {16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 
  57},
        {86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 
 58},
        {19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 
 40},
        {4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 
   66},
        {88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 
  53, 69},
        {4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 
   36},
        {20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 
 36, 16},
        {20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 
  54},
        {1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 
   48}
    };

    /*
     * |A11 A12 A13 *  *  A1N|
     * |A21 A22 A23 *  *  A2N|
     * |A31 A32 A33       A3N|
     *  *                  *
     *  *                  *
     * |An1 A2N A3N *  *  ANN|
     *
     *    */

    String line;
    int[] temp = new int[4];
    int compre = 1;
    int result = 1;

    for (int i = 0; i < arr.length - 3; i++) { // optimize:- the condition is true 
       // if the remaining index are at least four therefore  the length should be reduced by 
       // three that means only the first 16 members can can satisfy the condition 
        for (int j = 0; j < arr[0].length - 3; j++) {  
            result = arr[i][j] * arr[i + 1][j + 1] * arr[i + 2][j + 2] * arr[i + 3][j + 3];
            if (compre < result) {
                compre = result;
            }

        }
    }
  //
  System.out.println(compre  + " Right sie test  ");
    for (int i = 0; i < arr.length - 3; i++) {
        line = "{";
        for (int j = arr[0].length - 1; j > 3; j--) {
            result = arr[i][j] * arr[i + 1][j - 1] * arr[i + 2][j - 2] * arr[i + 3][j 
 - 3];
            if (compre < result) {
                compre = result;
            }
        }

    }

    System.out.println(compre + " final result");  // solution= 70600674
   
   }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜