Problem 41
コンテンツ
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
What is the largest n-digit pandigital prime that exists?
下のを作ってから気がついたけど、この問題実は7桁の素数をひとつ見つければ終わりだから、
“7654321”の置換を昇順に生成して、素数かチェックして、
素数なら出力、合成数なら次の候補へ
というアルゴリズムが高速なはず。
実装はめんどくさいので省略。置換の昇順作成あたりが。
そう考えると、このプログラムはすげー無駄なことしてる。
import Data.Char import Data.List sieve (_,((p:ps),qs)) = (ps',(ps++ps',filter ((/=).(`mod` p)) qs')) where (ps',qs') = span (<p*p) qs primes = iterate sieve([2],([3],[3,5..]))>>=fst intToList ::Integer -> [Int] intToList = map(digitToInt).show isPandigit p = let li = intToList p in sort li == [1..(length li)] pandigits [] = [] pandigits (p:ps) | isPandigit p = p:(pandigits ps) | otherwise = pandigits ps p041 =maximum.pandigits.takeWhile(<=7654321)$primes
めんどくさいといったが、順列生成はそれはそれで面白いので
なんとなく作ってみた。順列生成速度は速いのかはよく分からないが、
実行は悲しくなるほど速い。
計算量を考えれば当然だが。
import Data.List sieve (_,((p:ps),qs)) = (ps',(ps++ps',filter ((/=).(`mod` p)) qs')) where (ps',qs') = span (<p*p) qs primes = iterate sieve([2],([3],[3,5..]))>>=fst perm ::Eq a =>[a]->Int->[[a]] perm _ = [[]] perm [] _ = [] perm xs@(_:_) (n+1)=concat[map (h:)$perm(delete h xs)n|h<-xs] isPrime ::Integer->Bool isPrime 1 = False isPrime n@(m+1) = isP primes n where isP (p:ps) n | n < p*p = True | mod n p == = False | otherwise = isP ps n p041 = head.filter isPrime .map read.perm "7654321"$ 7
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)