2014年3月20日木曜日

プロジェクトオイラー Problem 58 「螺旋素数」 †

Problem 58 「螺旋素数」 

1から始めて, 以下のように反時計回りに数字を並べていくと, 辺の長さが7の渦巻きが形成される.
37363534333231
38171615141330
39185431229
40196121128
41207891027
42212223242526
43444546474849
面白いことに, 奇平方数が右下の対角線上に出現する. もっと面白いことには, 対角線上の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 件のコメント:

コメントを投稿