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