Goldbachパーティション


18

ゴールドバッハ予想では、2より大きいすべての偶数は2つの素数の合計として表現できると述べています。例えば、

4 = 2 + 2
6 = 3 + 3
8 = 5 + 3

ただし、10に達すると、興味深いことが起こります。10と書けるだけでなく、

5 + 5

しかし、次のように書くこともできます

7 + 3

10は2つの素数の和として2 つの方法で表現できるため、10 の「ゴールドバックパーティション」はであると言います2。またはより一般的には、

数のゴールドバッハパーティションが書き込みの異なる方法の合計数であるn = p + q場合pq素数であり、そしてp >= q

あなたの課題は、番号のGoldbachパーティションを見つけるプログラムまたは関数を書くことです。現在、技術的には「Goldbachパーティション」という用語は偶数を指すためにのみ使用されています。ただし、p> 2が素数の場合、奇数の整数p + 2は2つの素数の和として表現できるため、これをすべての正の整数(A061358)に拡張します。

入力は常に正の整数であり、関数の引数と戻り値、STDINとSTDOUT、ファイルの読み取りと書き込みなど、許可されているデフォルトのメソッドのいずれかで入力と出力を受け取ることができます。

100までの正の整数のGoldbachパーティションは次のとおりです。

0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 2, 1, 2, 0, 2, 1, 2, 1, 3, 0, 3, 1,
3, 0, 2, 0, 3, 1, 2, 1, 4, 0, 4, 0, 2, 1, 3, 0, 4, 1, 3, 1, 4, 0, 5, 1, 4,
0, 3, 0, 5, 1, 3, 0, 4, 0, 6, 1, 3, 1, 5, 0, 6, 0, 2, 1, 5, 0, 6, 1, 5, 1,
5, 0, 7, 0, 4, 1, 5, 0, 8, 1, 5, 0, 4, 0, 9, 1, 4, 0, 5, 0, 7, 0, 3, 1, 6

いつものように、標準的な抜け穴が適用され、バイト単位の最短回答が勝ちます!


1
あなたはいつもそのような素晴らしい挑戦を思いつきます:
ルイスメンドー

回答:


6

ゼリー、8 バイト

_ÆRÆPSHĊ

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

_ÆRÆPSHĊ  Main link. Argument: n (positive integer)

 ÆR       Prime range; yield [2, 3, 5, ..., n].
_         Subtract all primes in this range from n.
   ÆP     Compute the primality of the resulting differences.
          This returns 1 for each prime p such that n - p is also prime.
     S    Compute the sum of the resulting Booleans.
      H   Divide it by 2, since [p, n - p] and [n - p, p] have both been counted.
       Ċ  Ceil; round the resulting quotient up (needed if n = 2p).

ああ、はるかに良い:D
ジョナサンアラン

5

Python 2、76バイト

g=lambda n,k=2:n/k/2and all(x%i for x in[k,n-k]for i in range(2,x))+g(n,k+1)

再帰から這い上がっk=2n/2両方の値まで加算し、kそしてn-kプライムあるが。n代わりに同時にカウントダウンするのは良いことですが、これには問題がk=0ありk=1、誤ってプライムと呼ばれます:

g=lambda n,k=0:n/k and all(x%i for x in[k,n]for i in range(2,x))+g(n-1,k+1)

素数チェックは試行分割で、両方kn-k一緒にチェックすることで短縮されます。これは、ウィルソンの定理ジェネレーター(79バイト)を使用するよりも短いことがわかりました。

f=lambda n,k=1,P=1,l=[]:n/k and P%k*(n-k in l+P%k*[k])+f(n,k+1,P*k*k,l+P%k*[k])

このアイデアは、上半分に到達するまでに下半分のすべての素数のリストをチェックすることですが、中間点についてはk=n/2n-kリストに追加する時間がありません。k。反復バージョンはこれを回避しますが、82バイトです:

n=input()
s=P=k=1;l=[]
while k<n:l+=P%k*[k];s+=P%k*(n-k in l);P*=k*k;k+=1
print~-s

5

MATL、8バイト

tZq&+=Rz

オンラインでお試しください!

説明

8例として入力を検討する

      % Take input implicitly
t     % Duplicate
      % STACK: 8, 8
