Help us understand the problem. What is going on with this article?

【C#】Project Euler 11,12,13問目

More than 1 year has passed since last update.

はじめに

C#を用いてProjectEulerに挑戦している人の記録です。VisualStudio2017で、1つのフォームアプリの中に問題番号のボタンを作成し、そのボタンをクリックすると結果をラベルに表示するという形式でやっています。

11問目

次の数字の表の、上下左右斜めのいずれかの方向で連続する4つの数字の積のうち最大のものを求めよ

 private void button11_Click(object sender, EventArgs e)
        {           
            int[,] NumberString;
            NumberString = new int[20, 20] {
       { 08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08},
       { 49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00},
       { 81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65},
       { 52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 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, 03, 45, 02, 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, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21},
       { 24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72},
       { 21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95},
       { 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92},
       { 16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57},
       { 86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58},
       { 19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40},
       { 04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66},
       { 88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69},
       { 04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36},
       { 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16},
       { 20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54},
       { 01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48}
            };
            int Vertical = 0;
            int Horizontal = 0;
            int RightDiagonal = 0;
            int LeftDiagonal = 0;
            int MaxValue = 0;
             for (int i = 0; i <= NumberString.GetUpperBound(0); i++)
            {
                for (int j = 0; j <= NumberString.GetUpperBound(1); j++)
                {
                    if (i + 3 <= NumberString.GetUpperBound(0)) { 
                        Vertical = NumberString[i, j] * NumberString[i + 1, j] * NumberString[i + 2, j] * NumberString[i + 3, j];
                    }
                    if (j + 3 <= NumberString.GetUpperBound(1))
                    {
                        Horizontal = NumberString[i, j] * NumberString[i, j + 1] * NumberString[i, j + 2] * NumberString[i, j + 3];
                    }
                    if (i + 3 <= NumberString.GetUpperBound(0) && j + 3 <= NumberString.GetUpperBound(1))
                    {
                        RightDiagonal = NumberString[i, j] * NumberString[i + 1, j + 1] * NumberString[i + 2, j + 2] * NumberString[i + 3, j + 3];
                    }
                    if (i < 17 && j > 2)
                    {
                        LeftDiagonal = NumberString[i, j] * NumberString[i + 1, j - 1] * NumberString[i + 2, j - 2] * NumberString[i + 3, j - 3];
                    }
                    int Max = Max4(Vertical, Horizontal, RightDiagonal, LeftDiagonal);
                    if (MaxValue < Max) MaxValue = Max;
                }
            }
            label1.Text = "Answer = " + MaxValue;
        }

 public static int Max4(int a, int b, int c, int d)
        {
            int Max = a;
            Max = Math.Max(Max, b);
            Max = Math.Max(Max, c);
            Max = Math.Max(Max, d);
            return Max;
        }

表を2次元配列で宣言し、インデックスを操作することで上下左右斜めの数字4つを取り出し、積を計算して最大値を計算しています。/のような方向に進む時のインデックス操作は考える必要がありました。素直に条件判定を繰り返したので効率が悪そうです。

12問目

三角数とは、1からその番目の数までを足したものである。例:7番目の三角数:1+2+3+4+5+6+7=28
三角数の7番目までの数列:1, 3, 6, 10, 15, 21, 28
500個より多く約数をもつ最初の三角数を求めよ

       private void button12_Click(object sender, EventArgs e)
        {
            int TriangularNumber = 0;
            int i = 1;
            while (true)
            {
                int Exp = 0;
                TriangularNumber += i;
                int Number = TriangularNumber;
                int NumberOfPrime = 1;

                for (int j = 2; Number >= j; j++)
                {
                    while (Number % j == 0)
                    {
                        Number /= j;
                        Exp++;
                    }
                    NumberOfPrime *= (1 + Exp);
                    Exp = 0;
                }
                if (NumberOfPrime > 500) { break; }
                i++;
            }
            label1.Text = "Answer = " + TriangularNumber;
        }

三角数を計算し、その数を2から順に割っていき、割り切れる数の個数を計算し、(1も約数なので1を足している)、500個よりも多かったら無限ループを抜けるという方法でやりました。

13問目

50桁の数字100個の合計の上から10桁(この数字は問題には書いてあるが、あまりにも巨大なため内容をデスクトップのa.txtから読み込んでいる)

 private void button13_Click(object sender, EventArgs e)
        {
 string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\a.txt";
            Encoding utf8 = Encoding.GetEncoding("utf-8");
            string[] NumberString;
            NumberString = new string[100];

            using (var reader = new StreamReader(path, utf8))
            {
                try
                {
                    for (int i = 0; i < 100; i++)
                    {
                        NumberString[i] = reader.ReadLine();
                    }
                }
                catch (Exception ex)
                {

                }
            }
            long Number = 0;
            long digit = 0;

            for (int Div = 40; Div >= 0; Div -= 10)
            {
                Number = digit;
                for (int i = 0; i < 100; i++)
                {
                    Number += long.Parse(NumberString[i].Substring(Div, 10));
                }
                if (Div != 0)
                {
                    digit = Number / (long)Math.Pow(10, 10);
                }
                else
                {
                    string Answer = Number.ToString();
                    label1.Text = "Answer = " + Answer.Substring(0, 10);
                }
            }
        }

100個の数字の桁の末尾から10個ずつ(41~50桁目、31~40桁目、21~30桁目、11~20桁目、1~10桁目)取り出し、それぞれの桁目ごとの合計を出し、繰上りを足しながら最上位まで行き、上から10桁を取り出すという方法でやりました。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away