Premier jeu de Conway

18

Plus précisément, le PRIMEGAME de Conway .

Il s'agit d'un algorithme conçu par John H. Conway pour générer des nombres premiers en utilisant une séquence de 14 nombres rationnels:

 A   B   C   D   E   F   G   H   I   J   K   L   M   N
17  78  19  23  29  77  95  77   1  11  13  15  15  55
--  --  --  --  --  --  --  --  --  --  --  --  --  --
91  85  51  38  33  29  23  19  17  13  11  14   2   1

Par exemple, F est la fraction 77/29.

Voici donc comment l'algorithme trouve les nombres premiers. En commençant par le nombre 2, recherchez la première entrée de la séquence qui, lorsqu'elle est multipliée, produit un entier. Ici , il est M, 15/2qui produit 15. Ensuite, pour cet entier 15, recherchez la première entrée de la séquence qui, multipliée, produit un entier. C'est le dernier,, Nou 55/1, qui cède 825. Notez la séquence correspondante. (Les plus avisés d'entre vous peuvent reconnaître cela comme un programme FRACTRAN .)

Après quelques itérations, vous obtiendrez les éléments suivants:

2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, 910, 170, 156, 132, 116, 308, 364, 68, 4 ...

Notez que le dernier élément répertorié est 4, ou 2^2. Voici notre premier nombre premier (l' 2exposant) généré avec cet algorithme! Finalement, la séquence ressemblera à ceci:

2 ... 2^2 ... 2^3 ... 2^5 ... 2^7 ... etc.

Ainsi, donnant les nombres premiers. Il s'agit d' OEIS A007542 .

Le défi

Étant donné un numéro d'entrée n, soit zéro, soit un indexé (votre choix), vous pouvez soit sortir les premiers nnombres de cette séquence, soit sortir le nnuméro de cette séquence.

Exemples

Les exemples ci-dessous sortent le ne terme de la séquence indexée zéro.

 n   output
 5   2275
19   4
40   408

Règles

  • Le cas échéant, vous pouvez supposer que l'entrée / sortie s'adaptera au type Integer natif de votre langue.
  • L'entrée et la sortie peuvent être fournies par n'importe quelle méthode pratique .
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
11
Peut-être que le jeu principal de Conway serait un nom plus descriptif pour ce défi que Let's Play a Game . Cela permettrait de retrouver plus facilement ce défi à l'avenir.
Lynn
La sortie peut-elle être un flotteur? 408.0au lieu de 408par exemple.
dylnan
Malheureusement, nous n'avons pas de défi (canonique) "Interpréter Fractran". Celui de Stack Overflow est verrouillé.
user202729
@dylnan Bien sûr, ça va.
AdmBorkBork

Réponses:

5

Python 3 , 173 165 153 145 145 144 136 135 127 126 125 108 107 104 octets

f=lambda n:2>>n*2or[f(n-1)*t//d for t,d in zip(b"NM_M\r7",b"[U3&!\r")if f(n-1)*t%d<1][0]

Essayez-le en ligne!

  • -30 octets grâce à Jonathan Frech!
  • -3 octets grâce à Lynn!

2>>n*2est 2pour n==0et 0autrement.

103 octets si nous pouvons retourner des flottants.

dylnan
la source
Utilisation de Python 2; 153 octets .
Jonathan Frech
@JonathanFrech Cool, belle astuce. Merci!
dylnan
1
Rester en Python 3, 146 octets !
Jonathan Frech
144 octets .
Jonathan Frech
Merci encore, vous en avez fait plus que moi maintenant!
dylnan
5

FRACTRAN , 99 octets

17/2821 78/2635 19/1581 23/1178 29/1023 77/899 95/713 77/589 1/527 11/403 13/341 15/434 15/62 55/31

Essayez-le en ligne!

Le programme prend 2*31^nen entrée, qui est utilisé comme état initial.

Toutes les fractions du programme FRACTRAN d'origine ont été divisées par 31 (le premier registre premier inutilisé), de sorte que le programme s'arrête à la nième itération.

Vincent
la source
Réponse effrontée. ;-)
AdmBorkBork
4

Gelée , 49 43 octets

ד×NŒçøM_M¢¿ÆÐÐ7‘“[U3&!øçŒ×Æ¿Ç£¢‘:@xḍɗḢ
2Ç¡

Essayez-le en ligne!

  • -6 octets grâce aux miles
dylnan
la source
Dommage que 0ọ0¤est inf, sinon vous aurait pu réduire ce 42 octets ...
Erik le Outgolfer
3

Python 3 , 107 octets

f=lambda n,k=2:n and f(n-1,[k*a//b for a,b in zip(b"NM_M\r7",b"[U3&!\r")if k*a%b<1][0])or k

Essayez-le en ligne!

Encode la liste des fractions en ziping deux bytestrings contenant des caractères ASCII bas non imprimables.

Si nest nul, nous renvoyons l'argument k; sinon, nous récursions avec de nouveaux paramètres. Notre nouveau kest la première valeur k*a//bcorrespondant à une fraction (a, b)de la liste telle qu'un k*a//bentier, c'est-à-dire k*a%b<1.

Lynn
la source
2

MATL , 50 octets

Hi:"'0m26<l~l *,..V'31-*'{uSFA=731-+."!'32-&\w~)1)

Essayez-le en ligne!

Luis Mendo
la source
3
Devinez quelles parties du code sont des littéraux de chaîne et quelles sont les déclarations réelles ...
Luis Mendo
2
Hi:... aww, "Bonjour" à toi aussi, code. :-)
AdmBorkBork
2

J , 116110 octets

g=.3 :0
((1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x)([:({.@I.@(=<.){[)*)])^:y 2
)

Essayez-le en ligne!

Indexé 0; renvoie le nième nombre

Certains octets peuvent être enregistrés en rendant le verbe tacite, mais j'ai du mal à faire ^:fonctionner.

Explication:

J décrit les nombres rationnels sous la forme NrD, où N est le numérateur et D est le dénominateur, par exemple 17r91 78r85 19r51 23r38...j'ai créé 2 listes distinctes pour les numérateurs et les dénominateurs et en ai fait 2 nombres en base 96.

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x convertit les nombres de base 96 en listes et construit une liste de fractions en divisant les deux listes.

   1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x
17r91 78r85 19r51 23r38 29r33 77r29 95r23 77r19 1r17 11r13 13r11 15r14 15r2 55

2 commencer par 2

^:yrépéter le verbe à sa gauche n(y est l'argument de la fonction)

] le bon argument (commence à 2, puis utilise le résultat de chaque itération)

* multiplier la liste des fractions par le bon argument

(=<.) sont les résultats entiers (comparer chaque nombre avec son plancher)

{.@I.@trouve l'index I.du premier {.des entiers

{[ utilise l'index pour récupérer le nombre

Galen Ivanov
la source
1
62 octets:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
miles
@miles Merci, je pense que vous devez publier votre solution, c'est bien mieux que le mien.
Galen Ivanov
2

05AB1E ,  44  43 octets

0 indexé

2sF•Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•тв2ä`Š*s‰ʒθ_}нн

Essayez-le en ligne!

Explication

2                                             # initialize stack with 2
 sF                                           # input times do:
   •Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•                  # push a base-255 compressed large number
                            тв                # convert to a list of base-100 digits
                              2ä`             # split in 2 parts to stack
                                 Š            # move denominators to bottom of stack
                                  *           # multiply the last result by the numerators
                                   s‰         # divmod with denominators
                                     ʒθ_}     # filter, keep only those with mod result 0
                                         нн   # get the div result

Le grand nombre poussé est 17781923297795770111131515559185513833292319171311140201

Emigna
la source
1

Pari / GP , 121 octets

n->a=2;for(i=1,n,a=[x|x<-a*[17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55],x\1==x][1]);a

Essayez-le en ligne!

alephalpha
la source
1

JavaScript (Node.js) , 106 95 octets

  • merci à @Arnauld et @Neil pour avoir réduit de 11 octets
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

Essayez-le en ligne!

DanielIndie
la source
J'ai réussi à extraire quelques octets, mais je ne peux m'empêcher de penser que je manque quelque chose: essayez-le en ligne!
Neil
1
@Neil Il n'est pas nécessaire d'utiliser l'opérateur d'étalement Buffer. De plus, je pense qu'il est sûr de mettre toutes les données dans un seul tampon: 95 octets .
Arnauld
@Arnauld L'OP a utilisé l'opérateur d'étalement (je ne connais pas le Buffer donc je ne connaissais pas mieux) mais c'est une bonne chose avec le seul Buffer!
Neil
@Arnauld correct, mis à jour :)
DanielIndie
1

Rétine , 213 octets

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2
\d+
*
"$+"+`((_+)/(_+)¶(.+¶)*)(\3)+$
$1$#5*$2
r`_\G

Essayez-le en ligne! Explication:

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2

Remplacez l'entrée par une liste de toutes les fractions, plus l'entier initial.

\d+
*

Convertissez tout en unaire.

"$+"+`

Répétez la substitution le nombre de fois donné par l'entrée d'origine.

((_+)/(_+)¶(.+¶)*)(\3)+$

Trouvez un dénominateur qui divise également l'entier.

$1$#5*$2

Remplacez l'entier par le résultat de la division multiplié par le numérateur.

r`_\G

Convertissez l'entier en décimal et affichez le résultat.

Neil
la source
1

Attaché , 81 octets

Nest<~{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]},2~>

Essayez-le en ligne! Génère une fraction sur 1. Par exemple, l'entrée 5renvoie2275/1 . Cela peut être corrigé avec plus de 2 octets en ajoutant N@au programme.

Explication

Il s'agit d'une fonction curry, qui curry Nest avec deux arguments prédéfinis:

{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]}

et 2 . Ce dernier argument est simplement la graine initiale, et l'argument qui est passé à cette fonction est le nombre d'itérations pour imbriquer la fonction donnée.

Ce qui suit est utilisé pour encoder PRIMEGAME:

&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]

Ceci est évalué comme tel:

A> "0zmt2R6E<@l<~6l2 0*,,*.-.!V "
"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
[48, 122, 109, 116, 50, 82, 54, 69, 60, 64, 108, 60, 126, 54, 108, 50, 32, 48, 42, 44, 44, 42, 46, 45, 46, 33, 86, 32]
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31
[17, 91, 78, 85, 19, 51, 23, 38, 29, 33, 77, 29, 95, 23, 77, 19, 1, 17, 11, 13, 13, 11, 15, 14, 15, 2, 55, 1]
A> Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
 17 91
 78 85
 19 51
 23 38
 29 33
 77 29
 95 23
 77 19
  1 17
 11 13
 13 11
 15 14
 15  2
 55  1
A> &`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
[(17/91), (78/85), (19/51), (23/38), (29/33), (77/29), (95/23), (77/19), (1/17), (11/13), (13/11), (15/14), (15/2), (55/1)]

Remplaçons cette expression par Gdans l'explication. Notre première fonction devient:

{Find[Integral,_*G]}

Cela effectue une seule itération de code FRACTRAN sur _, l'entrée de la fonction. C'est Findun Integralmembre (un entier) du tableau _*G, qui est l'entrée _multipliée par chaque membre de G.Nestapplique simplement cette transformation le nombre de fois donné.

Attaché, 42 octets

J'ai implémenté des parties de la $langsbibliothèque, étant inspiré par ce défi, je marque donc cette section non concurrente.

Needs[$langs]2&FRACTRAN_EXAMPLES.prime.run

Cela interroge simplement la liste que FRACTRAN_EXAMPLESj'ai. Chaque exemple est une FractranExampleinstance, qui appelle la FRACTRANfonction intégrée . L' primeexemple est PRIMEGAME de Conway.

Conor O'Brien
la source
1

F # (Mono) , 215 octets

let q m=
 let rec i x y=
  if y=m then x 
  else[17;91;78;85;19;51;23;38;29;33;77;29;95;23;77;19;1;17;11;13;13;11;15;14;15;2;55;1]|>List.chunkBySize 2|>List.find(fun[n;d]->x*n%d=0)|>fun[n;d]->i(x*n/d)(y+1)   
 i 2 0

Essayez-le en ligne!

Henrik Hansen
la source
0

PHP, 183 octets (189 avec la balise "php")

Golfé:

$t=2;for(;@$i++<$argv[1];){foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1]as$n){$a=$t*$n;if(preg_match('/^\d+$/',$a)){$t=$a;break;}}}echo$t;

Non golfé:

<?php 
$t=2;
for(;@$i++<$argv[1];){
    foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1] as $n){
        $a=$t*$n;
        if(preg_match('/^\d+$/',$a)){
            $t=$a;break;
        }
    }
}
echo $t;

Essayez-le en ligne!

Boian Ivanov
la source