Congettura di Goldbach


15

Scrivi un programma che richiede all'utente un numero intero pari a 2.

Data la congettura di Goldbach secondo cui ogni numero intero maggiore di 2 può essere espresso come la somma di due numeri primi, stampare due numeri primi che, sommati, forniscono il numero pari richiesto. Modifica: il programma deve solo stampare UNA COPPIA di numeri primi, non tutti. Per esempio:

4: 2 + 2

6: 3 + 3

8: 3 + 5

10: 5 + 5 o 3 + 7


"deve solo stampare una coppia di numeri primi" Ciò significa che è consentito stampare più coppie?
Ayiko,

Suppongo che accorcia la lunghezza del codice, ma dovrebbe essere organizzato
Razionalità

Risposte:


11

APL, 34 o 44 byte

La prima versione è lunga 34 simboli ed è limitata ai caratteri dei set di caratteri APL a byte singolo originali, come quello ancora supportato in Dyalog APL:

↑c/⍨n=+/¨c←,∘.,⍨v/⍨~v∊v∘.×v←1↓⍳n←⎕

Spiegazione:

                               n←⎕   ⍝ ask for a number, store as n
                          v←1↓⍳n     ⍝ generate all integers from 2 to n
                      v∘.×v          ⍝ compute the product table of any two such integers
                v/⍨~v∊               ⍝ select those that don't appear in the product table 
         c←,∘.,⍨                     ⍝ generate all possible pairs of these primes
    n=+/¨c                           ⍝ check which pairs have a sum equal to n
↑c/⍨                                 ⍝ take the first that does

La seconda versione è lunga solo 22 simboli, perché sfrutta la πfunzione per verificare la presenza di numeri primi, ma è disponibile solo in NARS2000 che utilizza Unicode, quindi il conteggio dei byte è 44 in UCS-2:

2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1

Spiegazione:

                   ⎕    ⍝ ask for a number N
                  ⍳ -1  ⍝ generate all naturals from 1 to N-1
             (⍪,⌽)      ⍝ arrange it into a table of all pairs of naturals with sum N
     {∧/0π⍵}            ⍝ check which pairs are made of all primes
2⍴(⌿⍨       )           ⍝ return the first pair that does

Esempi

(⎕: è il prompt che richiede un numero)

      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      4
2 2
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      6
3 3
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      8
3 5
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      124
11 113

Funzionerebbe ¯2π⍳2πncome generatore principale?
Oberon,

@Oberon cosa fa πesattamente l' operatore?
primo

Diadiche πinterruttori con : ¯2πxcalcola il primo xth, ¯1πxè il primo primo minore di x, 0πxtest x per primalità, 1πxè il primo maggiore primaria di x, 2πxè il numero di primi minori di x, 10πxè il numero di divisori di x, 11πxè la somma di tutti i divisori di x, 12πxe 13πxsono rispettivamente la funzione Möbius e totient. Ultimo ma non meno importante, la monade πxrestituisce la scomposizione in fattori primi di x.
Oberon,

@Oberon specifico di NARS2000, vero? Sembra essere un interprete interessante. Lo proverò e rivedrò la mia risposta.
Tobia,

@Tobia Lo è? Mi dispiace allora. L'ho visto referenziato da qualche parte, ma non hanno mai menzionato NARS2000. Buono a sapersi.
Oberon,

6

Python 2, 75 71 byte

n=input();k=m=1;p={0}
while{n-k,k}-p:m*=k*k;k+=1;p|={m%k*k}
print n-k,k

Provalo su Ideone .

Come funziona

Usiamo un corollario del teorema di Wilson :

corollario del teorema di Wilson

In ogni momento, la variabile m è uguale al quadrato del fattoriale di k - 1 ; k inizia dal valore 1 e m dal valore 0! ² = 1 . L'insieme p sarà composto da 0 e tutti i numeri primi fino al valore corrente di k .

In ogni iterazione, controlliamo prima se sia n - k che k appartengono a p , il che è vero se e solo se la differenza impostata di {nk, k} e p è vuota. Se lo è, la condizione è falsa e il ciclo continua.

Nota che k> 0 e {n - k, k} soddisferanno la condizione per un valore positivo di n - k (supponendo che la congettura di Goldbach sia vera), quindi lo 0 in p non porterà a falsi positivi.

Nel ciclo, aggiorniamo k e m . Il nuovo valore di m è m × k² = (k - 1)! ² × k² = k! ² e il nuovo valore di k è k + 1 , quindi m = (k - 1)! ² vale ancora prima e dopo l'aggiornamento.

