Project Euler 50,51,52問目

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

41 = 2 + 3 + 5 + 7 + 11 + 13.
100未満の素数を連続する素数の和で表したときにこれが最長になる.

同様に, 連続する素数の和で1000未満の素数を表したときに最長になるのは953で21項を持つ.

100万未満の素数を連続する素数の和で表したときに最長になるのはどの素数か?

```CSharp
private void button50_Click(object sender, EventArgs e)
        {
            var PrimeList = new List<int>(Eratosthenes(1000000));
            int MaxCount = 0;
            int Answer = 0;
            for (int i = 1001; i < PrimeList.Count; i++)
            {
            NextLoop:;
                for (int Head = 1; Head <= i; Head++)
                {
                    int Number = PrimeList[i];
                    int Count = 0;
                    for (int j = Head; Number > 0; j++)
                    {
                        Number -= PrimeList[j];
                        Count++;
                        if (Number == 0)
                        {
                            if (MaxCount < Count)
                            {
                                MaxCount = Count;
                                Answer = PrimeList[i];
                                goto NextLoop;
                            }
                        }
                    }
                }
            }
            label1.Text = "Answer = " + Answer;
        }
```
1000000以下の素数をリストに入れ、判定する素数がそれより小さい素数を引いていって0になったら最長かどうか判定、最長なら答えとして次のループに進むという仕組みです。
C#では2重ループを抜ける方法がないため、gotoを使うことになりました。
#51問目
*3の第1桁を置き換えることで, 13, 23, 43, 53, 73, 83という6つの素数が得られる.

56**3の第3桁と第4桁を同じ数で置き換えることを考えよう. この5桁の数は7つの素数をもつ最初の例である: 56003, 56113, 56333, 56443, 56663, 56773, 56993. よって, この族の最初の数である56003は, このような性質を持つ最小の素数である.

桁を同じ数で置き換えることで8つの素数が得られる最小の素数を求めよ. (注:連続した桁でなくても良い)

```CSharp
private void button51_Click(object sender, EventArgs e)
        {
            var PrimeList = new List<int>(Eratosthenes(1000000));
            PrimeList.RemoveAll(X => X % 2 == 0);
            PrimeList.RemoveAll(X => X < 100000);
            List<string> PatternList = new List<string>();
            foreach (char EachChar in "123456789*")
            {
                PatternList.Add(EachChar.ToString());
            }
            for (int i = 2; i <= 6; i++)
            {
                foreach (string EachStr in PatternList.FindAll(X => X.Length + 1 == i))
                {
                    foreach (char EachChar in "0123456789*")
                    {
                        PatternList.Add(EachStr + EachChar.ToString());
                    }
                }
            }
            PatternList = PatternList.FindAll(X => X.Contains('*'));
            PatternList.RemoveAll(X => X.EndsWith("*"));
            PatternList.RemoveAll(X => X.EndsWith("0") || X.EndsWith("2") || X.EndsWith("4") || X.EndsWith("6") || X.EndsWith("8"));
            PatternList.RemoveAll(X => X.Length < 6);


            foreach (string EachPattern in PatternList)
            {
                int count = 0;
                string ReplaceNumber = "9876543210";
            NextPattern:;
                for (int i = 0; i <= ReplaceNumber.Length - 1; i++)
                {
                    if (EachPattern.StartsWith("*") && ReplaceNumber[i] == 0) continue;
                    int JudgeNumber = int.Parse(EachPattern.Replace('*', ReplaceNumber[i]));
                    if (PrimeList.Contains(JudgeNumber))
                    {
                        count++;
                        if (i == 4 && count < 1) goto NextPattern;
                        if (count == 8)
                        {
                            label1.Text = "Answer=" + JudgeNumber;
                            break;
                        }
                    }
                }
            }
        }
```
上の部分では、123456789*の6桁までのすべての組み合わせをリストに入れて、その数字の最後が*の場合、偶数の場合、6桁より小さい場合を消しています。
その後、下部分で*の部分を数字で置き換えて素数になった数をカウントし、8個になったら答えとしています。

#52問目
125874を2倍すると251748となる. これは元の数125874と順番は違うが同じ数を含む.

2x, 3x, 4x, 5x, 6x が x と同じ数を含むような最小の正整数 x を求めよ.

```CSharp
private void button52_Click(object sender, EventArgs e)
        {
            for (int i = 10; i < int.MaxValue; i++)
            {
                string NumberString = i.ToString();
                var List = new List<char>(NumberString);
                List.Sort();
                int EqualCount = 0;
                for (int j = 2; j <= 6; j++)
                {
                    int CharEqualCount = 0;
                    string NumberString2 = (i * j).ToString();
                    var List2 = new List<char>(NumberString2);
                    List2.Sort();
                    for (int k = 0; k < List.Count; k++)
                    {
                        if (List[k] == List2[k])
                        {
                            CharEqualCount++;
                        }
                    }
                    if (CharEqualCount == List.Count)
                    {
                        EqualCount++;
                    }
                    else { break; }
                    if (EqualCount == List.Count - 1)
                    {
                        label1.Text = "Answer=" + NumberString;
                        goto end;
                    }
                }

            }
        end:;
        }
```
int型の最大値までの数字を考えます。文字列として考え、2~6倍した数字も文字列とします。すべての文字列をソートして比べ、すべてが同じであれば答えとしてループを抜けます。