A entrada consistirá nos seguintes caracteres:
^
: Suba umv
: Desça um▲
ouk
: sobe dois▼
ouj
: desça duas
Por exemplo, a seguinte entrada:
^^▲^v▼▲^^v
produziria a seguinte saída:
^
^ ^ v
▲ v ▲
^ ▼
^
Sequências de escape que movem o cursor como \e[B
não são permitidas. Você deve produzir a saída usando espaços e novas linhas.
Aqui estão mais alguns casos de teste.
▲v^v^v^v^v^v^v^v▲
▲
▲ ^ ^ ^ ^ ^ ^ ^
v v v v v v v v
^^^^^^^▲▲▲▼▼▼vvvvvv
▲
▲ ▼
▲ ▼
^ ▼
^ v
^ v
^ v
^ v
^ v
^ v
v^^vv^^vvv^v^v^^^vvvv^^v^^vv
^ ^ ^
^ v ^ v ^ v ^
v v v ^ ^ ^ v ^ ^ v
v v v v ^ v v
v
j
descer duas vezes ek
subir duas vezes também.Respostas:
Pitão, 27 bytes
Experimente on-line: Demonstration or Test Suite
Eu uso
k
e emj
vez de▲
e▼
. Existem muitas linhas vazias iniciais e finais. Você precisa procurar um pouco para encontrar a imagem. Aqui está uma versão de 34 bytes , que remove todas as linhas vazias iniciais e finais.Experimente on-line: Demonstration or Test Suite
Explicação:
fonte
Ilegível ,
219921452134210420872084 bytesSuporta tanto
k
/j
como também▲
/▼
sintaxe.Em boa tradição ilegível, eis o programa formatado em fonte proporcional, para ofuscar a distinção entre apóstrofos e aspas duplas:
Este foi um desafio incrível. Obrigado por postar!
Explicação
Para ter uma idéia do que o ilegível pode ou não fazer, imagine Brainfuck com uma fita infinita nas duas direções, mas, em vez de um ponteiro de memória mover uma célula de cada vez, você pode acessar qualquer célula de memória desmarcando um ponteiro. Isso é bastante útil nessa solução, embora outras operações aritméticas - incluindo o módulo - tenham que ser feitas manualmente.
Aqui está o programa como pseudocódigo com o comentário do diretor:
Tanta coisa para a lógica do programa. Agora precisamos traduzir isso para Ilegível e usar mais alguns truques de golfe interessantes.
As variáveis são sempre desreferenciadas numericamente em Ilegível (por exemplo,
a = 1
torna-se algo parecido*(1) = 1
). Alguns literais numéricos são mais longos que outros; o menor é 1, seguido por 2, etc. Para mostrar o número de números negativos mais longos, aqui estão os números de -1 a 7:Claramente, queremos alocar a variável nº 1 à que ocorre com mais frequência no código. No primeiro loop while, esse é definitivamente o
mod5
que ocorre 10 vezes. Mas não precisamosmod5
mais depois do primeiro loop while, para que possamos realocar o mesmo local de memória para outras variáveis que usamos mais tarde. Estes sãoptr2
eptr3
. Agora a variável é referenciada 21 vezes no total. (Se você estiver tentando contar o número de ocorrências, lembre-se de contar algo comoa++
duas vezes, uma para obter o valor e outra para defini-lo.)Há apenas uma outra variável que podemos reutilizar; depois que calculamos os valores do módulo,
ch
não é mais necessário.up
edn
suba o mesmo número de vezes, então qualquer um está bem. Vamos mesclarch
comup
.Isso deixa um total de 8 variáveis únicas. Poderíamos alocar variáveis de 0 a 7 e iniciar o bloco de memória (contendo os caracteres e os números de linha) em 8. Mas! Como 7 tem o mesmo comprimento de código que -1, também poderíamos usar as variáveis -1 a 6 e iniciar o bloco de memória em 7. Dessa forma, toda referência à posição inicial do bloco de memória é um pouco mais curta em código! Isso nos deixa com as seguintes atribuições:
Agora, isso explica a inicialização no topo: é 5 porque é 7 (o início do bloco de memória) menos 2 (o incremento obrigatório na primeira condição while). O mesmo vale para as outras duas ocorrências de 5 no último loop.
Observe que, como 0 e 4 têm o mesmo comprimento no código,
ptr
eminLine
podem ser alocados de qualquer maneira. ... Ou poderiam?E os misteriosos 2 no penúltimo loop while? Isso não deveria ser um 6? Queremos apenas diminuir os números no bloco de dados, certo? Quando chegamos a 6, estamos fora do bloco de dados e devemos parar! Seria uma vulnerabilidade de segurança de falha de erro de bug de estouro de buffer!
Bem, pense no que acontece se não pararmos. Nós decrementamos as variáveis 6 e 4. A variável 6 é
mod4
. Isso é usado apenas no primeiro loop while e não é mais necessário aqui, para não causar danos. E a variável 4? O que você acha que deveria ser a variável 4ptr
ou deveria serminLine
? Isso mesmo,minLine
também não é mais usado neste momento! Assim, a variável nº 4 éminLine
e podemos diminuí-la com segurança e não causar danos!ATUALIZAÇÃO 1! Jogou golfe de 2199 a 2145 bytes ao perceber que também
dn
pode ser mesclado , embora ainda seja usado no cálculo do valor paramod5
mod5
dn
! A nova atribuição de variável agora é:ATUALIZAÇÃO 2! Golfou de 2145 a 2134 bytes ao perceber que, desde
mod5
agora está na mesma variável quedn
, que é contada como 0 em um loop while,mod5
não precisa mais ser explicitamente inicializada como 0.ATUALIZAÇÃO 3! Jogou de 2134 a 2104 bytes ao realizar duas coisas. Primeiro, embora valha a pena a idéia do “módulo negativo”
mod5
, o mesmo raciocínio não se aplica amod4
porque nunca testamos contramod4+2
etc. Portanto, mudarmod4 ? mod4+1 : -3
paramod4 ? mod4-1 : 3
nos leva a 2110 bytes. Segundo, comomod4
sempre é 0 ou 2, podemos inicializarmod4
para 2 em vez de 0 e reverter os dois ternários (emmod4 ? 3 : 1
vez demod4 ? 1 : 3
).ATUALIZAÇÃO 4! Jogou de 2104 a 2087 bytes ao perceber que o loop while que calcula os valores do módulo sempre é executado pelo menos uma vez e, nesse caso, Ilegível permite reutilizar o valor da última instrução em outra expressão. Assim, em vez de
while --ch: [...]; up = (mod5 ? mod5+1 ? [...]
agora termosup = ((while --ch: [...]) ? mod5+1 ? [...]
(e dentro desse loop while, calculamosmod4
primeiro, de modo que essamod5
é a última declaração).ATUALIZAÇÃO 5! Joguei de 2087 a 2084 bytes ao perceber que, em vez de escrever as constantes
32
e10
(espaço e nova linha), posso armazenar o número 10 na variável # 2 (agora não utilizada) (vamos chamá-loten
). Em vez deptr3 = 5
escreverten = (ptr3 = 5) + 5
,32
torna - seten+22
eprint 10
torna - seprint ten
.fonte
CJam, 37 bytes
Isso imprime linhas vazias antes e depois da saída desejada, que foi permitida pelo OP .
Experimente online no intérprete CJam .
Como funciona
fonte
Python 2, 102
Imprime linha por linha.
Faz um loop através de caracteres na entrada e rastreia a altura atual. A altura é atualizada por um dos
+2, +1, -1, -2
calculado por'kv_^j'.find(c)-2
. Provavelmente existe uma cadeia de mods mais curtaQuando a altura atual é igual ao número da linha (que pode ser negativa), acrescentamos o caractere atual à linha e, de outra forma, acrescentamos um espaço. Então, imprimimos a linha. Na verdade, é mais curto iniciar a altura no número da linha atual e subtrair as alterações de altura, acrescentando o caractere quando o valor atingir
0
.Os números das linhas abrangem um intervalo grande o suficiente para que uma sequência de dois ou dois pares permaneça nela. Na verdade, há uma boa quantidade de excesso. Se tivéssemos um limite superior no comprimento da entrada, seria mais curto escrever, digamos
j=999
.Surpreendentemente,
i and' 'or c
foi mais curto que o habitual[' ',c][i==0]
. Observe quei
pode ser negativo, o que elimina alguns truques comuns.fonte
MATLAB, 116
É um começo. O
j
ek
torná-lo uma dor no pescoço, como eu não consigo encontrar uma maneira de mapear matematicamente dej^vk
para[-2 -1 1 2]
e com o MATLAB não reconhecendo o Unicode (aparentemente, tanto para cima quanto para baixo têm um valor de 26 no MATLAB. Vamos entender!), Existem muitos bytes desperdiçados no mapeamento.Inspirando-se na solução @xnors, o código pode ser reduzido em outros 14 caracteres mapeando o caractere de controle dentro do loop for.
Também há muitos bytes desperdiçados tentando explicar se a string de entrada envia o padrão de volta abaixo do índice em que foi iniciada (talvez se houvesse um limite no comprimento da string, eu poderia simplificar esse bit).
E em sua forma legível:
fonte
b=[-2 -1 1 2](a==[106 107 94 118])
? Funciona em oitava. Ou mesmob=[-2 -1 1 2](a-94==[12 13 0 24])
se você quiser economizar mais um byte!==
paradas que funcionam, e também no MATLAB, você não pode colocar um()
após a[]
.+=
, fwiw.)JavaScript (ES6), 140
Teste a execução do snippet abaixo em um navegador compatível com EcmaScript 6 (testado no Firefox).
fonte
GS2, 34 bytes
Este calcula corretamente os limites de saída para que nenhum espaço em branco em excesso seja produzido. Aqui está a minha solução em hexadecimal
Uma pequena explicação está em ordem. Na pilha, temos a entrada do usuário como uma matriz de códigos ASCII. O programa inicia em uma string literal por causa do
05
. Aqui vamos nós.GS2, 24 bytes
Também tenho uma solução de 24 bytes que não toma muito cuidado ao calcular o tamanho da saída e acaba com espaço em branco extra. Eu prefiro aquele com o espaço em branco reduzido ao mínimo.
fonte
Lápis de cera , 13 bytes (não competitivo)
Experimente online! Usa as setas reais porque porque não.
Não competir porque o Crayon é muito mais novo que esse desafio.
Como funciona
O Crayon é uma linguagem baseada em pilha projetada para ser uma ameaça nos desafios da arte ASCII. Ele é construído em torno da base de uma "tela" de saída bidimensional e de um "giz de cera", um cursor que viaja por essa tela. Tudo o que é enviado para a saída é desenhado na tela na posição do giz de cera e na direção em que o giz de cera está voltado. Por padrão, o giz de cera aponta para o leste (à direita).
fonte
pb - 136 bytes
Usa
k
e emj
vez de▲
e▼
.Algumas notas:
Escape sequences that move the cursor such as \e[B are not allowed. You must produce the output using spaces and newlines.
Eu sigo esta regra! O pb usa o conceito de "pincel" para gerar caracteres. O pincel se move pela tela e pode imprimir um caractere imediatamente abaixo dela. No entanto, a implementação real imprime o caractere usando espaços e novas linhas.You are allowed trailing spaces and/or empty lines
. Isso ocorre por alguns motivos:n
ela começa emY=3n+1
. O-1
é porque ele está indo para baixo3n
a partir deY=-1
, e a partir deY=2n-1
falhar por uma entrada de todosk
.Você pode assistir a este programa em ação no YouTube! Esta versão é ligeiramente modificada na medida em que apenas desce para
n-1
. Funciona para essa entrada, mas falhará para outras pessoas. No entanto, captura muito melhor.Com comentários:
fonte
Ceilão, 447 bytes
Ou com quebras de linha para "legibilidade":
import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}
Isso funciona com as entradas ▲ / ▼ e j / k (se tivéssemos que suportar apenas uma delas, o programa seria 8 bytes mais curto). A última linha de saída está vazia quando a posição inicial estava nela (ou seja, a primeira entrada era a
▲
ou^
e nunca mais chegamos a isso mais tarde). A entrada que não é um dos caracteres especificados será simplesmente impressa como está, sem mudar a linha:→
Aqui está uma versão formatada (753 bytes):
Este é um programa "orientado a objetos" quase direto ... a classe (local)
L
(buffer de linha) armazena uma linha de texto (int
), bem como ponteiros (anuláveis) para os próximos (n
) e anteriores (p
) linha. Os atributos (não anuláveis)u
(para cima) ed
(para baixo) inicializam aqueles se necessário (com um ponteiro reverso para si mesmo) e, nesse caso, também acompanham a primeira e a última linha geral (nof
el
variáveis ).o
a
método (anexar) anexa um caractere a essa linha, incluindo alguns espaços eventualmente necessários.c
é a linha atual. Analisamos a string de entrada (usandoreadLine
como a entrada deve estar em uma linha) usando uma instrução switch que atualiza a linha atual e, em seguida, chama o método append.Após a conclusão da análise, iteramos as linhas da primeira à última, imprimindo cada uma delas. (Isso destrói o
f
ponteiro, se necessário depois, deveríamos ter usado uma variável separada para isso.)Alguns truques usados para jogar golfe:
Algumas coisas que em outros idiomas seriam palavras-chave são na verdade apenas identificadores no
ceylon.language
pacote e podem ser renomeadas com uma importação de alias - usamos isso para as anotaçõesshared
(usadas 5 ×) evariable
(usadas 6 ×), bem como para o objetonull
(usado 4 ×):(Curiosidades: o formatador no IDE do Ceilão formata algumas anotações de linguagem incorporadas, entre elas
variable
eshared
, colocando-as na mesma linha da declaração anotada, contrasta com as anotações personalizadas, que são colocadas em uma linha separada acima da declaração. torna a versão formatada do programa de golfe ilegível, portanto, alterei o alias-imports novamente para esta versão.)this
,void
,case
,else
São palavras-chave reais e não pode ser renomeado desta maneira, eInteger
,String
eCharacter
aparecer apenas uma vez cada um, então não há nada a ser adquirida através da importação.Originalmente, eu também tinha uma classe ScreenBuffer separada (que acompanhava a lista vinculada de buffers de linha, o índice atual e assim por diante), mas como havia apenas um objeto, ela foi otimizada.
Essa classe Screenbuffer também tinha
up
edown
métodos, que foram chamados a partir do analisador (e apenas o fizeramcurrentLine = currentLine.up
respectivamentecurrentLine = currentLine.down
). Ele mostrou que fazer isso diretamente no comutador do analisador é mais curto. Também permitiu escrevercurrentLine = currentLine.up.up
(que mais tarde se tornouc = c.u.u
) em vez decurrentLine = currentLine.up;currentLine = currentLine.up
.Originalmente, passamos o índice atual como argumento para o método append (e até para o analisador do loop) - ter uma variável na função que contém é mais curta.
Originalmente, meu método printAll usava o ponteiro atual e o movia primeiro para cima até que a linha atual estivesse vazia e depois para baixo enquanto imprimia cada linha. Isso quebrou ao usar ▲ e ▼ para pular linhas, então tivemos que acrescentar explicitamente algo nessas linhas saltadas. Manter o controle da primeira / última linha se mostrou mais fácil (embora tenha sido necessário o uso de duas instruções de impressão, porque não existe um ciclo de execução no Ceilão).
Originalmente, eu tinha algo parecido com isto:
process.readLine
retornanull
se não houver linha que possa ser lida (porque a entrada foi fechada) e o compilador Ceylon exige que eu verifique isso antes de acessarinput
. Como neste caso eu não quero fazer nada, posso usar de forma equivalente oelse
operador que retorna seu primeiro argumento, se não nulo, e o segundo argumento, salvando a variável e a instrução if. (Isso também nos permite codificar uma entrada padrão para testar:for (x in process.readLine() else "^^▲^v▼▲^^v") {
)fonte
JavaScript (ES6), 228 bytes
Bem, aqui está uma solução recursiva (bastante longa) que passa em todos os casos de teste fornecidos. Foi um bom desafio. Isso usa
k
ej
no lugar de▼
e▲
.Snippet de teste
Embora o envio em si só possa manipular
k,j
, o seguinte snippet pode manipular ambosk,j
e▼,▲
.fonte