Programa que emite um programa que emite um programa… que emite “Olá!”

8

Desafio

Escreva o programa mais curto P, de modo que

  • P pega qualquer número inteiro positivo n como entrada e gera uma sequência de programas P 1
  • executar P 1 (sem entrada) gera uma sequência de programa P 2 ,

  • executar P 2 (sem entrada) gera uma sequência de programa P 3 ,

  • ...

  • execução de P n (sem entrada) envia exatamente "Olá!" (sem as aspas).

Esquematicamente:

                P (n) → P 1 → P 2 → ... → P n → Olá!

Critério

  • A E / S é via stdin / stdout.
  • O comprimento do programa é medido em bytes.
  • Os programas consistem apenas em caracteres imprimíveis ASCII.
  • Não deve haver duplicatas entre os programas P, P 1 , ..., P n .

EDIT: Os programas P, P 1 , ..., P n devem ser código fonte e "executar o programa" refere-se a qualquer processamento que produz a saída (ou seja, interpretação, compilação e execução, etc.).

res
fonte
1
Relacionado: codegolf.stackexchange.com/questions/5510/can-you-meta-quine
dmckee --- ex-moderator kitten
@dmckee - O relacionamento, se houver, parece muito remoto. Esquematicamente, o comportamento de um quine é como P -> P , e o comportamento dos programas vinculados é como P -> Q -> P ; mas aqui o comportamento é como P (n) -> ...--> Olá! , em que P não é necessário para se parecer com nenhuma das saídas.
res
1
Isso não é uma crítica, apenas uma observação de que as pessoas que gostam desse problema também podem gostar do outro.
dmckee --- gatinho ex-moderador
@dmckee - Bom ponto, obrigado.
res

Respostas:

10

Golfscript 39 14

