Conjecture de Goldbach


15

Écrivez un programme qui invite l'utilisateur à saisir un entier pair supérieur à 2.

Étant donné la conjecture de Goldbach selon laquelle chaque entier pair supérieur à 2 peut être exprimé comme la somme de deux nombres premiers, imprimez deux nombres premiers qui, lorsqu'ils sont additionnés, fournissent le nombre pair demandé. Edit: le programme n'a qu'à imprimer UNE PAIRE de nombres premiers, pas tous. Par exemple:

4: 2 + 2

6: 3 + 3

8: 3 + 5

10: 5 + 5 ou 3 + 7


"n'a qu'à imprimer une paire de nombres premiers" Est-ce à dire que nous sommes autorisés à imprimer plus de paires?
Ayiko

Je suppose que si cela raccourcit la longueur de votre code, mais il devrait être organisé
Rationality

Réponses:


11

APL, 34 ou 44 octets

La première version comporte 34 symboles et est limitée aux caractères des jeux de caractères APL d'origine à un octet, tels que celui toujours pris en charge dans Dyalog APL:

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

Explication:

                               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 deuxième version ne fait que 22 symboles, car elle exploite la πfonction pour vérifier les nombres premiers, mais elle n'est disponible que dans NARS2000 qui utilise Unicode, donc le nombre d'octets est de 44 dans UCS-2:

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

Explication:

                   ⎕    ⍝ 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

Exemples

(⎕: est l'invite demandant un numéro)

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

Fonctionnerait ¯2π⍳2πncomme un générateur principal?
Oberon

@Oberon que fait πexactement l' opérateur?
primo

πCommutateurs dyadiques avec : ¯2πxcalcule le xième nombre premier, ¯1πxest le premier nombre premier inférieur à x, 0πxteste x pour la primauté, 1πxest le premier nombre premier supérieur à x, 2πxest le nombre de nombres premiers inférieur à x, 10πxest le nombre de diviseurs de x, 11πxest la somme de tous les diviseurs de x, 12πxet 13πxsont respectivement la fonction de Möbius et la fonction de totient. Enfin, le monadique πxrenvoie la factorisation première de x.
Oberon

@Oberon est spécifique au NARS2000, n'est-ce pas? Semble être un interprète intéressant. Je vais l'essayer et réviser ma réponse.
Tobia

@Tobia C'est? Désolé alors. Je l'ai vu référencé quelque part, mais ils n'ont jamais mentionné NARS2000. Bon à savoir.
Oberon

6

Python 2, 75 71 octets

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

Testez-le sur Ideone .

Comment ça fonctionne

Nous utilisons un corollaire du théorème de Wilson :

corollaire du théorème de Wilson

À tout moment, la variable m est égale au carré de la factorielle de k - 1 ; k commence à la valeur 1 et m à la valeur 0! ² = 1 . L'ensemble p sera composé de 0 et de tous les nombres premiers jusqu'à la valeur actuelle de k .

Dans chaque itération, nous vérifions d'abord si n - k et k appartiennent à p , ce qui est vrai si et seulement si la différence définie de {nk, k} et p est vide. Si c'est le cas, la condition est fausse et la boucle continue.

Notez que k> 0 et {n - k, k} satisferont la condition pour une valeur positive de n - k (en supposant que la conjecture de Goldbach est vraie), donc le 0 dans p ne conduira pas à des faux positifs.

Dans la boucle, nous mettons à jour k et m . La nouvelle valeur de m est m × k² = (k - 1)! ² × k² = k! ² , et la nouvelle valeur de k est k + 1 , donc m = (k - 1)! ² est toujours valable avant et après la mise à jour.

Ensuite, nous effectuons l'union d'ensemble pour ajouter la valeur de m% k × k à p . Par le corollaire du théorème de Wilson, cela ajoutera 1 × k = k si k est premier et 0 × k = 0 sinon.

Lorsque la boucle se termine, nous affichons les dernières valeurs de n - k et k , qui seront des nombres premiers avec la somme n .


Comment diable fonctionne cet algorithme de génération de nombres premiers?
Leaky Nun

@LeakyNun J'ai ajouté une explication.
Dennis

Oh ... c'est du génie.
Leaky Nun

5

Rubis 2.0 (65)

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

4

PHP - 73 octets

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

L'entrée est considérée comme un argument de ligne de commande.

Exemple d'utilisation:

$ php goldbach.php 7098
19+7079

4

GolfScript 41 33 32

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

Accepte l'argument de ligne de commande, par exemple

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

Trouve toutes les partitions pertinentes du numéro d'entrée avec:

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

puis trouve la première partition où aucun nombre n'est pas premier avec:

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

où le bloc de vérification composite npest:

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

ce bloc filtre tous les nombres qui divisent également un nombre donné. S'il n'y a pas de tels nombres (donc le nombre est premier), le résultat est [], ce qui est falsey dans GolfScript.


3

perl 6: 69

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

3

R, 170 112 83 caractères

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

Dentelé:

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)

