Buraco 2 - Prime Quine

9

Encontre o Buraco 1 aqui .

Faça uma solução que, quando executada, produz seu próprio bloco de código-fonte várias vezes. De fato, ele deve produzi-lo n vezes, onde n no próximo número primo.

Eu acho que um exemplo mostra melhor.

[MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]

Cada programa emitirá seu "bloco" base (então [MY QUINE]) nos próximos números primos .

Funções internas para calcular se um número é primo (como uma função isPrime) ou para determinar o próximo primo (como uma função nextPrime ()) não são permitidas.

  • Isso significa que as funções para listar o número de divisores não são permitidas
  • Funções que retornam a fatoração principal também não são permitidas

Isso deve ser um problema real (exceto por uma margem de manobra, veja o próximo ponto); portanto, você não deve ler seu próprio código-fonte.

Como linguagens como Java e C # já estão em desvantagem, você não precisa gerar um código totalmente funcional. Se puder ser colocado em uma função (chamada) e gerar a próxima pergunta, você estará bem.

Isso é código-golfe, então o código mais curto vence!

Stretch Maniac
fonte
Ninguém respondeu ao buraco 1, então, qual é a pontuação que todos que respondem ao primeiro buraco?
Optimizer
11
Você poderia esclarecer a parte com as funções principais? Podemos usá-los ou não podemos usá-los?
Martin Ender
3
O que é considerado verificação primária e o que não é? Considerando que a verificação nobre pode ser construída usando qualquer Quine se este tipo, as regras são o suficiente para não clara
haskeller orgulhoso
@ Otimizador: Todo mundo tem uma pontuação de 0 para o primeiro buraco até que alguém atenda.
Stretch Maniac
2
@StretchManiac Você deve mencionar claramente na pergunta que a lista de métodos de fatoração primários e a lista de métodos de divisores também não são permitidos. Poste a pergunta na Sandbox na próxima vez.
Optimizer

Respostas:

5

CJam, 31 bytes

{'_'~]-3>U):U{)__,1>:*)\%}g*}_~

Experimente on-line no intérprete CJam .

Idéia

Para verificar a primalidade, usaremos o teorema de Wilson , que afirma que um número inteiro n> 1 é primo se e somente se (n - 1)! -1 (mod n) , o que é verdadeiro se e somente se (n - 1)! + 1% n == 0 .

Código

{                           }_~ e# Define a block and execute a copy.
                                e# The original block will be on top of the stack.
 '_'~]                          e# Push those characters and wrap the stack in an array.
      -3>                       e# Keep only the last three elements (QUINE).
         U):U                   e# Increment U (initially 0).
             {           }g     e# Do-while loop:
              )__               e# Increment the integer I on the stack (initially U).
                 ,1>            e#   Push [1 ... I-1].
                    :*          e#   Multiply all to push factorial(I-1).
                      )\%       e#   Push factorial(I-1) + 1 % I.
                                e# While the result is non-zero, repeat.
                                e# This pushes the next prime after U.
                           *    e# Repeat QUINE that many times.
Dennis
fonte
Como você encontrou esse método de verificação do prime oO
Optimizer
3
Lembrado seria mais preciso. É conhecido como teorema de Wilson.
Dennis
mp(is prime?) existe agora, portanto, na versão mais recente do CJam, pode-se reduzir um pouco mais isso.
Lynn
11
@Mauris Existia na primeira versão pública, IIRC. No entanto, a pergunta proíbe os operadores primos e de fatoração.
Dennis
1

CJam, 36 35 bytes

{]W="_~"]U):U{)_,{)1$\%!},,2>}g*}_~

Definitivamente, isso pode ser ainda mais jogado.

Como funciona:

{                               }_~   "Copy this code block and execute the copy";
 ]W=                                  "Take just the last element from the stack";
                                      "The other thing on stack is the block from above";
    "_~"]                             "Put "_~" on stack and wrap the 2 things in an array";
                                      "At this point, the string representation of stack"
                                      "elements is identical to the source code";
         U):U                         "Increment U and update U's value. This  variable"
                                      "actually counts the number of [Quine] blocks";
             {)_,{)1$\%!},,2>}g       "Find the next prime number"
                               *      "Repeat the array that many times, thus repeat the"
                                      "[Quine] block, the next prime times";

Obrigado a Martin por me lembrar o ]W=truque :)

Experimente online aqui

Optimizer
fonte
1

Mathematica, 248 222 bytes

