Partizioni Goldbach


18

La congettura di Goldbach afferma che ogni numero pari maggiore di due può essere espresso come la somma di due numeri primi. Per esempio,

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

Tuttavia, una volta arrivati ​​a 10 succede qualcosa di interessante. Non solo 10 possono essere scritti come

5 + 5

ma può anche essere scritto come

7 + 3

Poiché 10 può essere espresso come la somma di due numeri primi in due modi , diciamo che la "partizione di Goldbach" di 10 è 2. O più in generale,

La partizione di Goldbach di un numero è il numero totale di modi distinti di scrivere n = p + qdove pe qsono numeri primi ep >= q

La tua sfida è scrivere un programma o una funzione che trovi la partizione Goldbach di un numero. Ora, tecnicamente il termine "partizione di Goldbach" viene utilizzato solo per riferirsi a numeri pari. Tuttavia, poiché l'intero dispari p + 2 può anche essere espresso come la somma di due numeri primi se p> 2 è primo, lo estenderemo a tutti i numeri interi positivi ( A061358 ).

Puoi tranquillamente supporre che l'input sia sempre un numero intero positivo e puoi accettare input e output in uno qualsiasi dei nostri metodi predefiniti consentiti , ad esempio argomenti di funzioni e valore di ritorno, STDIN e STDOUT, lettura e scrittura su un file, ecc.

Le partizioni di Goldbach degli interi positivi fino a 100 sono:

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

Come al solito, si applicano scappatoie standard e vince la risposta più breve in byte!


1
Ti vengono sempre in mente sfide così belle :-)
Luis Mendo,

Risposte:


6

Gelatina , 8 byte

_ÆRÆPSHĊ

Provalo online! o verifica tutti i casi di test .

Come funziona

_Æ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).

Oh molto meglio: D
Jonathan Allan il

5

Python 2, 76 byte

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)

Esegue una scansione ricorsiva da k=2a n/2, sommando i valori dove entrambi ke n-ksono primi. Sarebbe bello invece fare il conto nalla rovescia allo stesso tempo, ma questo ha un problema che k=0e k=1sono falsamente chiamati primi:

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)

Il controllo della primalità è la divisione di prova, abbreviata controllando entrambi ke n-kinsieme. Ho trovato questo per essere più breve rispetto all'uso di un generatore di teoremi di Wilson (79 byte):

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

L'idea per questo è quella di tenere un elenco di tutti i numeri primi nella metà inferiore per essere controllati quando arriviamo alla metà superiore, ma per il punto medio k=n/2non abbiamo avuto il tempo di aggiungere n-kalla lista quando arriviamo a k. Una versione iterativa aggira questo, ma è di 82 byte:

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 byte

tZq&+=Rz

Provalo online!

Spiegazione

Considera l'input 8come esempio

      % 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

È interessante osservare il grafico della sequenza , usando una versione leggermente modificata del codice:

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

Per input 10000il risultato è

inserisci qui la descrizione dell'immagine

Puoi provarlo su MATL Online (Aggiorna la pagina se il pulsante "Esegui" non cambia in "Uccidi" quando viene premuto). Sono necessari diversi circa 25 secondi per produrre il grafico per l'input 3000; gli input superiori a poche migliaia andranno in timeout.


1
Questo Upper triangular parttrucco è davvero fantastico!
DJMcMayhem

3

JavaScript (ES6), 77 73 70 byte

Salvato 3 byte grazie a @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è una funzione di test di primalità; la funzione rilevante è g.

ffunziona contando ricorsivamente da n-1 ; il flusso di controllo in ogni fase va così:

  • x<2||Se x <2 , il numero è primo; ritorno 1 .
  • n%x&&Altrimenti se n mod x = 0 , il numero non è primo; ritorno n%x.
  • f(n,x-1)Altrimenti, il numero può essere o non essere primo; decrementa x e riprova.

gfunziona in modo simile, anche se con un flusso di controllo non così elevato. Funziona moltiplicando f (b) da f (ab) per ogni intero b nell'intervallo [2, piano (a / 2)] , quindi sommando i risultati. Questo ci dà il numero di coppie che somma una in cui entrambi i numeri nella coppia sono primi, che è esattamente quello che vogliamo.


Poiché aè positivo, b=a>>1dovrebbe salvarti un byte.
Arnauld,

@Arnauld Grazie! Avrei dovuto ricordare l' >>operatore ...
ETHproductions

Per quanto riguarda la funzione di test di primalità, potresti fare f=(n,x=n)=>--x<2||n%x&&f(n,x)?
Arnauld,

@Arnauld Questo è genio, grazie :)
ETHproductions

2

05AB1E , 10 8 byte

Estremamente inefficiente.

D!f-pO;î

Provalo online! oppure Prova un modo meno efficiente di generare numeri primi

Spiegazione

n = 10 usato come esempio.

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

Non potresti usare üinvece? Come D!fü+r¢?
Magic Octopus Urn,

1
@carusocomputing: non vedo come funzionerebbe. Per l'esempio n=10che verrebbe conteggiato (10, [5,8,12]) che è 0 invece di 2. üviene applicato solo tra ciascuna coppia di elementi. Mi è venuta l'idea di provarci ã, ma sfortunatamente è risultato 1 byte più lungo.
Emigna,

2

GAP , 57 byte

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

Non penso che GAP abbia un modo più breve di questo ovvio. Numberconta quanti elementi di un elenco soddisfano un predicato.

Usandolo per calcolare i primi 100 valori:

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 byte

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

Provalo online!

Spiegazione

Una trascrizione diretta del problema.

:{                }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 byte

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

Il risultato è fornito come una funzione anonima. Prova a tracciare un grafico su di esso:

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

trama della sequenza

A proposito, il codice ha la stessa lunghezza con la versione della funzione del codice demo su OEIS.


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

1

Gelatina , 12 byte

HRð,_@ÆPð×/S

TryItOnline
1-100

Come?

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

Racchetta 219 byte

(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

test:

(f 10)
(f 100)

Produzione:

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

1

In realtà , 11 byte

;R`p`░@-♂bΣ

Provalo online!

Spiegazione:

;R`p`░@-♂bΣ
 R`p`░       prime values in [1, n]
;     @-     subtract each value from n
        ♂b   convert each value to boolean
          Σ  sum

1

05AB1E , 6 byte

;ÅP-pO

Provalo online!

Spiegazione:

                  # 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

0

Haskell, 73 byte

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]

Esempio di utilizzo: 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].

Realizzazione diretta della definizione: prima si legano ra tutti i numeri primi fino al numero di input n, poi prendere un 1per tutti pe qda rdove q<=pe p+q==ne li somma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.