Escreva um programa que imprima a seguinte linha de 80 caracteres:
Este programa do codegolf.stackexchange.com permite-se codificar uma string.
depois aceita uma linha de entrada e depois imprime seu código-fonte com seus pontos de código possivelmente reordenados (nenhum adicionado e nenhum excluído). Quando esse código é executado, o mesmo precisa acontecer, exceto que a linha impressa seria a linha de entrada mais recente.
O regex no estilo Perl ^[A-Za-z0-9. ]{80}$
corresponderá a qualquer linha de entrada. Você não pode fazer nenhuma suposição adicional.
A pontuação de uma submissão é o número de pontos de código em seu código-fonte menos 94 . Menor é melhor.
O código não deve fazer nada que seja inaceitável em uma solução ( por exemplo, leitura de arquivo). Em particular, qualquer envio com uma pontuação negativa deve estar enganando de alguma forma, como 93! é menor que 64 80 .
21/04/2014 adicionado: O código-fonte inteiro do seu programa deve estar bem formado na codificação de caracteres sob a qual você conta pontos de código. Por exemplo, você não pode usar 80 bytes consecutivos no intervalo de bytes à direita UTF-8 (80..BF) e contar cada um como um único CARACTER DE SUBSTITUIÇÃO U + FFFD (ou pior, como nenhum ponto de código).
Além disso, se a codificação permitir várias maneiras de codificar um ponto de código ( por exemplo, SCSU ), seu programa, bem como todos os programas que gera direta ou indiretamente, deverá usar apenas um deles (ou pelo menos todos deverão ser tratados de forma equivalente em todo o código )
Respostas:
GolfScript,
231162131Como funciona
Começamos escolhendo 94 caracteres diferentes que serão permutados para codificar uma sequência. Quaisquer 94 caracteres funcionariam, mas escolhemos o seguinte para fins de golfe:
Vamos chamar a matriz desses caracteres "&".
A linha de entrada sempre conterá 81 caracteres (incluindo o LF). Todos esses caracteres estão presentes nos primeiros 65 caracteres de "&". Esse é o único motivo para escolher caracteres nos 128 bytes superiores.
Substituímos cada caractere da string pelo seu índice em “&”, para que LF se torne 0, o espaço se torne 1 etc.
Consideramos os 81 números obtidos os dígitos de um único número base 65. Vamos chamar esse número de "N".
Agora, enumeramos todas as permutações possíveis de "&" e recuperamos a permutação correspondente ao número acima. Isso é alcançado da seguinte maneira:
c = 1
eA = []
.N % c
aA
.N = N / c
ec = c + 1
.c < 95
, volte para 2.i = 0
es = ""
.&[A[i]]
, anexe-o a "s" e remova-o de "&".i = i + 1
.i < 94
voltar para 6.Suponha que tenhamos blocos de código "E" e "D" que codificam e decodificam uma string, conforme explicado acima.
Agora, precisamos de um invólucro para os blocos de código que atendem aos requisitos da pergunta:
Isso faz o seguinte:
{…}.~
define um bloco, duplica e executa a segunda cópia. A primeira cópia permanecerá na pilha.\.$
troca a sequência codificada pelo bloco e cria uma cópia da sequência codificada, com caracteres classificados.[{}/]:&;
converte a string de cima em uma matriz, salva em "&" e a descarta.D puts
decodifica a sequência codificada e imprime o resultado.'"#{`head -1`}"'~
lê uma linha de entrada executandohead -1
no shell.E "'".@+\+
codifica a sequência e precede e acrescenta uma aspas simples.\'.~'
troca a sequência codificada e o bloco e anexa a sequência'.~'
.Após a execução do bloco, o GolfScript imprime o conteúdo da pilha (sequência codificada, bloco,
'.~'
) e sai."E" pode ser definido da seguinte forma:
"D" pode ser definido da seguinte forma:
Golfe final:
Substitua
\.$[{}/]:&;0&@
por0@.$[{}/]:&\
para salvar dois caracteres.Defina a função
{;65base}:b
para salvar um caractere.Remova todo o espaço em branco, exceto o LF à direita e o LF na string.
Exemplo
fonte
Perl,
14281099Possui 1193 caracteres ASCII (incluindo 960 dígitos binários permutados). 1193 - 94 = 1099
Meu primeiro design
Antes de receber uma sugestão de Dennis para mudar para binário, meu programa permutava dígitos octais.
Meu primeiro design codifica cada string em 160 dígitos octais, com 2 dígitos por caractere. Essa codificação possui 100 8 = 64 caracteres diferentes. O sistema octal possui 8 dígitos diferentes. O programa deve ter 160 cópias de cada dígito, para permitir 8 × 160 = 1280 dígitos.
Eu mantenho 160 dígitos
$s
e os outros 1120 dígitos$t
. Começo com um programa que não é adequado, mas apenas imprime as atribuições para$s
e$t
para a próxima execução. É isso:(() = $s =~ /$_/g))
é uma atribuição a uma lista vazia de variáveis. Eu tomo esse truque no tutorial de contexto do PerlMonks . Força o contexto da lista no operador de correspondência=~
. No contexto escalar, a correspondência seria verdadeira ou falsa, e eu precisaria de um loop$i++ while ($s =~ /$_/g)
para contar as correspondências. No contexto da lista,$s =~ /$_/g
há uma lista de correspondências. Eu coloquei essa lista no contexto escalar de uma subtração, para que o Perl conte os elementos da lista.Para fazer um quine, tomo o formulário
$_=q{print"\$_=q{$_};eval"};eval
dos perl quines do Rosetta Code . Este atribui uma stringq{...}
para$_
e depois chamaeval
, para que eu possa ter meu código em uma string e também executá-lo. Meu programa se torna um Quine quando eu envolver minha terceira a última linha em$_=q{
e};eval
, e mudar o meu passadoprint
paraprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Finalmente, eu jogo meu programa alterando a primeira tarefa para
$t
para um comentário e removendo caracteres extras.Possui 1522 caracteres ASCII (incluindo 1280 dígitos octais permutados).
1522 - 94 = 1428
A mudança para binário
Nos comentários, Dennis notou que 960 dígitos binários permutados seriam menores que 1280 dígitos octais. Então, eu gráfico o número de dígitos permutados para cada base de 2 a 16.
Embora a base 8 seja o mínimo local, as bases 2 e 3 e 4 são a melhor base, com 960 dígitos permutados. Para o código de golfe, a base 2 é melhor porque o Perl tem conversões para a base 2.
A substituição de 1280 dígitos octais por 960 dígitos binários salva 320 caracteres.
Mudar o código de octal para binário custa 8 caracteres:
oct
paraoct'0b'.$_
custos 7./../g
para/.{6}/g
custos 2."%02o"
para "% 06b" `custa 0.160
para480
custos 0.0..7
para0,1
salvar 1.Aprendi algumas dicas de golfe em Perl . Eles economizam 14 caracteres:
'A'..'Z','a'..'z','0'..'9'
paraA..Z,a..z,0..9
, usando palavras de barra e números simples, salva 12 caracteres."\n"
para$/
salva 2 caracteres.Eu salvo 3 caracteres movendo o
#$t
comentário para o final do arquivo. Isso remove a nova linha que termina o comentário e um literal\n
no quine.Essas alterações salvam um total de 329 caracteres e reduzem minha pontuação de 1428 para 1099.
fonte