Usage:

> 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 

Ancienne solution à 112 caractères, pour la postérité

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

Dentelé:

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

C'est à la fois fou et génial !!
Tomas

3

Python - 107

Fondamentalement, une amélioration par rapport à la deuxième partie de la réponse de Nutria (j'ai exécuté ceci sur 2.7 mais je pense que cela devrait également fonctionner pour 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

Les sauts de ligne et les espaces après sont-ils :obligatoires?
mniip

L'onglet peut être réduit à un espace et l'espace avant l'impression peut être supprimé (rase 4 octets).
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)

Vous avez maintenant une expression régulière qui teste la conjecture de Goldbach, qui a peu d'exigences sur les fonctionnalités spéciales (support de référence arrière de base, anticipation positive et négative).

Cela utilise String.prototype.repeat(), qui fait partie de la proposition EcmaScript 6e édition. Actuellement, ce code ne fonctionne que sur Firefox.

J'ai vraiment besoin d'un meilleur langage avec une commande concise lorsque je travaille avec regex ...


2

Scala, 286 192 172 148 caractères

Pas le plus rapide mais ça marche. Appelez g (10) pour obtenir la liste des paires de goldbach pour 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 conversion en C ++ est simple.


2

C - 139 129 caractères

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);}

Vous pouvez raser 8 caractères en supprimant les intdéclarations de votre fonction i. Vous pouvez enregistrer 2 autres caractères en supprimant ifet en ajoutant une autre double esperluette:i(b,2)&&i(a-b,2)&&printf(...)
Josh

Merci! Je n'y ai pas pensé &&. (Je ne m'habituerai jamais au silence de type argument ...)
Oberon

J'adore votre utilisation du ternaire imbriqué.
Josh

2

newLISP - 169 148 caractères

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

inclut le code pour l'exécuter. Les résultats sont trop généreux ...

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

Sauge, 60

Similaire en termes de score et de sensation à la solution de res , mais je pense que c'est assez différent pour poster.

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

2

Sauge , 65 62

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

Avec ce qui précède dans le fichier goldbach.sage, exécutez-le avec Sage en cours d'exécution dans un terminal:

sage: %runfile goldbach.sage 

Merci à @boothby pour l' p=is_primeidée.


Vous pouvez le réduire à 62 en définissant 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]

Explication:

  • gest la fonction "goldbach". L'appel g nvous donne la paire de nombres premiers qui s'additionnent n.
  • pest une fonction qui génère une liste de nombres premiers inférieurs à n.
  • cest la fonction principale de vérification utilisée pour définir p.

L'exemple s'exécute:

*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

Cela renvoie toutes les solutions pour l'entier d'entrée.

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

Par exemple, lorsque 1298 est entré…

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

Comme écrit, il renvoie chaque solution deux fois.

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}}


Entrée 2, demander à un oracle s'il s'arrête, prouver / infirmer la conjecture des nombres premiers jumeaux, gagner
Filipq

1