Quindi, eseguiamo set union per aggiungere il valore di m% k × k a p . Secondo il corollario del teorema di Wilson, questo aggiungerà 1 × k = k se k è primo e 0 × k = 0 in caso contrario.

Quando il ciclo termina, stampiamo gli ultimi valori di n - k e k , che saranno numeri primi con la somma n .


Come mai funziona questo algoritmo di generazione primaria?
Leaky Nun,

@LeakyNun Ho aggiunto una spiegazione.
Dennis,

Oh ... è geniale.
Leaky Nun,

5

Ruby 2.0 (65)

require'prime'
n=gets.to_i
Prime.find{|i|p [i,n-i]if(n-i).prime?}

4

PHP - 73 byte

<?for(;@($n%--$$n?:$o=&$argv[1]>$$n=++$n)||${++$b}^${--$o};);echo"$b+$o";

L'input viene considerato come argomento della riga di comando.

Esempio di utilizzo:

$ php goldbach.php 7098
19+7079

4

GolfScript 41 33 32

~(,2>.-1%]zip{{.,2>\{\%!}+,},!}?

Accetta l'argomento della riga di comando, ad es

echo "14" | ruby golfscript.rb goldbach.gs
-> [2 12]

Trova tutte le partizioni pertinenti del numero di input con:

(,2>.-1%]zip  #If only zip were a one-character command!  It is so often useful.

e quindi trova la prima partizione in cui nessun numero NON è primo con:

{np,!}? #For each partition, filter down to elements that are not prime, and only accept if there are no such results (since [] is falsey).

dove si trova il blocco di controllo composito np:

{.,2>\{\%!}+,}

questo blocco filtra fino a tutti i numeri che dividono uniformemente un determinato numero. Se non ci sono tali numeri (quindi il numero è primo), il risultato è []che è falso in GolfScript.


3

perl 6: 69

$/=get;for grep &is-prime,^$/ {exit say $_,$_-$/ if ($/-$_).is-prime}

3

R, 170 112 83 caratteri

a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];q=p[(a-p)%in%p][1];cat(a,":",q,a-q)

rientrato:

a=scan() #Take user input as a numeric
b=2:a
p=b[rowSums(!outer(b,b,`%%`))<2] #Find all primes from 2 to user input
q=p[(a-p)%in%p][1] #Check which a-p also belong to p and takes the first one
cat(a,":",q,a-q)

Uso:

> a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];q=p[(a-p)%in%p][1];cat(a,":",q,a-q)
1: 72
2: 
Read 1 item
72 : 5 67 

Vecchia soluzione a 112 caratteri, per i posteri

a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];w=which(outer(p,p,`+`)==a,T);cat(a,":",p[w[1,1]],p[w[1,2]])

rientrato:

a=scan()
b=2:a
p=b[rowSums(!outer(b,b,`%%`))<2]
w=which(outer(p,p,`+`)==a,T) #Find the index of valid combinations
cat(a,":",p[w[1,1]],p[w[1,2]]) #Prints the first valid combination

Questo è sia pazzo che geniale !!
Tomas,

3

Python - 107

Fondamentalmente un miglioramento nella seconda parte della risposta nutria (ho eseguito questo su 2.7 ma penso che dovrebbe funzionare anche per 3.x)

p=lambda x:all(x%i!=0 for i in range(2,x))
n=input()
for i in range(2,n-1):
    if p(i)&p(n-i): print i,n-i

Le newline e gli spazi dopo sono :obbligatori?
mniip,

La scheda potrebbe essere ridotta a uno spazio e lo spazio prima della stampa potrebbe essere rimosso (rasatura di 4 byte).
clismique,

3

JavaScript (ES6) (Regex), 105

a=/^(xx+?)(?!(xx+)\2+$)x*(?=\1$)(?!(xx+)\3+$)/.exec("x".repeat(prompt()));alert(a[1].length+"+"+a[0].length)

Ora hai una regex che mette alla prova la congettura di Goldbach, che ha bassi requisiti in termini di caratteristiche speciali (supporto di riferimento posteriore, aspetto positivo e negativo).

Questo utilizza String.prototype.repeat(), che fa parte della proposta EcmaScript per la sesta edizione. Attualmente, questo codice funziona solo su Firefox.

Ho davvero bisogno di un linguaggio migliore che abbia il comando terse quando lavoro con regex ...


2

Scala, 286 192 172 148 caratteri

Non il più veloce ma funziona. Chiama g (10) per ottenere l'elenco delle coppie goldbach per 10.

def g(n:Int)={def p(n:Int,f:Int=2):Boolean=f>n/2||n%f!=0&&p(n,f+1)
s"$n : "+(for(i<-2 to n/2;j=n-i if p(i)&&p(j))yield s"$i + $j").mkString(" or ")}