Edit: Corrigido o uso de uma função relacionada ao prime, mas também melhorava um pouco o quining.

Edit: Obrigado a Dennis por me apresentar o teorema de Wilson.

1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#\2&@@("*"&,For[i=n,Mod[++i!/i+1,i]>0,0];i]")&,For[i=n,Mod[++i!/i+1,i]>0,0];i]

Isso pressupõe que o kernel é encerrado entre execuções subseqüentes do quine (ou pelo menos né redefinido), porque depende de nser indefinido antes da [MyQuine]execução da primeira instância .

Provavelmente isso pode ser muito reduzido, mas não tenho muita experiência com quines, especialmente no Mathematica.

Aqui está uma explicação:

1;

Isso não faz nada, mas se concatenado no final do quine anterior, multiplica o resultado da última expressão por 1(que é um no-op) e o ponto e vírgula suprime a saída. Isso garante que apenas a última cópia [MyQuine]imprima alguma coisa.

n=If[ValueQ@n,n+1,1];

Este inicializa na 1na primeira cópia [MyQuine]e, em seguida, incrementa-o 1em cada cópia adicional - ou seja, este apenas a contagem de quantas cópias existem no n.

Pule para o final agora:

For[i=n,Mod[++i!/i+1,i]>0,0];i

Este encontra o próximo primo usando o teorema de Wilson .

StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("QUINE_PREFIX"*"QUINE_SUFFIX")&,NEXTPRIME[n]]

Este é o quine real. Ele cria NextPrime@ncópias do próprio código. Também é um pouco estranho. Sim, estou multiplicando duas strings por lá, e nenhuma que não tenha um resultado significativo. QUINE_PREFIXcontém todo o código antes das duas cadeias e QUINE_SUFFIXcontém todo o código após as duas cadeias. Agora normalmente você usa Apply(ou @@) para transformar uma lista em uma série de argumentos. Mas você pode substituir qualquer Headcom Apply- por exemplo multiplicação. Portanto, apesar de ser um produto, ainda posso transformá-lo em dois argumentos para minha função. Essa função faz:

#<>ToString[1##,InputForm]<>#2

Onde #está o primeiro argumento (a sequência do prefixo), #2é o segundo argumento (a sequência do sufixo), ##é uma sequência dos dois argumentos. Preciso anexar 1para preservar a multiplicação - caso contrário, isso ##seria exibido na lista de argumentos para ToString. Enfim, ToString[1##,InputForm]&@@("abc"*"def")retorna "abc"*"def"... exatamente o que eu preciso!

Eu acho que com todas as coisas que eu preciso em torno do quine, um evalquine baseado em um seria mais apropriado aqui. Vou analisar isso mais tarde ou amanhã.

Martin Ender
fonte
@ MartinBüttner a pergunta deve ser editada
proud haskeller
Heh, também posso usar o Teorema de Wilson para igualar minha entrada a Denis ';)
Optimizer
@Optimizer Mas no meu caso não havia perigo de ofender ninguém, porque eu ainda estou usando 7 vezes como muitos bytes como o dois de você;)
Martin Ender
@ MartinBüttner eu sei: D É por isso que eu não usá-lo :)
Optimizer
0

J - 60 caracteres

Usa o método next-prime como as outras respostas. (Essa é a parte 4 p:.)

((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''

Um truque bonitinho J é que f :gage como fquando dado um argumento e gquando dado dois. Portanto, se você escrever, diga f :;'a'f :;'a'f :;'a'que é assim f'a';'a';'a', o que é ótimo, porque é uma lista em caixa cujos itens são 'a'e cujo tamanho é o número de ocorrências.

Para que possamos elevar isso a um tipo de coisa refinada. A faparência que usamos (foo $~ bar), onde fooconstrói a parte da string que repetimos repetidamente, barencontra o próximo número primo e o multiplica por 60, o comprimento da string em foo.

   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
180
   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
300
algoritmshark
fonte
Você pode modificar seu código para atender às novas especificações? Métodos que produzem o próximo prime não são permitidos. Obrigado.
Stretch Maniac
0

Python 2.7, 214

from sys import*;R,s=range,chr(35)
def N(n):
 if n<3:return n+1
 for p in R(n+1,n+n):
    for i in R(2, p):
     if p%i==0:break
     else:return p
P=file(argv[0]).read();print(P.split(s)[0]+s)*N(P.count(chr(37)));exit(0)
#
dieter
fonte