Conway's Prime Game


18

In particolare, PRIMEGAME di Conway .

Questo è un algoritmo ideato da John H. Conway per generare numeri primi usando una sequenza di 14 numeri razionali:

 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

Ad esempio, F è la frazione 77/29.

Quindi ecco come l'algoritmo trova i numeri primi. A partire dal numero 2, trova la prima voce nella sequenza che quando moltiplicata insieme produce un numero intero. Qui è M, 15/2che produce 15. Quindi, per quel numero intero 15, trova la prima voce nella sequenza che quando moltiplicata produce un numero intero. Questo è l'ultimo N, o 55/1, che cede 825. Annota la sequenza corrispondente. (L'astuto tra voi potrebbe riconoscere questo come un programma FRACTRAN .)

Dopo alcune iterazioni, otterrai quanto segue:

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

Si noti che l'ultimo elemento elencato è 4o 2^2. Ecco il nostro primo numero primo (l' 2esponente) generato con questo algoritmo! Alla fine, la sequenza sarà simile alla seguente:

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

Quindi, dando i numeri primi. Questo è OEIS A007542 .

La sfida

Dato un numero di input n, zero o uno-indicizzato (a scelta), emette i primi nnumeri di questa sequenza o emette il nnumero th di questa sequenza.

Esempi

Gli esempi seguenti mostrano il ntermine della sequenza indicizzata zero.

 n   output
 5   2275
19   4
40   408

Regole

  • Se applicabile, puoi supporre che l'input / output si adatti al tipo intero nativo della tua lingua.
  • L'input e l'output possono essere forniti con qualsiasi metodo conveniente .
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

11
Forse il gioco principale di Conway sarebbe un nome più descrittivo per questa sfida rispetto a Let's Play a Game . Ciò renderebbe più semplice ritrovare questa sfida in futuro.
Lynn,

L'output può essere un float? 408.0invece che 408per esempio.
dylnan,

Sfortunatamente non abbiamo una sfida (canonica) "Interpret Fractran". Quello su Stack Overflow è bloccato.
user202729

@dylnan Certo, va bene.
AdmBorkBork,

Risposte:


5

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

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]

Provalo online!

  • -30 byte grazie a Jonathan Frech!
  • -3 byte grazie a Lynn!

2>>n*2è 2per n==0e 0altrimenti.

103 byte se possiamo restituire float.


Utilizzando Python 2; 153 byte .
Jonathan Frech,

@JonathanFrech Fantastico, bel trucco. Grazie!
dylnan,

1
Soggiornare in Python 3, 146 byte !
Jonathan Frech,


Grazie ancora, hai fatto più di me adesso!
dylnan,

5

FRACTRAN , 99 byte

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

Provalo online!

Il programma accetta 2*31^ncome input, che viene utilizzato come stato iniziale.

Tutte le frazioni del programma FRACTRAN originale sono state divise per 31 (il primo registro primo non utilizzato), quindi il programma si ferma all'ennesima iterazione.


Risposta sfacciata. ;-)
AdmBorkBork


3

Python 3 , 107 byte

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

Provalo online!

Codifica l'elenco delle frazioni zipinserendo due bytestring contenenti caratteri ASCII bassi non stampabili.

Se nè zero, restituiamo l'argomento k; altrimenti ricorreremo con nuovi parametri. Il nostro nuovo kè il primo valore k*a//bcorrispondente ad una frazione (a, b)dell'elenco tale che k*a//bè un numero intero, cioè k*a%b<1.



2

J , 116 110 byte

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

Provalo online!

0-indicizzati; restituisce l'ennesimo numero

Alcuni byte possono essere salvati rendendo il verbo tacito, ma ho problemi a far ^:funzionare.

Spiegazione:

