Problem 58 - Project Euler
30分プログラム、その336。Problem 58 - Project Euler。
1から初めて, 以下のように反時計回りに数字を並べていくと, 辺の長さが7の渦巻きが形成される.
37 36 35 34 33 32 31 38 17 16 15 14 13 30 39 18 5 4 3 12 29 40 19 6 1 2 11 28 41 20 7 8 9 10 27 42 21 22 23 24 25 26 43 44 45 46 47 48 49 面白いことに, 奇平方数が右下の対角線上に出現する. もっと面白いことには, 対角線上の13個の数字のうち, 8個が素数である. ここで割合は8/13 ≈ 62%である.
渦巻きに新しい層を付け加えよう. すると辺の長さが9の渦巻きが出来る. 以下, この操作を繰り返していく. 対角線上の素数の割合が10%未満に落ちる最初の辺の長さを求めよ.
前に解いたProblem28 - みずぴー日記と類似していたので、コードを流用した。
使い方
$ ./problem58 0.10001906214258482 ... 13118 0.10001524622655893 13119 0.1000076225322052 13120 0.1 13121 9.999237862967762e-2 13121
ソースコード
import Debug.Trace diag size = if size == 1 then take 1 xs else take 4 xs where xs = [a,a+k..] k = size - 1 prev = size - 2 a = prev * prev + k squares = map diag [3,5..] isPrime 1 = False isPrime 2 = True isPrime n = and $ map (\x-> n `mod` x /= 0) [2..m] where m = ceiling $ sqrt $ fromInteger n solve (prime,all,n) (x:xs) = let all' = all + length (trace (show n) x) prime' = prime + length (filter isPrime x) ratio = toF prime' / toF all' in if (trace (show ratio) ratio) < 0.1 then 2*n-1 else solve (prime',all',n+1) xs where toF = fromInteger.toInteger main = print $ solve (0,0,1) squares