Julia, 62 caractères (85 avec invite)

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]

Cela n'invite pas l'utilisateur (comme requis), n'est-ce pas?
res

Non, je n'ai pas remarqué ça. Cela ajouterait de nombreux personnages en ce moment julia. g(int(readline(STDIN)))
gggg

1

GTB , 31

Pour votre calculatrice TI-84

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

Pas de modules intégrés principaux.

Exemple d'exécutions

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


1

Python 3 - 150 143 caractères

Ancienne version (150 caractères):

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

Nouvelle version (merci à 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))]

Il imprime chaque combinaison, par exemple:
4 2 + 2
10 7 + 3 5 + 5 3 + 7


|peut être utilisé en toute sécurité avec le type booléen, donc(a+b!=n)|p(a)|p(b)
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Encore plus court en utilisant: print([(a,b)for b in range(2,n)for a in range(2,n)if not((a+b!=n)|p(a)|p(b))])(imprime une liste de tuples, dont la somme est n). Enregistre 8 octets.
agtoever

L'utilisation r=range(2,n)et le référencement rpermettent également d'en économiser quelques-uns.
agtoever

1

q [116 caractères]

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

Aucune fonction intégrée pour trouver le nombre premier.

Contribution

72

Production

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 peu tard pour la fête mais je pratique mes talents de golfeur.

En fait, j'ai codé cela avant de trouver cette question! La mienne n'inclut donc pas la belle lambda que les autres solutions Python utilisent.

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 car

"Demander à l'utilisateur" est le fléau de tout golfeur J. Voilà tous mes personnages durement gagnés!

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

Expliqué:

  • ".1!:1]1- Lisez une chaîne ( 1!:1) depuis l'entrée (descripteur de fichier 1) et convertissez-la en un nombre ( ".).
  • p:i.n=:- Attribuez ce nombre à la variable n, puis prenez les premiers nnombres premiers.
  • +/~- Faire une table d'addition, nlarge et nhaute.
  • i.&n, - Transformez le tableau en une seule liste, puis recherchez l'index de la première occurrence de n , qui existe si la conjecture de Goldbach est vraie.
  • p:(n,n)#: - Récupérez la ligne et la colonne de l'index, et prenez les nombres premiers correspondants.

Usage:

   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

Si l'invite n'était pas une exigence, voici un verbe de 25 caractères:

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

1

Gelée , 8 octets (non concurrent)

_ÆRfÆR.ị

Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça fonctionne

_Æ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 octets

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

Essayez-le en ligne!

Si une fonction était acceptable, le code pourrait être raccourci à 32 octets :

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

Comment ça fonctionne

~=primescrée un alias pour la fonction prime intégrée qui renvoie une liste de tous les nombres premiers jusqu'à son argument. n=ARGS[]|>intanalyse le premier argument de ligne de commande tel qu'il l'enregistre dans n .

Pour trouver une paire appropriée de nombres premiers, nous calculons d'abord la plage de nombres premiers susmentionnée avec ~n. Ensuite, n-~ndonne toutes les différences de ces nombres premiers et n .

En coupant ( ) le résultat avec la plage de nombres premiers elle-même, nous nous assurons que les nombres premiers p restants sont tels que n - p est aussi un nombre premier.

Enfin, extremaprend le premier le plus bas et le plus haut de l'intersection, leur somme doit donc être n .


0

SQL, 295 284

En 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;

Devrait être capable de le faire dans la moitié de l'espace, si ce n'était pour des choses comme "pas de jointure externe gauche en récursivité", "pas de sous-requête en récursivité" ...

Voici la sortie:

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

Lot - 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!

Partez proprement -

@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 octets

57, plus 1 pour -nE

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

L'entrée et la sortie sont unaires. Exemple:

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

Pointe de chapeau.


0

Oracle SQL 11.2, 202 octets

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;   

Non golfé

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 octets

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) est un test de primalité pour x, et g (x) passe en revue les nombres pour trouver deux nombres premiers qui correspondent.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.