Existem 95 caracteres ASCII imprimíveis :
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Na fonte Consolas (o bloco de código Stack Exchange padrão), alguns dos caracteres têm espelhos em torno de um eixo vertical de simetria:
- Esses pares de caracteres são espelhos um do outro:
()
[]
{}
<>
/\
- Esses personagens são espelhos de si mesmos:
! "'*+-.8:=AHIMOTUVWXY^_ovwx|
(Observe que o espaço é um). - Estes não têm espelhos:
#$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~
( i
, l
, 0
, #
, E, provavelmente, outros personagens são seus próprios espelhos em algumas fontes, mas vamos ficar com as formas Consolas.)
Diz-se que uma corda é um espelho de si mesma se for feita apenas com os 39 caracteres de espelho , organizados de modo que a corda tenha uma linha vertical central de simetria. Assim ](A--A)[
é um espelho de si mesmo, mas ](A--A(]
não é.
Escreva um programa uniforme de uma linha que seja um espelho de si mesmo. Quando N cópias da metade esquerda tiverem sido anexadas a ele e N cópias da metade direita tiver sido anexadas a ele, ele deverá gerar N + 1. N é um número inteiro não negativo.
Por exemplo, se o programa foi ](A--A)[
(metade esquerda:, ](A-
metade direita:) -A)[
, então:
- A execução
](A--A)[
deve sair1
. (N = 0) - A execução
](A-](A--A)[-A)[
deve sair2
. (N = 1) - A execução
](A-](A-](A--A)[-A)[-A)[
deve sair3
. (N = 2) - A execução
](A-](A-](A-](A--A)[-A)[-A)[-A)[
deve sair4
. (N = 3) - . . .
- A execução
](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[
deve sair10
. (N = 9) - etc.
Regras
- Saída para stdout ou a alternativa mais próxima do seu idioma. Pode haver uma nova linha opcional à direita. Nenhuma entrada deve ser tomada.
- Teoricamente, o processo deve funcionar para N até 2 15 -1 ou mais, com memória e poder de computação suficientes.
- É necessário um programa completo, não apenas um comando REPL .
O programa inicial mais curto (caso N = 0) em bytes vence.
fonte
#
é a sua própria relação também, mas, você está certo, não em consolas.Respostas:
Pip,
1284 bytesAgora com 66% menos bytes!
x
é uma variável pré-inicializada para""
. No contexto numérico, isso se torna0
.+
, faz uma expressão da formax+x+...+x
. Esta é uma declaração válida que não faz nada.+
da primeira metade, faz uma expressão da forma++x+x+...+x
.++x
incrementax
para1
, e o restante adiciona a ele N vezes. Como as expressões são avaliadas da esquerda para a direita no Pip, é garantido que o incremento ocorra primeiro e o resultado é igual ao número de níveis de espelho.Infelizmente, o Pip não funciona bem ao processar grandes expressões: esta solução causa um
maximum recursion depth exceeded
erro para N acima de 500 ou mais. Aqui está uma solução anterior que não funciona, por 8 bytes :Mais sobre Pip
fonte
Fatal error: maximum recursion depth exceeded while calling a Python object
.x+x+...+x
gera O (N) profundidade de recursão. Talvez isso invalide esta resposta. Vou adicionar uma nota.GolfScript, 10 bytes
Experimente online com o Web Golfscript: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
O Web GolfScript tem um limite de 1024 caracteres, mas o interpretador Ruby manipula N = 32767 perfeitamente:
Como funciona
Sem nenhuma entrada, o GolfScript inicialmente possui uma string vazia na pilha.
Na primeira metade esquerda, acontece o seguinte:
!
aplica NOT lógico à string vazia. Isso empurra1
.:{
salva o inteiro na pilha na variável{
.Sim, esse é um identificador válido, embora não haja maneira de recuperar o valor armazenado.
)
incrementa o número inteiro na pilha.:
é uma instrução incompleta.Nas metades esquerdas subsequentes, acontece o seguinte:
:!
(onde:
fica uma sobra de antes) salva o número inteiro na pilha na variável!
.Sim, esse também é um identificador válido. Isso quebra o
!
comando, mas não o usamos mais.:{
,)
E:
trabalho como antes.Na primeira metade direita, acontece o seguinte:
::
(onde:
fica uma sobra de antes) salva o número inteiro na pilha na variável:
.Sim, mesmo esse é um identificador válido. Assim como com
{
, não há como recuperar o valor armazenado.(
diminui o número inteiro na pilha, produzindo o número de metades esquerdas.}
, pois é incomparável e finaliza a execução imediatamente.Este é um recurso não documentado. Eu os chamo de super-comentários .
O código restante é simplesmente ignorado.
fonte
}
na segunda metade do seu código em uma competição de espelhos."\""/"
, a quarta citação dupla também não teria comparação, pois a segunda foi escapada.Código da máquina Z80,
86 bytes *<8ww8>
* Assume certas condições ao entrar no Amstrad BASICA
é inicialmente 0 quando inserido no BASIC. IncrementaA
n vezes e depois escreve n vezes no mesmo local de memória (que é definido como BASIC em um local ligeiramente aleatório)! AJR
operação Jump Relative nunca faz nada, já que oC
sinalizador está sempre desmarcado; portanto, é usado para "comentar" o seguinte byte! Esta versão é um pouco trapaceira, assumindo-se certas condições de entrada, como a entrada de garantias BASIC queA
são sempre 0. A localização de(HL)
não é garantida como segura e, de fato, é provavelmente uma localização perigosa. O código abaixo é muito mais robusto e é por isso que é muito mais longo.Código da máquina Z80, 30 bytes
Como ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Basicamente, a primeira metade garante a criação de um valor zero e a segunda metade o incrementa e grava na memória. Na versão expandida abaixo
##
denota código que não serve para nada na metade do espelho.Repartição das instruções permitidas:
Das 39 instruções permitidas, 28 são operações de carregamento (o bloco de 0x40 a 0x7F são
LD
instruções de byte único ), a maioria das quais não ajuda aqui! A única instrução de carregamento na memória ainda permitida é oLD (HL), A
que significa que tenho que armazenar o valorA
. ComoA
é o único registro que resta com umaINC
instrução permitida, isso é realmente bastante útil!Não consigo carregar
A
com 0x00 porque o ASCII 0x00 não é um caractere permitido! Todos os valores disponíveis estão longe de 0 e todas as instruções matemáticas e lógicas foram proibidas! Exceto ... eu ainda posso fazerADD HL, HL
, adicione 16 bitsHL
a si mesmo! Além de carregar diretamente os valores (sem uso aqui!), INCrementingA
e DECrementingA
,L
ouHL
é a única maneira que tenho de alterar o valor de um registro! Na verdade, existe uma instrução especializada que pode ser útil no primeiro semestre, mas é difícil trabalhar no segundo semestre, e uma instrução complementar que é quase inútil aqui e ocuparia apenas espaço.Então, eu achei o valor mais próximo de 0 que eu pude: 0x41. Como isso é perto de 0? Em binário, é 0x01000001. Então eu diminuo, carrego
L
e façoADD HL, HL
duas vezes!L
agora é zero, no qual carrego de voltaA
! Infelizmente, o código ASCII paraADD HL, HL
é)
agora preciso usar(
duas vezes. Felizmente,(
éJR Z, e
, ondee
é o próximo byte. Portanto, ele devora o segundo byte e eu só preciso garantir que ele não faça nada, tomando cuidado com aZ
bandeira! A última instrução para afetar aZ
flag foiDEC A
(contra-intuitivamente,ADD HL, HL
não a altera) e, como eu sei queA
era 0x40 naquele momento, é garantido queZ
não está definido.A primeira instrução na segunda metade
JR Z, #28
não fará nada nas primeiras 255 vezes, porque o sinalizador Z só pode ser definido se A tiver excedido de 255 para 0. Depois disso, a saída estará errada, no entanto, pois ele está salvando valores de 8 bits de qualquer maneira que não deveria importar. O código não deve ser expandido mais de 255 vezes.O código deve ser executado como um trecho, pois todas as formas disponíveis de retorno limpo foram desabilitadas. Todas as instruções RETurn estão acima de 0x80 e as poucas operações de salto permitidas só podem pular para um deslocamento positivo, porque todos os valores negativos de 8 bits também foram proibidos!
fonte
A
registro é sempre de 8 bits, caso contrário, o processador não seria compatível com o Z80. Eu diria que, dada a memória e o poder de computação suficientes , foram cobertos aqui!A
registro de nada além de 8 bits? Mudá-lo para 16 bits quebraria o código contando com 255 + 1 = 0, por exemplo. Você precisaria inventar uma CPU, vamos chamá-la de Z160, que usa um registro de 16 bits padrão, mas ainda usa as mesmas instruções de 8 bits do Z80. Esquisito!J,
1614 bytesUsos:
Explicação:
J avalia da direita para a esquerda.
(_=_)
é oinf equals inf
que é verdadeiro, tem um valor de1
, então a expressão se torna1+]...[+1
. ((8=8)
também funcionaria, mas isso parece mais legal. :))[
e]
retorne os argumentos esquerdo e direito, respectivamente, se eles tiverem 2 argumentos. Se eles recebem apenas 1, retornam isso.+
adiciona os 2 argumentos. Se obtiver apenas 1, retornará isso.Agora vamos avaliar uma expressão de nível 3 (da direita para a esquerda):
Como vemos, a metade direita
1
é adicionada e o lado esquerdo1
é omitido, resultando no número inteiro desejadoN
, o nível do espelho.Experimente online aqui.
fonte
Haskell, 42 bytes
Felizmente, um comentário de linha em Haskell (->
--
) é espelhado e metade dele (->-
) é uma função válida. O resto é matemática para obter os números0
e1
. Basicamente, temos(0)-(-1)
um comentárioN=0
e um prefixo(0)-(-1)-
em cada etapa.Se números de ponto flutuante são permitidos para saída, podemos construir a
1
partir8/8
e seguir com 26 bytes:Haskell, 26 bytes
Saídas
1.0
,2.0
etc.fonte
program.hs
e depois executar$ runhaskell program.hs
na linha de comando e ver a saída. Eu não conheço Haskell, então não posso dizer exatamente o que precisa mudar.runhaskell
é um script de shell que configura algum ambiente e finalmente chamaghc
o compilador Haskell. Você pode executar o meu código diretamente comghc
:ghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"
. Isso inicia,ghc
que avalia o código fornecido como argumento, imprime o resultado e sai. Sem REPL, sem interação. É claro que isso adicionaria +1 à contagem de bytes de-e
.-e
não contribui para a pontuação neste caso. Nós não contamos bytes paraperl -E
ougcc -std=c99
também.CJam, 14 bytes
Experimente on-line no intérprete CJam: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Observe que esse código termina com uma mensagem de erro. Usando o interpretador Java, essa mensagem de erro pode ser suprimida fechando ou redirecionando o STDERR.1 1
Como funciona
Nas metades esquerdas, acontece o seguinte:
]
quebra a pilha inteira em uma matriz.X
anexa1
a essa matriz.:+
calcula a soma de todos os elementos da matriz.Oo
imprime o conteúdo da matriz vazia (ou seja, nada).Na primeira metade direita, acontece o seguinte:
o
imprime o número inteiro na pilha, que é a saída desejada.O+
tenta anexar uma matriz vazia ao item mais alto da pilha.No entanto, a pilha estava vazia antes de empurrar
O
. Isso falha e finaliza a execução do programa.O código restante é simplesmente ignorado.
1 De acordo com a meta enquete Os envios devem ser autorizados a sair com um erro? , isso é permitido.
fonte