X

C#でプロジェクトオイラーを解く(問題32「パンデジタル積」)

どーも、みつおです。

問題

すべての桁に 1 から n が一度だけ使われている数をn桁の数がパンデジタル (pandigital) であるということにしよう: 例えば5桁の数 15234 は1から5のパンデジタルである.

7254 は面白い性質を持っている. 39 × 186 = 7254 と書け, 掛けられる数, 掛ける数, 積が1から9のパンデジタルとなる.

掛けられる数/掛ける数/積が1から9のパンデジタルとなるような積の総和を求めよ.

HINT: いくつかの積は, 1通り以上の掛けられる数/掛ける数/積の組み合わせを持つが1回だけ数え上げよ.

出典:Problem32

解答

using System;
using System.Collections.Generic;
using System.Linq;

namespace Problem32
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Solve());
            Console.ReadLine();
        }

        private static long Solve()
        {
            long ret = 0;
            List<long> pandigilist = new List<long>();
            long pandigi = 0;

            //a × b = c が9桁以内であるから
            //5桁 × 1 = 5桁 は11文字になるので除外
            for(long a = 1; a <= 9876; a++)
            {
                //パンデジタル積か判定
                if (IsPandgital(a, ref pandigi)) pandigilist.Add(pandigi);
            }

            //重複削除
            var distpandigilist = pandigilist.Distinct();

            //積の総和
            ret = distpandigilist.Sum();

            return ret;
        }

        private static bool IsPandgital(long a, ref long c)
        {
            bool ret = false;

            for(long b = 1; b <= 9876; b++)
            {
                //積
                c = a * b;

                //積が5桁以上ならパンデジタルでない
                if (9999 < c) return false;
                else if (IsPandigital(a, b, c)) return true;
            }

            return ret;
        }

        private static bool IsPandigital(long a,long b,long c)
        {
            bool ret;

            //文字列に変換
            string strdata = a.ToString() + b.ToString() + c.ToString();

            //パンデジタル判定
            Predicate<string> IsPandigi = A => A.OrderBy(B => B).SequenceEqual("123456789");

            //文字の長さが 9 であればパンデジタル判定
            ret = strdata.Length == 9 && IsPandigi(strdata.ToString());

            return ret;
        }
    }
}

 

出力

45228

みつお: