21
\$\begingroup\$

The Goldbach conjecture states that every even number greater than two can be expressed as the sum of two primes. For example,

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

However, once we get to 10 something interesting happens. Not only can 10 be written as

5 + 5

but it can also be written as

7 + 3

Since 10 can be expressed as the sum of two primes two ways, we say that the "Goldbach partition" of 10 is 2. Or more generally,

The Goldbach partition of a number is the total number of distinct ways of writing n = p + q where p and q are primes and p >= q

Your challenge is to write a program or function that finds the Goldbach partition of a number. Now, technically the term "Goldbach partition" is used only to refer to even numbers. However, since the odd integer p + 2 can also be expressed as the sum of two primes if p> 2 is prime, we will extend this to all positive integers (A061358).

You may safely assume that your input will always be a positive integer, and you may take input and output in any of our default allowed methods, for example function arguments and return value, STDIN and STDOUT, reading and writing to a file, etc.

The Goldbach partitions of the positive integers up to 100 are:

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

As usual, standard loopholes apply, and the shortest answer in bytes wins!

Dennis
212k41 gold badges380 silver badges830 bronze badges
asked Oct 22, 2016 at 0:03
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You always come up with such nice challenges :-) \$\endgroup\$ Commented Oct 22, 2016 at 0:15

15 Answers 15

7
\$\begingroup\$

Jelly, 8 bytes

_ÆRÆPSHĊ

Try it online! or verify all test cases.

How it works

_Æ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).
answered Oct 22, 2016 at 0:42
\$\endgroup\$
1
  • \$\begingroup\$ Oh much better :D \$\endgroup\$ Commented Oct 22, 2016 at 0:48
5
\$\begingroup\$

Python 2, 76 bytes

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)

Recursively crawls up from k=2 to n/2, adding up values where both k and n-k are prime. It would be nice to count n down at the same time instead, but this has a problem that k=0 and k=1 are falsely called prime:

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)

The primality check is trial-division, shortened by checking both k and n-k together. I found this to be shorter than using a Wilson's Theorem generator (79 bytes):

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])

The idea for this one is to keep a list of all primes in the bottom half to be checked by the time we get to the top half, but for the midpoint k=n/2, we haven't had time to add n-k to out list when we get to k. An iterative version gets around this, but is 82 bytes:

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
answered Oct 22, 2016 at 0:32
\$\endgroup\$
5
\$\begingroup\$

MATL, 8 bytes

tZq&+=Rz

Try it online!

Explanation

Consider input 8 as an example

 % 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

It's interesting to observe the graph of the sequence, using a slightly modified version of the code:

:"@ % 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

For input 10000 the result is

enter image description here

You can try it at MATL Online (Refresh the page if the "Run" button doesn't change to "Kill" when pressed). It takes several about 25 seconds to produce the graph for input 3000; inputs above a few thousands will time out.

Suever
11.2k1 gold badge24 silver badges52 bronze badges
answered Oct 22, 2016 at 0:07
\$\endgroup\$
1
  • 1
    \$\begingroup\$ That Upper triangular part trick is really cool! \$\endgroup\$ Commented Oct 22, 2016 at 0:19
4
\$\begingroup\$

05AB1E, 6 bytes

;ÅP-pO

Try it online!

Explanation:

 # implicit input (example: 10)
; # divide input by 2 (5)
 ÅP # primes up to that ([2, 3, 5])
 - # subtract from the implict input ([8, 7, 5])
 p # isPrime? ([0, 1, 1])
 O # sum (2), implicit output
answered May 3, 2019 at 16:00
\$\endgroup\$
4
\$\begingroup\$

Regex 🐇 (ECMAScriptRME / Perl / PCRE), (削除) 38 (削除ここまで) (削除) 33 (削除ここまで) 32 bytes

^(xx+)(?=1円(x*))(?!2円?(xx+)3円+$)

Try it on replit.com! - ECMAScript (RegexMathEngine)
Try it online! - Perl
Try it online! - PCRE2

Takes its input in unary, as a string of x characters whose length represents the number. Returns its output as the number of ways the regex can match. (The rabbit emoji indicates this output method.)

^ # tail = N = input number
(xx+) # 1円 = conjectured first prime, automatically asserted
 # to be ≥ 2;
 # tail = N-1円 == conjectured second prime
(?=
 1円 # tail -= 1円; assert that second prime ≥ first prime;
 # since the first prime is ≥ 2, this automatically
 # asserts the second also to be so.
 (x*) # 2円 = tail == N-2*1円 == tool to make tail = 1円
)
(?! # Assert there is no way to make the following match:
 2円? # either leave tail unchanged, or tail = 1円
 (xx+)3円+$ # Assert that tail is composite (which is only the same
 # as being not prime for numbers ≥ 2)
)

Regex 🐝 (ECMAScript 2018 or better), 36 bytes

(?<=(x+x))(?=1円(x*))(?!2円?(xx+)3円+$)

Returns its output as the number of matches.

Try it online! - ECMAScript 2018
Try it online! - Python (import regex )
Try it online! - .NET

Regex 🐝 (ECMAScript 2018 or better / Java), 37 bytes

(?<=^(xx+))(?=1円(x*))(?!2円?(xx+)3円+$)

Try it online! - ECMAScript 2018
Try it online! - Java
Try it online! - Python (import regex )
Try it online! - .NET

answered Aug 4, 2022 at 21:21
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), (削除) 77 (削除ここまで) (削除) 73 (削除ここまで) 70 bytes

