Pergunta

Eu vi um monte de soluções baseadas em C / C ++ para este problema em que temos de escrever um programa que após a execução imprime sua própria fonte.

algumas soluções -

http://www.cprogramming.com/challenges/solutions/self_print.html

solução Quine página em muitas línguas

Há muitas mais soluções na rede, cada uma diferente da outra. Pergunto-me como é que vamos abordar a esse problema um, o que se passa dentro da mente de quem resolve. Empreste-me alguns insights sobre este problema ... Enquanto soluções em linguagens interpretadas como Perl, PHP, Ruby, etc pode ser fácil ... eu gostaria de saber como se faz para projetá-la em linguagens compiladas ...

Foi útil?

Solução

Além de cheating¹ não há diferença entre linguagens compiladas e interpretadas.

A abordagem genérica para quines é bastante fácil. Em primeiro lugar, qualquer que seja o programa se parece, em algum momento ele tem que imprimir algo:

print ...

No entanto, o que deveria imprimir? Em si. Por isso, precisa imprimir o "imprimir" comando:

print "print ..."

O que deveria imprimir o próximo? Bem, nesse meio tempo, o programa cresceu, por isso precisa imprimir a string começando com "print", também:

print "print \"print ...\""

Agora, o programa cresceu outra vez, então não há outra vez mais para imprimir:

print "print \"print \\\"...\\\"\""

E assim por diante. Com cada código adicionado há mais código para imprimir. Esta abordagem está chegando a lugar nenhum, mas revela um padrão interessante: A "impressão \" string" é repetida uma e outra vez. Seria bom para colocar a parte repetindo em uma variável:

a = "print \""
print a

No entanto, o programa só mudou, por isso precisamos ajustar a:

a = "a = ...\nprint a"
print a

Quando nós agora tentar preencher o "...", nos deparamos com os mesmos problemas que antes. Em última análise, queremos escrever algo como isto:

a = "a = " + (quoted contents of a) + "\nprint a"
print a

Mas isso não é possível, porque mesmo se tivéssemos tal função um quoted() para citar, ainda há o problema que nós definimos a em termos de si mesma:

a = "a = " + quoted(a) + "\nprint a"
print a

Assim, a única coisa que podemos fazer é colocar um espaço reservado para a:

a = "a = @\nprint a"
print a

E esse é o truque! Qualquer outra coisa é agora claro. Basta substituir o titular do lugar com o conteúdo cotados de a:

a = "a = @\nprint a"
print a.replace("@", quoted(a))

Uma vez que mudaram o código, precisamos ajustar a cadeia:

a = "a = @\nprint a.replace(\"@\", quoted(a))"
print a.replace("@", quoted(a))

E é isso! Todos os quines em todas as línguas assim que funciona (Exceto os batota).

Bem, você deve garantir que você só substituir a primeira ocorrência do titular do lugar. E se você usar um segundo titular lugar, você pode evitar a necessidade de citar a string.

Mas essas são questões menores e fácil de resolver. Se o fato, a realização de quoted() e replace() são os únicos detalhes em que os vários quines realmente diferem.


¹, fazendo o programa ler seu arquivo fonte

Outras dicas

Há um par de diferentes estratégias para escrever quines. A mais óbvia é a de código apenas gravação que abre o código e imprime-lo. Mas os mais interessantes envolvem recursos de linguagem que permitem a auto-incorporação, como o recurso printf% de estilo s em muitas línguas. Você tem que descobrir como incorporar alguma coisa para que ele acaba resolvendo a solicitação para ser incorporado. Eu suspeito que, como palíndromos, um monte de tentativa e erro está envolvido.

Além disso, você pode estudar como Core Wars jogo funciona. Seria um bom exemplo, eu acho.

A abordagem usual (quando você não pode enganar *) é escrever algo que codifica a sua fonte em uma constante corda, em seguida, imprime essa constante duas vezes: uma vez como um literal de cadeia, e uma vez como código. Que fica em torno do "cada vez que eu escrever uma linha de código, eu tenho que escrever uma outra para imprimi-lo para fora!" problema.

'Engano' inclui: - Usando uma linguagem interpretada e simplesmente carregar a fonte e imprimi-lo -. Arquivos longos 0 bytes, que são válidos em algumas linguagens, como C

Para se divertir, eu vim com um no esquema, que eu era muito orgulhoso por aproximadamente 5 minutos até que eu descobri foi descoberto antes. De qualquer forma, há uma ligeira modificação para as "regras" do jogo para melhor contagem para a dualidade de dados e código em Lisp: em vez de imprimir a fonte do programa, que é uma S-expressão que retorna-se:

((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))

O um em Wikipedia tem o mesmo conceito, mas com um (mais detalhado) mecanismo ligeiramente diferente para citar. Eu como o meu melhor ainda.

Uma idéia para pensar sobre a codificação e como dar algo um duplo significado para que ele possa ser usado para imprimir algo em um par de formas. Há também a cavaet que este tipo de problema vem com restrições para tornar mais difícil, pois sem quaisquer outros do que a própria saída do programa regras, o programa vazio é uma solução.

Você pode encontrar algumas soluções para este aqui: http: // forums.thedailywtf.com/forums/p/5232/147528.aspx

Como cerca de realmente ler e imprimir o seu código-fonte? A sua não é difícil em tudo !! Heres um em php:

<?php
{
header("Content-Type: text/plain");
    $f=fopen("5.php","r");
    while(!feof($f))
    {
        echo fgetc($f);
    } 
    fclose($f);
}
?>

Em Python, você pode escrever:

s='c=chr(39);print"s="+c+s+c+";"+s';c=chr(39);print"s="+c+s+c+";"+s

inspirado a partir desta pseudo-código de auto impressão:

Print the following line twice, the second time with quotes.
"Print the following line twice, the second time with quotes."

Eu fiz um exemplo AS3 para os interessados ??nesta

var program = "var program = @; function main(){trace(program.replace('@', 

String.fromCharCode(34) + program + String.fromCharCode(34)))} main()"; 
function main(){
   trace(program.replace('@', String.fromCharCode(34) + program + String.fromCharCode(34)))
}
main()

Em Ruby:

puts File.read (_ _ _ _ ARQUIVO)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top