~'Hello!'{`}@*

Exemplo:

Supondo que n = 4 e nosso programa seja P , estas são as etapas:

  1. Execute P com o parâmetro 4 . A saída é "\"\\\"\\\\\\\"Hello!\\\\\\\"\\\"\""( P 1 )

  2. Execução de saídas P 1"\"\\\"Hello!\\\"\"" ( P 2 )

  3. Execução de saídas P 2"\"Hello!\"" ( P 3 )

  4. Execução de saídas P 3"Hello!" ( P 4 )

  5. Executando saídas P 4Hello! . Se você não confia em mim, siga este link ☺.

Cristian Lupascu
fonte
1
Acho que seu P1, P2, P3, P4 está se comportando conforme necessário, mas com a entrada de stdin, seu P não gera P1 - em vez disso, ele gera \'\\\'\\\\\\\'Hello!\\\\\\\'\\\'\'(ou seja, sem as aspas externas), quando eu o executo tanto no Linux quanto no Linux. Win 7 (usando echo 4 | ...em um prompt de comando). Alguma idéia de qual possa ser o problema?
res
@res Você está certo; isso é uma falha do site de testes Golfscript que eu criei. Consegui consertar isso adicionando três caracteres, mas, enquanto isso, encontrei uma versão muito mais curta e editei meu post.
Cristian Lupascu
@res A versão correta da antiga abordagem é~''\(,{)2\?('\\'*}/]"'"*:z"'Hello!"z-1%"'"
Cristian Lupascu
Com 14 bytes, impressionante! ... e bom site btw. (Parece que o stdin pode ser simulado precedendo um programa por ;"...", onde ...está a entrada. Por exemplo, ;"4"teria revelado o problema de cotações ausentes acima, enquanto simplesmente precedendo o programa por "4"não.) ...
res
@res Muito obrigado! Você está absolutamente certo sobre a liderança ;. Quando escrevi o primeiro programa, esqueci-me disso ao longo do caminho, embora tenha sido eu quem o escreveu no meta site: meta.codegolf.stackexchange.com/a/521/3527
Cristian Lupascu
4

JavaScript, 58 caracteres

function $(_){alert(_?$+'$('+--_+')':'Hello!')}$(prompt())
cópia de
fonte
Como isso funciona?
precisa
@ thepirat000 Se o argumento _for 0, ele gera, caso contrário, ele exibe a definição da função e chamada com "Olá!" _um menos
copiar
+1 por abusar de regras utilizando um contador em vez de alongar o código ...
Wally West
4

Perl ( 45 36)

say"say q("x($m=<>),"Hello!",")"x$m         

Corra com perl -M5.010para usar say.

For n=1, saídas say q(Hello!)
For n=2, saídas say q(say q(Hello!))
Para n=3, saídas say q(say q(say q(Hello!)))
e assim por diante.

marinus
fonte
2

Python3, 66

r="print(%r)";e=eval;n=e(input())+1;e(e("(r%"*n+"'Hello!'"+")"*n))
Ev_genus
fonte
2

Lisp comum, 68 caracteres

(do((n(read)(1- n))(s'(princ"Hello!")`(print',s)))((= 0 n)(eval s)))
(do ((n (read) (1- n))
     (s '(princ "Hello!") `(print ',s)))
    ((= 0 n) (eval s)))

A única coisa não-direta: gera mais um nível de programa do que o necessário e avalia-o, porque evalé um caractere menor que print.

Kevin Reid
fonte
2

Lisp comum: 65

#1=(SETF N(READ)(CADDR'#1#)(1- N)W(PRINT(IF(= N 0)"Hello!"'#1#)))

Esta versão é menor que a resposta CL existente. Caso seu Lisp coaxe com um stackoverflow, você precisará usar isso, 81 bytes:

#1=(SETF N(READ)*PRINT-CIRCLE* T(CADDR'#1#)(1- N)W(PRINT(IF(= N 0)"Hello!"'#1#)))

Sei que estou atrasado para a festa e tenho certeza de que isso ainda pode ser otimizado.

Demonstração (cuidado, alguns REPLs on-line não funcionam corretamente):

* #1=(SETF N(READ)*PRINT-CIRCLE* T(CADDR'#1#)(1- N)W(PRINT(IF(= N 0)"Hello!"'#1#)))
2
#1=(SETF N 1
         *PRINT-CIRCLE* T
         (CADDR '#1#) (1- N)
         W
           (PRINT
            (IF (= N 0)
                "Hello!"
                '#1#))) 
#1=(SETF N 1
         *PRINT-CIRCLE* T
         (CADDR '#1#) (1- N)
         W
           (PRINT
            (IF (= N 0)
                "Hello!"
                '#1#)))
* (eval *)

#1=(SETF N 0
         *PRINT-CIRCLE* T
         (CADDR '#1#) (1- N)
         W
           (PRINT
            (IF (= N 0)
                "Hello!"
                '#1#))) 
#1=(SETF N 0
         *PRINT-CIRCLE* T
         (CADDR '#1#) (1- N)
         W
           (PRINT
            (IF (= N 0)
                "Hello!"
                '#1#)))
* (eval *)
"Hello!" 
"Hello!"
* 

Observe que:

  • Testado usando SBCL 1.2.11.debian

  • Existem muitos avisos porque estou fazendo coisas que não deveriam ser feitas com seriedade. Felizmente, todos os avisos são impressos com ponto-e-vírgula, para que sejam tratados como comentários de qualquer maneira.

  • A duplicação ocorre porque um é o valor de retorno e uma saída real. Se o valor de retorno também conta, simplifica para 58 bytes:#1=(SETF N(READ)(CADDR'#1#)(1- N)W(IF(= N 0)"Hello!"'#1#))

  • Eu ainda sei que estou atrasado para a festa

Mike Gebirge
fonte
1

Python 2.7, 57

print reduce(lambda x,y:y+`x`,input()*["print"],"Hello!")
JPvdMerwe
fonte
1

Haskell, 62

main=interact$(iterate(("main=putStr"++).show)"Hello!"!!).read
Joey Adams
fonte
1

Bash, 47 ou 12 (se eu usar golfbash)

Código:

read x;for((;x>=0;x--)){ O+=" echo";};$O Hello!

código golfbash:

R;n e Hello!

Código anterior (49):

read x;E=echo;eval \"\${E[0]\"{0..$x}\"}\" Hello!

Usar:

Tornar programa P

$ echo '<paste code here>' > P

$ chmod +x P

Exemplo

Faça P1:

$> echo 4 | ./P > 
echo echo echo echo Hello!

Faça P2:

$> echo 4 | ./P | bash
echo echo echo Hello!

Faça P3:

$ echo 4 | ./P | bash | bash
echo echo Hello!

Faça P4:

$ echo 4 | ./P | bash | bash | bash
echo Hello!

Execute P4:

$ echo 4 |./P | bash | bash | bash | bash
Hello!

Digamos que eu criei uma nova linguagem de uso geral chamada golfbash - parecida com golfscript - que possui alguns comandos úteis como estes:

R which reads stdin and places result into variable $REPLY.
n $1 $2 which echo's $1 $REPLY times followed by $2.
e which echo's all parameters to stdout.

Então eu poderia escrever isso:

R;n e Hello!

Isso seria legal, não é?

philcolbourn
fonte
1
Isso é rude. -1 para quê?
22414 phpBaixar
+1. Eu acho que o voto negativo foi para a sua linguagem inventada que parece ser especificamente para esse desafio. Veja meta.codegolf.stackexchange.com/questions/871/…
Cees Timmerman
Tudo bem, mas eu fiz isso no bash também.
philcolbourn
0

F #, 182

let say msg = sprintf "%s" msg
let gen num = 
    let rec g n a =
        match n with
        | i when i > 0 -> g (i-1) ("say \"" + a + "\"")
        | _ -> say a
    g num "Hello!"
vasu
fonte
Quando executo o seu programa , ele não parece inserir nada do stdin, nem gerar nada para o stdout.
res
0

J - 31 char

Lembre-se de que J usa seqüências de caracteres no estilo Pascal: 'It''s too easy!'

'Hello!'(],,)''''#~<:2^".1!:1]1

Explicado:

  • ".1!:1]1 - Leia uma linha do stdin e converta-a em um número.
  • <:2^ - Leve 2 para a potência desse número e diminua.
  • ''''#~ - Faça uma sequência com tantas cópias do caractere de aspas simples.
  • 'Hello!'(],,)- Anexe essas aspas à frente e atrás de Hello!.

Uso:

   'Hello!'(],,)''''#~<:2^".1!:1]1   NB. let's try 3
3
'''''''Hello!'''''''
   '''''''Hello!'''''''  NB. P1
'''Hello!'''
   '''Hello!'''          NB. P2
'Hello!'
   'Hello!'              NB. and P3 prints Hello!
Hello!
algoritmshark
fonte
0

Python 2.7: 75

def h(n):
 return "Hello"if n<1 else'print %s' % `h(n-1)`
print h(input())

Golfe pela primeira vez, não tenho certeza se estou fazendo certo; p

heo
fonte
2
Isso não pressupõe que a definição de htambém seja conhecida nos programas subseqüentes? (Para que isso teria de ser executado em um REPL ou algo assim?)
Martin Ender
0

Clojure, 36 bytes

(str(apply str(repeat 5\'))"Hello!")

Símbolo

'something

avalia como

something

Crie um símbolo com 5 aspas simples e execute o resultado até que não haja mais aspas.

Michael M
fonte