Saved 3 bytes thanks to @Arnauld

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 is a primality-test function; the relevant function is g.

f works by recursively counting down from n-1; the control flow at each stage goes like this:

  • x<2|| If x < 2, the number is prime; return 1.
  • n%x&& Otherwise if n mod x = 0, the number is not prime; return n%x.
  • f(n,x-1) Otherwise, the number may or may not be prime; decrement x and try again.

g works in a similar fashion, though with not so much control flow. It works by multiplying f(b) by f(a-b) for each integer b in the range [2, floor(a/2)], then summing the results. This gives us the number of pairs that sum to a where both numbers in the pair are prime, which is exactly what we want.

answered Oct 22, 2016 at 1:28
\$\endgroup\$
3
  • \$\begingroup\$ Since a is positive, b=a>>1 should save you a byte. \$\endgroup\$ Commented Oct 22, 2016 at 8:39
  • \$\begingroup\$ @Arnauld Thanks! I should've remembered the >> operator... \$\endgroup\$ Commented Oct 22, 2016 at 14:56
  • \$\begingroup\$ Regarding the primality-test function, could you do f=(n,x=n)=>--x<2||n%x&&f(n,x)? \$\endgroup\$ Commented Oct 22, 2016 at 15:06
3
\$\begingroup\$

GAP, 57 bytes

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

I don't think GAP has a shorter way than this obvious one. Number counts how many elements of a list satisfy a predicate.

Using it to compute the first 100 values:

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 ]
answered Oct 22, 2016 at 15:58
\$\endgroup\$
3
\$\begingroup\$

Brachylog, 22 bytes

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

Try it online!

Explanation

A straight up transcription of the problem.

:{ }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
answered Oct 22, 2016 at 16:36
\$\endgroup\$
3
\$\begingroup\$

Mathematica, 52 bytes

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

The result is provided as an anonymous function. Try to plot a graph over it:

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

plot of the sequence

By the way, the code has the same length with function version of demo code on OEIS.

answered Oct 22, 2016 at 16:51
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 49 bytes: PrimeQ[#~IntegerPartitions~{2}]~Count~{a=True,a}& \$\endgroup\$ Commented Oct 22, 2016 at 21:31
2
\$\begingroup\$

05AB1E, (削除) 10 (削除ここまで) 8 bytes

Extremely inefficient.

D!f-pO;î

Try it online! or Try a less efficient way of generating primes

Explanation

n = 10 used as example.

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
answered Oct 22, 2016 at 15:16
\$\endgroup\$
2
  • \$\begingroup\$ Couldn't you use ü instead? Like D!fü+r¢? \$\endgroup\$ Commented Oct 24, 2016 at 20:54
  • 1
    \$\begingroup\$ @carusocomputing: I don't see how that would work. For the example n=10 that would be count(10, [5,8,12]) which is 0 instead of 2. ü is applied between each pair of items only. It gave me the idea to try ã though, but that turned out 1 byte longer unfortunately. \$\endgroup\$ Commented Oct 25, 2016 at 6:28
2
\$\begingroup\$

Vyxal, 6 bytes

1⁄2~æ-æ∑

Try it Online! Includes header and footer to produce first 100 results.

answered Sep 1, 2022 at 3:32
\$\endgroup\$
1
\$\begingroup\$

Jelly, 12 bytes

HRð,_×ばつ/S

TryItOnline
1-100

How?

HRð,_×ばつ/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
answered Oct 22, 2016 at 0:34
\$\endgroup\$
1
\$\begingroup\$

Racket 219 bytes

(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))

Ungolfed:

(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

Testing:

(f 10)
(f 100)

Output:

'((5 5) (7 3))
2
'((97 3) (89 11) (83 17) (71 29) (59 41) (53 47))
6
answered Oct 22, 2016 at 5:10
\$\endgroup\$
1
\$\begingroup\$

Actually, 11 bytes

;R`p`░@-♂bΣ

Try it online!

Explanation:

;R`p`░@-♂bΣ
 R`p`░ prime values in [1, n]
; @- subtract each value from n
 ♂b convert each value to boolean
 Σ sum
answered Oct 22, 2016 at 5:42
\$\endgroup\$
1
\$\begingroup\$

Haskell, 73 bytes

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]

Usage example: 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].

Direct implementation of the definition: first bind r to all primes up to the input number n, then take a 1 for all p and q from r where q<=p and p+q==n and sum them.

answered Nov 4, 2016 at 14:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.