Zq    % All primes up to that number
      % STACK: 8, [2 3 5 7]
&+    % Matrix with all pairwise additions
      % STACK: 8, [4  5  7  9
                   5  6  8 10
                   7  8 10 12
                   9 10 12 14]
=     % True for entries that equal the input
      % STACK: [0 0 0 0
                0 0 1 0
                0 1 0 0
                0 0 0 0]
R     % Extract upper triangular part (including diagonal). 
      % This removes pairs that are equal up to order
      % STACK: [0 0 0 0
                0 0 1 0
                0 0 0 0
                0 0 0 0]
z     % Number of nonzero entries
      % STACK: 1
      % Display implicitly

コードのわずかに変更されたバージョンを使用して、シーケンスグラフを観察することは興味深いです:

:"@       % Input n implicitly. For each k from 1 to n, push k
tZq&+=Rz  % Same code as above. Pushes the result for each k
]v'.'&XG  % End. Concatenate all results into a vector. Plot as dots

入力の場合10000、結果は

ここに画像の説明を入力してください

MATL Onlineで試すことができます([実行]ボタンが押されても[キル]に変わらない場合はページを更新します)。入力用のグラフを作成するには、約25秒かかります3000。数千を超える入力はタイムアウトします。


1
そのUpper triangular partトリックは本当にクールです!
DJMcMayhem

3

JavaScript(ES6)、77 73 70バイト

@Arnauldのおかげで3バイト節約

f=(n,x=n)=>--x<2||n%x&&f(n,x)
g=(a,b=a>>1)=>b>1?f(b)*f(a-b)+g(a,b-1):0

f素数テスト関数です。関連する関数はgです。

fn-1から再帰的にカウントダウンすることにより機能します。各段階の制御フローは次のようになります。

  • x<2||場合X <2 、数が素数です。1を返します。
  • n%x&&それ以外の場合、n mod x = 0の場合、数値は素数ではありません。戻りn%xます。
  • f(n,x-1)それ以外の場合、数値は素数である場合とそうでない場合があります。xをデクリメントして、再試行してください。

g制御フローはそれほど多くありませんが、同様の方法で動作します。範囲[2、floor(a / 2)]の各整数bについてf(b)f(ab)を乗算し、結果を合計することにより機能します。これにより、ペアの両方の数が素数であるaに合計されるペアの数が得られます。これはまさに必要なものです。


以来a正である、b=a>>1あなたにバイトを保存する必要があります。
アーナルド

@Arnauldありがとう!私は覚えていたはず>>のオペレータ...
ETHproductions

素数テスト関数については、できますかf=(n,x=n)=>--x<2||n%x&&f(n,x)
アーナルド

@Arnauldそれは天才です、ありがとう:)
ETHproductions

2

05AB1E10 8バイト

非常に非効率的です。

D!f-pO;î

オンラインでお試しください! または素数を生成する効率の低い方法を試してください

説明

n = 10 例として使用。

D          # duplicate
           # STACK: 10, 10 
 !         # factorial
           # STACK: 10, 3628800
  f        # unique prime factors
           # STACK: 10, [2,3,5,7]
   -       # subtract
           # STACK: [8,7,5,3]
    p      # is prime
           # STACK: [0,1,1,1]
     O     # sum
           # STACK: 3
      ;    # divide by 2
           # STACK: 1.5
       î   # round up
           # STACK: 2
           # implicit output

ü代わりに使用できませんか?好きD!fü+r¢
魔法のタコUr

1
@carusocomputing:それがどのように機能するかわかりません。たとえば、n=10count(10、[5,8,12])の場合、2ではなく0です。ü各ペアのアイテム間にのみ適用されます。ãしかし、試してみるというアイデアはありましたが、残念ながら1バイト長くなりました。
エミグナ

2

GAP、57バイト

n->Number([2..QuoInt(n,2)],k->IsPrime(k)and IsPrime(n-k))

GAPの方がこの明白な方法よりも短いとは思いません。Number述語を満たすリストの要素の数をカウントします。

それを使用して最初の100個の値を計算します。

