Problem 58 「螺旋素数」 †
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%未満に落ちる最初の辺の長さを求めよ.
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2058
解法
うーん?
一つずつ素数判定してみたらなんか遅い。
not_prime(N):-N<2,!.
not_prime(N):-
between(2,N,D),
(N<D*D -> !,fail;true),
N mod D=:=0,
!.
is_prime(N):-not(not_prime(N)).
conner_check(Size,1):-
!,
Base is (2*Size-3)*(2*Size-3),
between(1,3,M),
P is Base+2*(Size-1)*M,
is_prime(P).
conner_count(Size,Count):-
!,
findall(E,conner_check(Size,E),Primes),
length(Primes,Count).
loopSize(Size,Hit,All):-Hit*10<All,!,
Ans is Size*2-3,
write(Ans).
loopSize(Size,Hit,All):-
conner_count(Size,Add),
!,
Hit1 is Hit+Add,
Size1 is Size+1,
All1 is All+4,
loopSize(Size1,Hit1,All1).
main58:-
loopSize(3,3,5).
0 件のコメント:
コメントを投稿