J descrive i numeri razionali nella forma NrD, dove N è il numeratore e D è il denominatore, ad esempio 17r91 78r85 19r51 23r38...ho creato 2 liste separate per i numeratori e denominatori e ne ho ricavato 2 numeri base-96.

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x converte i numeri di base 96 in elenchi e costruisce un elenco di frazioni dividendo i due elenchi.

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

2 inizia con 2

^:yripeti il ​​verbo sui ntempi a sinistra (y è l'argomento della funzione)

] l'argomento giusto (inizia da 2, quindi utilizza il risultato di ogni iterazione)

* moltiplicare l'elenco delle frazioni per l'argomento giusto

(=<.) sono i risultati interi (confronta ogni numero con il suo piano)

{.@I.@trova l'indice I.del primo {.degli interi

{[ utilizza l'indice per recuperare il numero


1
62 byte:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
miglia

@miles Grazie, penso che tu debba pubblicare la tua soluzione, è molto meglio della mia.
Galen Ivanov,

2

05AB1E ,  44  43 byte

0-indicizzato

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

Provalo online!

Spiegazione

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

Il grande numero premuto è 17781923297795770111131515559185513833292319171311140201



1

JavaScript (Node.js) , 106 95 byte

  • grazie a @Arnauld e @Neil per la riduzione di 11 byte
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

Provalo online!


Riuscito a spremere un paio di byte, ma non posso fare a meno di pensare che mi sto perdendo qualcosa: provalo online!
Neil,

1
@Neil Non è necessario utilizzare l'operatore di diffusione su Buffer. Inoltre, penso che sia sicuro mettere tutti i dati in un singolo buffer: 95 byte .
Arnauld,

@Arnauld L'OP ha usato l'operatore spread (non ho familiarità con Buffer, quindi non ne sapevo nulla di meglio) ma è una mossa eccezionale con il singolo Buffer!
Neil,

@Arnauld correct, aggiornato :)
DanielIndie

1

Retina , 213 byte

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

Provalo online! Spiegazione:

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

Sostituisci l'input con un elenco di tutte le frazioni, più il numero intero iniziale.

\d+
*

Converti tutto in unario.

"$+"+`

Ripeti la sostituzione il numero di volte indicato dall'input originale.

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

Trova un denominatore che divide uniformemente l'intero.

$1$#5*$2

Sostituisci il numero intero con il risultato della divisione moltiplicato per il numeratore.

r`_\G

Converti il ​​numero intero in decimale e genera il risultato.


1

Attache , 81 byte

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

Provalo online! Emette una frazione su 1. Ad esempio, input 5restituisce 2275/1. Questo può essere risolto con più 2 byte anteponendo N@al programma.

Spiegazione

Questa è una funzione curry, che curry Nest con due argomenti predefiniti:

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

e 2. Quest'ultimo argomento è semplicemente il seme iniziale e l'argomento che viene passato a questa funzione è il numero di iterazioni per annidare la funzione data.

Quanto segue viene utilizzato per codificare PRIMEGAME:

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

Questo viene valutato come tale:

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

Sostituiamo questa espressione con Gnella spiegazione. La nostra prima funzione diventa:

{Find[Integral,_*G]}

Ciò esegue una singola iterazione del codice FRACTRAN sopra _, l'input per la funzione. È Findun Integralmembro (uno che è un numero intero) dell'array _*G, che è l'input _moltiplicato per ciascun membro di G. Nestapplica semplicemente questa trasformazione il dato numero di volte.

Attache, 42 byte

Ho implementato parti della $langsbiblioteca, ispirandomi a questa sfida, quindi segnare questa sezione come non competitiva.

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

Questo richiede semplicemente l'elenco di FRACTRAN_EXAMPLESI have. Ogni esempio è FractranExampleun'istanza, che chiama la FRACTRANfunzione integrata . L' primeesempio è PRIMEGAME di Conway.


1

F # (Mono) , 215 byte

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

Provalo online!


0

PHP, 183 byte (189 con tag "php")

Golfato:

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

Ungolfed:

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

Provalo online!

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.