La conversione in C ++ è semplice.


2

C - 139 129 caratteri

a,b;i(x,y){return x>y?x%y?i(x,y+1):0:x>1;}main(){scanf("%i",&a);for(b=a/2;b-->1;)i(b,2)&&i(a-
b,2)&&printf("%i:%i+%i\n",a,b,a-b);}

Puoi radere 8 caratteri rimuovendo le intdichiarazioni nella tua funzione i. Puoi salvare altri 2 caratteri rimuovendo ife aggiungendo un'altra e commerciale doppia:i(b,2)&&i(a-b,2)&&printf(...)
Josh

Grazie! Non ci ho pensato &&. (Non mi abituerò mai al silenziamento del tipo di argomento ...)
Oberon,

Adoro il tuo uso del ternario nidificato.
Josh,

2

newLISP - 169 148 caratteri

(define(p n)(=(length(factor n))1))
(define(g n)(when(even? n)(for(i 3 n 2)
(and(p i)(p(- n i))(println n {: } i { }(- n i))))))
(g(int(read-line)))

include il codice per eseguirlo. I risultati sono troppo generosi ...

72: 5 67
72: 11 61
72: 13 59
72: 19 53
72: 29 43
72: 31 41
72: 41 31
72: 43 29
72: 53 19
72: 59 13
72: 61 11
72: 67 5

2

Salvia, 60

Simile per punteggio e sensazione alla soluzione di res , ma penso che sia abbastanza diverso da pubblicare.

i=n=input()
while not{i,n-i}<set(primes(n)):i-=1
print i,n-i

2

Salvia , 65 62

n=input()
i=0
p=is_prime
while p(i)*p(n-i)==0:i+=1
print i,n-i

Con quanto sopra nel file goldbach.sage, eseguilo con Sage in esecuzione in un terminale:

sage: %runfile goldbach.sage 

Grazie a @boothby per l' p=is_primeidea.


Puoi ottenere questo fino a 62 impostando p=is_prime.
stand

2

Haskell, 97C

g n=head[(a,b)|let q=p n,a<-q,b<-q,a+b==n]
p n=filter c[2..n]
c p=null[x|x<-[2..p-1],p`mod`x==0]

Spiegazione:

  • gè la funzione "goldbach". La chiamata g nti dà la coppia di numeri primi che si sommano n.
  • pè una funzione che genera un elenco di numeri primi inferiori a n.
  • cè la funzione di controllo principale utilizzata per definire p.

Esempi di esecuzione:

*Main> g 4
(2,2)
*Main> g 6
(3,3)
*Main> g 8
(3,5)
*Main> g 10
(3,7)
*Main> g 12
(5,7)
*Main> map g [4,6..100]
[(2,2),(3,3),(3,5),(3,7),(5,7),(3,11),(3,13),(5,13),(3,17),(3,19),(5,19),(3,23),(5,23),(7,23),(3,29),(3,31),(5,31),(7,31),(3,37),(5,37),(3,41),(3,43),(5,43),(3,47),(5,47),(7,47),(3,53),(5,53),(7,53),(3,59),(3,61),(5,61),(7,61),(3,67),(5,67),(3,71),(3,73),(5,73),(7,73),(3,79),(5,79),(3,83),(5,83),(7,83),(3,89),(5,89),(7,89),(19,79),(3,97)]

2

Mathematica 56

Ciò restituisce tutte le soluzioni per l'intero di input.