gap> List([1..100],n->Number([2..QuoInt(n,2)],k->IsPrime(k)and IsPrime(n-k)));
[ 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 2, 1, 2, 0, 2, 1, 2, 1, 3, 0, 3, 1, 
  3, 0, 2, 0, 3, 1, 2, 1, 4, 0, 4, 0, 2, 1, 3, 0, 4, 1, 3, 1, 4, 0, 5, 1, 4, 
  0, 3, 0, 5, 1, 3, 0, 4, 0, 6, 1, 3, 1, 5, 0, 6, 0, 2, 1, 5, 0, 6, 1, 5, 1, 
  5, 0, 7, 0, 4, 1, 5, 0, 8, 1, 5, 0, 4, 0, 9, 1, 4, 0, 5, 0, 7, 0, 3, 1, 6 ]

2

Brachylog、22バイト

:{,A:B>=.:#pa+?,.=}fl

オンラインでお試しください!

説明

問題のまっすぐな転写。

:{                }f       Find all valid outputs of the predicate in brackets for the Input
                    l      Output is the number of valid outputs found

  ,A:B>=.                  Output = [A, B] with A >= B
         :#pa              Both A and B must be prime numbers
             +?,           The sum of A and B is the Input
                .=         Label A and B as integers that verify those constraints

2

Mathematica、52バイト

Count[IntegerPartitions[#,{2}]//PrimeQ,{True,True}]&

結果は匿名関数として提供されます。その上にグラフをプロットしてみてください:

DiscretePlot[
 Count[IntegerPartitions[#, {2}] // PrimeQ, {True, True}] &[i], {i, 1,
   1000}]

シーケンスのプロット

ところで、コードの長さはOEISのデモコードの機能バージョンと同じです。


2
49バイト:PrimeQ[#~IntegerPartitions~{2}]~Count~{a=True,a}&
LegionMammal978

1

ゼリー、12 バイト

HRð,_@ÆPð×/S

TryItOnline
1-100

どうやって?

HRð,_@ÆPð×/S - Main link: n    e.g. 22
H            - halve
 R           - range          [1,2,3,4,5,6,7,8,9,10,11] (note this will be 1 to n//2)
  ð          - dyadic chain separation
   ,         - pair with
    _@       - n -           [[1,2,3,4,5,6,7,8,9,10,11],[21,20,19,18,17,16,15,14,13,12,11]]
      ÆP     - is prime? (1 if prime 0 if not)
                            [[0,1,1,0,1,0,1,0,0,0,1],[0,0,1,0,1,0,0,0,1,0,1]]
        ð    - dyadic chain separation
         ×/  - reduce with multiplication
                             [0,0,1,0,1,0,0,0,0,0,1]
           S - sum           3

1

ラケット219バイト

(let*((pl(for/list((i n) #:when(prime? i))i))(ll(combinations(append pl pl)2))(ol'()))(for/list((i ll))(define tl(sort i >))
(when(and(= n(apply + i))(not(ormap(λ(x)(equal? x tl))ol)))(set! ol(cons tl ol))))(length ol))

ゴルフをしていない:

(define(f n)
 (let* ((pl                                   ; create a list of primes till n
          (for/list ((i n) #:when (prime? i))
            i))
         (ll (combinations (append pl pl) 2)) ; get a list of combinations of 2 primes
         (ol '()))                            ; initialize output list
    (for/list ((i ll))                        ; test each combination
      (define tl (sort i >))
      (when (and (= n (apply + i))            ; sum is n
                 (not(ormap (lambda(x)(equal? x tl)) ol))) ; not already in list
        (set! ol (cons tl ol))))              ; if ok, add to list
    (println ol)                              ; print list
    (length ol)))                             ; print length of list

テスト:

(f 10)
(f 100)

出力:

'((5 5) (7 3))
2
'((97 3) (89 11) (83 17) (71 29) (59 41) (53 47))
6



0

Haskell、73バイト

f n|r<-[a|a<-[2..n],all((<2).gcd a)[2..a-1]]=sum[1|p<-r,q<-r,q<=p,p+q==n]

使用例:map f [1..25]-> [0,0,0,1,1,1,1,1,1,2,0,1,1,2,1,2,0,2,1,2,1,3,0,3,1]

定義の直接実装:最初のバインドr入力番号までのすべての素数にはn、その後、取る1すべてのためpqからrどこq<=pp+q==nし、それらを合計します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.