どーも、みつおです。
問題
すべての桁に 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