のてすきあ − 完全独習非プログラマー −

Haskell で Project Euler を解く素人遊び

Problem 41

ある数が n-digit pandigital であるとは、1からnまでの数字を1回ずつ使って構成されていることを意味する。例えば2143は4-digit pandigital であり、かつ素数でもある。最大のn-digit pandigitalな素数を求める。

 存在するn-digit pandigital 素数の中で最大のものを求める問題である。探索の上限が与えられていないところが考えどころであるが、pandigital の定義から、求めるべき素数は 987654321以下である。この上限をできるだけ引き下げたいが、すぐに気付くのは、9-digit pandigital な素数はないということである。なぜなら9-digit pandigital な数は各桁の合計が 1+2+3+...+9 = 45になるが、各桁の合計が9の倍数となる数は、それ自身が9の倍数だからである。同じ理由で8-digit pandigital な素数もない。よって、探索の上限は7654321まで引き下げられる。

 ここからは、2通りの攻め方が考えられる。1つは7654321までの素数の中からpandigitalな数を拾い上げる方法。もう1つは、pandigitalな数の中から素数を拾い上げる方法。いずれでも答えが出るが、計算が圧倒的に速いのは後者である。なぜなら素数の列挙は基本的に非効率だからである。  ということで後者を採用した。知りたいのは最大の数なので7桁の数から探索するが、7桁のpandigitalな数の中に素数が必ずいるとは限らないので、7桁の中に見つからない時は6桁、見つからなければ5桁…と下へ下へ探索することにした。(実際は7桁の中に答えが見つかる) 

permutationsも便利である☆