Select[Tuples[Prime@Range@PrimePi[n = Input[]], 2], Tr@# == n &]

Ad esempio, quando viene inserito 1298 ...

{{7, 1291}, {19, 1279}, {61, 1237}, {67, 1231}, {97, 1201}, {127, 1171}, {181, 1117}, {211, 1087}, { 229, 1069}, {277, 1021}, {307, 991}, {331, 967}, {379, 919}, {421, 877}, {439, 859}, {487, 811}, {541, 757}, {547, 751}, {571, 727}, {607, 691}, {691, 607}, {727, 571}, {751, 547}, {757, 541}, {811, 487} , {859, 439}, {877, 421}, {919, 379}, {967, 331}, {991, 307}, {1021, 277}, {1069, 229}, {1087, 211}, { 1117, 181}, {1171, 127}, {1201, 97}, {1231, 67}, {1237, 61}, {1279, 19}, {1291, 7}}

Come scritto, restituisce ogni soluzione due volte.

Union[Sort/@ %]

{{7, 1291}, {19, 1279}, {61, 1237}, {67, 1231}, {97, 1201}, {127, 1171}, {181, 1117}, {211, 1087}, { 229, 1069}, {277, 1021}, {307, 991}, {331, 967}, {379, 919}, {421, 877}, {439, 859}, {487, 811}, {541, 757}, {547, 751}, {571, 727}, {607, 691}}


Ingresso 2, chiedi a un oracolo se si ferma, prova / confuta la congettura dei numeri primi gemelli, vinci
Filipq

1

Julia, 62 caratteri (85 con prompt)

julia> g(n)=collect(filter((x)->sum(x)==n,combinations(primes(n),2)))
g (generic function with 1 method)

julia> g(88)
4-element Array{Array{Int64,1},1}:
 [5,83] 
 [17,71]
 [29,59]
 [41,47]

Questo non richiede all'utente (come richiesto), vero?
res

No, non l'ho notato. Aggiungerebbe molti personaggi proprio ora, Julia. g(int(readline(STDIN)))
gggg

1

GTB , 31

Per la tua calcolatrice TI-84

`A:.5A→B@%;A,4)4$~B+1,B-1#~B,B&

Nessun built-in principale.

L'esempio funziona

?4
               2
               2
?6
               3
               3
?8
               3
               5
?10
               5
               5


1

Python 3 - 150 143 caratteri

Vecchia versione (150 caratteri):

p=lambda n:0 in[n % i for i in range(2,n)]
n=int(input())
[print('%d+%d'%(a, b))for b in range(2,n)for a in range(2,n)if not(a+b!=n or p(a) or p(b))]

Nuova versione (grazie a ProgramFOX):

p=lambda n:0 in[n%i for i in range(2,n)]
n=int(input())
[print('%d+%d'%(a,b))for b in range(2,n)for a in range(2,n)if not((a+b!=n)|p(a)|p(b))]

Stampa ogni combinazione, ad esempio:
4 2 + 2
10 7 + 3 5 + 5 3 + 7


|può essere tranquillamente utilizzato con tipo booleano, quindi(a+b!=n)|p(a)|p(b)
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Ancora più breve usando: print([(a,b)for b in range(2,n)for a in range(2,n)if not((a+b!=n)|p(a)|p(b))])(stampa un elenco di tuple, la cui somma è n). Salva 8 byte.
agtoever,

Anche l'utilizzo r=range(2,n)e la referenziazione ne rsalvano alcuni di più.
agtoever,

1

q [116 caratteri]

y where all each{{2=count where 0=(x mod)each til x+1}each x}each y:{a where x=sum each a:a cross a:til x}"I"$read0 0

Nessuna funzione integrata per trovare il numero primo.

Ingresso

72

Produzione

5  67
11 61
13 59
19 53
29 43
31 41
41 31
43 29
53 19
59 13
61 11
67 5

1

Python - 206

Un po 'tardi alla festa, ma sto esercitando le mie abilità nel golf.

In realtà l'ho codificato prima di trovare questa domanda! Quindi il mio non include la bellissima lambda che usano le altre soluzioni Python.

import math
def p(n):
    if n%2==0&n>2:return False
    for i in range(3,n):
        if n%i==0:return False
    return True 
X=int(input())
for i in range(2,X):
    if p(i)&p(X-i):print i,X-i;break

1

J - 35 32 caratteri

"Chiedi all'utente" è la rovina di ogni golfista J. Ecco tutti i miei personaggi guadagnati duramente!

p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1

Ha spiegato:

  • ".1!:1]1- Leggi in una stringa ( 1!:1) dall'input (handle del file 1) e convertilo in un numero ( ".).
  • p:i.n=:- Assegna questo numero alla variabile n, quindi prendi i primi nnumeri primi.
  • +/~- Crea una tabella di aggiunta, nampia e nalta.
  • i.&n, - Trasforma la tabella in un unico elenco, quindi trova l'indice della prima occorrenza di n , che esiste se la congettura di Goldbach è vera.
  • p:(n,n)#: - Recupera la riga e la colonna dall'indice e prendi i numeri primi corrispondenti.

Uso:

   p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1
666
5 661
   p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1
1024
3 1021

Se il prompt non fosse stato un requisito, ecco un verbo di 25 caratteri:

(,~p:@#:]i.~&,+/~@:p:@i.)

1

Gelatina , 8 byte (non competitiva)

_ÆRfÆR.ị

Provalo online! o verifica tutti i casi di test .

Come funziona

_ÆRfÆR.ị  Main link. Argument: n (integer)

 ÆR       Prime range; yield all primes in [1, ..., n].
_         Subtract all primes from n.
   fÆR    Filter; intersect the list of differences with the prime range.
      .ị  At-index 0.5; yield the last and first element.

1

Julia, 50 49 byte

~=primes;n=ARGS[]|>int
(n-~n)∩~n|>extrema|>show

Provalo online!

Se una funzione fosse accettabile, il codice potrebbe essere abbreviato a 32 byte :

~=primes
!n=(n-~n)∩~n|>extrema

Come funziona

~=primescrea un alias per la funzione di numeri primi incorporata che restituisce un elenco di tutti i numeri primi fino al suo argomento. n=ARGS[]|>intanalizza il primo argomento della riga di comando salvandolo in n .

Per trovare una coppia adatta di numeri primi, prima calcoliamo la gamma di cui sopra ~n. Quindi, n-~nproduce tutte le differenze di questi numeri primi e n .

Intersecando ( ) il risultato con l'intervallo primo stesso, ci assicuriamo che i primi rimanenti p siano tali che n - p sia anche un numero primo.

Infine, extremaprende il primo più basso e il più alto nell'intersezione, quindi la loro somma deve essere n .


0

SQL, 295 284

In postgresql:

create function c(c int) returns table (n int, m int) as $$ 
with recursive i(n) as
(select 2 union all select n+1 from i where n<c), 
p as (select * from i a where not exists 
(select * from i b where a.n!=b.n and mod(a.n,b.n)=0))
select * from p a, p b where a.n+b.n=c 
$$ language sql;

Dovrebbe essere in grado di farlo in metà dello spazio, tuttavia, se non fosse per cose come "nessun join esterno sinistro in ricorsione", "nessuna subquery in ricorsione" ...

Ecco l'output:

postgres=# select c(10);
   c   
-------
 (3,7)
 (5,5)
 (7,3)
(3 rows)

postgres=# select c(88);
   c    
---------
 (5,83)
 (17,71)
 (29,59)
 (41,47)
 (47,41)
 (59,29)
 (71,17)
 (83,5)
(8 rows)

0

Lotto - 266

@echo off&setLocal enableDelayedExpansion&for /L %%a in (2,1,%1)do (set/aa=%%a-1&set c=&for /L %%b in (2,1,!a!)do set/ab=%%a%%%%b&if !b!==0 set c=1
if !c! NEQ 1 set l=!l!%%a,)&for %%c in (!l!)do for %%d in (!l!)do set/ad=%%c+%%d&if !d!==%1 set o=%%c + %%d
echo !o!

Esegui ordinatamente -

@echo off
setLocal enableDelayedExpansion
for /L %%a in (2,1,%1) do (
    set /a a=%%a-1
    set c=
    for /L %%b in (2,1,!a!) do (
        set /a b=%%a%%%%b
        if !b!==0 set c=1
    )
    if !c! NEQ 1 set l=!l!%%a,
)
for %%c in (!l!) do for %%d in (!l!) do (
    set /a d=%%c+%%d
    if !d!==%1 set o=%%c + %%d
)
echo !o!

0

Perl 5, 58 byte

57, più 1 per -nE

/^(11+?)(?!(11+)\2+$)1*(?=\1$)(?!(11+)\3+$)/;say for$1,$&

Ingresso e uscita sono unari. Esempio:

$ perl -nE'/^(11+?)(?!(11+)\2+$)1*(?=\1$)(?!(11+)\3+$)/;say for$1,$&'
1111111111
111
1111111

Hat-punta.


0

Oracle SQL 11.2, 202 byte

WITH v(x,y,s)AS(SELECT LEVEL,LEVEL,0 FROM DUAL CONNECT BY LEVEL<=:1 UNION ALL SELECT x,y-1,s+SIGN(MOD(x,y))FROM v WHERE y>1),p AS(SELECT x FROM v WHERE x-s=2)SELECT a.x,b.x FROM p a,p b WHERE:1=a.x+b.x;   

Un-golfed

WITH v(x,y,s) AS
(
  SELECT LEVEL,LEVEL,0 FROM DUAL CONNECT BY LEVEL<=:1 
  UNION ALL 
  SELECT x,y-1,s+SIGN(MOD(x,y))FROM v WHERE y>1
)
,p AS (SELECT x FROM v WHERE x-s=2)
SELECT a.x,b.x 
FROM p a,p b 
WHERE :1=a.x+b.x;   

0

Python 3, 107 byte

b=lambda x:all(x%y for y in range(2,x))
g=lambda x,i=2:((i,x-i)if b(i)&b(x-i)else g(x,i+1))if(i<x)else 0

b (x) è un test di primalità per xe g (x) ricorre attraverso i numeri per trovare due numeri primi che si adattano.

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.