Os caras ASCII de olhos esquisitos gostam de trocar de ASCII Ii
:
>_> <_< >_< <_>
Dada uma série de caras safados, espaçados ou linhas separadas, mude o Ii
lado para o outro, deixou a parede e endireitou o céu:
Ii
O menor shifter ganha o prêmio.
Diga o quê?
Escreva um programa ou função que inclua uma sequência de uma lista arbitrária desses quatro emoticons ASCII, separados por espaço ou nova linha (com uma nova linha opcional à direita):
>_>
<_<
>_<
<_>
Por exemplo, a entrada pode ser
>_> >_> <_>
ou
>_> >_> <_>
(O método que você apoia depende de você.)
Cada emoticon executa uma ação diferente nos caracteres I
e i
, que sempre começam assim:
Ii
>_>
desloca-seI
para a direita em um, se possível, e desloca-sei
para a direita em um.<_<
deslocaI
para a esquerda em um, se possível, e deslocai
para a esquerda em um, se possível.>_<
deslocaI
para a direita em um, se possível, e deslocai
para a esquerda em um, se possível.<_>
mudaI
para a esquerda em um, se possível, e depoisi
para a direita em um.
I
não pode ser deslocado para a esquerda se estiver na borda esquerda da linha (como está inicialmente) e não pode ser deslocado para a direita se i
estiver diretamente à sua direita (como está inicialmente).
i
não pode ser deslocado para a esquerda se I
estiver diretamente para a esquerda (como é inicialmente), mas sempre pode ser deslocado para a direita.
Observe que, com essas regras, I
sempre permanecerá à esquerda de i
e tentará I
ser alterado antes i
para todos os emoticons.
Seu programa ou função precisa imprimir ou retornar uma sequência da Ii
linha final após aplicar todos os turnos na ordem indicada, usando espaços (
) ou pontos ( .
) para espaço vazio. Espaços ou períodos finais e uma nova linha final são opcionalmente permitidos na saída. Não misture espaços e períodos.
Por exemplo, a entrada
>_> >_> <_>
tem saída
I...i
porque as mudanças se aplicam como
start |Ii >_> |I.i >_> |.I.i <_> |I...i
O código mais curto em bytes vence. O desempatador é a resposta votada mais alta.
Casos de teste
#[id number]
[space separated input]
[output]
Usando .
para maior clareza.
#0
[empty string]
Ii
#1
>_>
I.i
#2
<_<
Ii
#3
>_<
Ii
#4
<_>
I.i
#5
>_> >_>
.I.i
#6
>_> <_<
Ii
#7
>_> >_<
.Ii
#8
>_> <_>
I..i
#9
<_< >_>
I.i
#10
<_< <_<
Ii
#11
<_< >_<
Ii
#12
<_< <_>
I.i
#13
>_< >_>
I.i
#14
>_< <_<
Ii
#15
>_< >_<
Ii
#16
>_< <_>
I.i
#17
<_> >_>
.I.i
#18
<_> <_<
Ii
#19
<_> >_<
.Ii
#20
<_> <_>
I..i
#21
>_> >_> <_>
I...i
#22
<_> >_> >_> >_> <_> <_<
.I...i
#23
<_> >_> >_> >_> <_> <_< >_< <_< >_<
..Ii
#24
>_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_<
...I.....i
Respostas:
CJam, 33 bytes
Usa o mesmo algoritmo da minha resposta Python , exceto com a indexação 0. Essencialmente:
<
para -1 e>
para 1I
e aplicar ai
, alternamos qual posição atualizamos após cada setaObrigado a @ MartinBüttner por jogar a etapa de saída e decolar 5 bytes.
Experimente online | Suíte de teste
fonte
Perl,
595654 bytesInclui +1 para
-p
Corra com a entrada no STDIN, por exemplo
perl -p shifty.pl <<< ">_> <_< >_< <_>"
shifty.pl
:Explicação
As instruções suplentes string de controle para
i
eI
e a regra é a mesma para ambos se você formulá-las como:<
Mover para a esquerda se houver um espaço à esquerda>
Mova para a direita se houver um espaço ou final de corda à direitaEntão, eu vou trocar
i
eI
na sequência de destino em cada etapa, então só preciso aplicar a regra a uma letra de cada vez. Isto é oy/iI/Ii/
Vou percorrer a cadeia de controle procurando
<
e>
usando uma substituição que geralmente é a maneira mais curta em perl para processar algo caractere por caractere. Para evitar ter que escrever$var =~
, quero a string de controle na variável padrão perl$_
. E eu também quero uma maneira fácil de distinguir<
a partir>
. Tudo isso pode ser realizado usandoA sequência de destino que eu também quero manipular usando substituições e, pelo mesmo motivo, também quero isso
$_
.$_
ser duas coisas ao mesmo tempo parece impossível.No entanto, posso pegar meu bolo e comê-lo também porque o
$_
interior de uma substituição não precisa permanecer igual ao de$_
substituição. Uma vez que o perl começou a substituir uma string, essa string não será alterada, mesmo se você alterar a variável da qual a string veio originalmente. Então você pode fazer algo como:Quero substituir o original
$_
pela inicial"Ii"
apenas na primeira vez em que o corpo de substituição é executado (caso contrário, continuo redefinindo a sequência de destino). Porém, essa substituição também deve ocorrer para uma cadeia de controle vazia, portanto, mesmo para a cadeia de controle vazia, o corpo precisa ser executado pelo menos uma vez. Para garantir que a subestação execute um tempo extra no início da cadeia de controle (mesmo para cadeias de controle vazias), altero a substituição para:Vou executar o
y/iI/Ii/
como a primeira coisa dentro do código de substituição. Embora$_
ainda seja a string de controle, isso ainda não conterá nenhumaIi
, portanto, se a transliteração indicar que nada foi alterado, essa é a minha inicialização do gatilho$_
:Agora eu posso implementar o movimento real das letras. Desde que eu começo com uma troca, todos os movimentos devem ser feitos
i
, nãoI
. Se$1
estiver definido, movai
para a direita:Se
$1
não estiver definido, movai
para a esquerdaObserve que no início da sequência de controle quando eu corresponder
^
$1
não será definido, portanto, ele tenta se moveri
para a esquerda na sequência inicialIi
. Isso não funcionará porque não há espaço lá; portanto, a string inicial permanece intacta (é por isso que eu dou a()
volta em>
vez de<
)Apenas um problema permanece: no final da substituição externa,
$_
é definido o resultado da substituição externa, independentemente do que você fez no$_
interior do corpo de substituição. Portanto, a cadeia de destino com o posicionamento correto dei
eI
se perde. Nos perigos mais antigos, isso seria uma falha fatal. Perls mais recentes, no entanto, têm or
modificador que significa "faça uma cópia da string original, faça sua substituição e retorne a string resultante (em vez do número de correspondências)". Quando eu uso isso aqui, o resultado é que a string de comando modificada é descartada enquanto o original$_
não é perturbado pelo perl e deixado após a substituição. No entanto, a perturbação que eu faço$_
ainda é feita depois que o perl é deixado em$_
paz. Então no final$_
será a sequência de destino adequada.A
-p
opção garante que a sequência original esteja inserida$_
e também imprime a final$_
.fonte
Ii
, nãoiI
.^
partida extra significa que eu tenho que trocá-los. Portanto, a inicialização reversa está correta.LittleLua - 178 Bytes
Implementação direta.
Ungolfed:
O que é LittleLua?
LittleLua é um trabalho em andamento para tentar nivelar os campos de jogo entre o meu idioma de escolha para esses desafios e os idiomas esotéricos que geralmente têm recursos extremamente poderosos.
LittleLua é um intérprete Lua 5.3.6 com um módulo adicional (LittleLua.Lua), bem como os nomes das funções e dos módulos diminuídos. Essas alterações serão expandidas nos próximos dias ou dois, até que eu esteja feliz, mas, como estão várias das maiores mudanças entre LittleLua e um interpretador Lua padrão, são:
Funções e módulos são reduzidos:
Variáveis incorporadas
LittleLua tem várias variáveis embutidas para reduzir algumas tarefas:
Funções incorporadas
Atualmente, uma lista deprimente pequena, mas aqui está:
fonte
$
e use isso no lugar deend
oue
-A-Za-z
caracteres não- palavras não precisam de espaços ao seu redor, certo? Isso rasparia um byte porend
/e
if
parai
, salvando um byte por uso, eend
parae
, salvando dois, mas você deixouelse
sozinho? Mesmo neste programa simples (5 seif
2else
s), você está gastando mais byteselse
do que economizaif
. (Estou assumindo que é uma melhoria planejada?)Retina ,
10186Experimente online
Economizou 15 bytes graças a daavko!
Pega entrada separada por novas linhas e saídas com os olhos separados por espaços.
Explicação:
Vou explicar estágio por estágio, como de costume. Todos esses estágios estão no modo Substituir da Retina. Isso significa que a primeira linha é uma expressão regular e a segunda linha é uma sequência de substituição.
Adicione a inicial
Ii
ao final da entrada.O backtick separa o palco das opções. O caractere de opção
(
indica que esse estágio é o início de um loop de estágios a serem executados repetidamente em ordem até que um ciclo completo seja concluído sem alterar a entrada. Como esse parêntese aberto nunca é fechado, todos os estágios restantes fazem parte desse loop.O estágio atual é muito simples, se o primeiro caractere da string for uma nova linha, exclua-a. Isso é apenas para ajudar a facilitar o manuseio da entrada vazia, caso contrário, seria mais fácil adicioná-la às duas últimas etapas.
Aqui, a opção
s
faz com que o metacaractere Regex.
corresponda às novas linhas. Esse estágio faz com que um líder>
corresponda aoI
seguido por um espaço opcional. Em seguida, substitui a correspondência com o material após o>
, seguido pelo espaço opcional (portanto, a cadeia vazia se o espaço não puder ser correspondido) e, em seguida, oI
.Este estágio é muito semelhante ao anterior, apenas o espaço opcional é anterior ao
I
, e a ordem e o olho são invertidos.O manuseio de
i
muitas vezes é mais simples, porque não precisamos nos preocupar em adicionar ou remover opcionalmente, poisi
sempre podemos mover para a direita. Nosi
casos, comparamos o sublinhado e o sinal maior / menor que, mas, de outro modo, fazemos uma lógica semelhante. Este adiciona um espaço antes doi
.Novamente semelhante ao anterior, mas ele exclui o caractere antes do
i
caractere se for um espaço, caso contrário, ele remove apenas o emoticon.fonte
s`^_>(.*)i( |$)?
=>s`^_>(.*)i
e sua substituição$1$#2$* i
=>$1 i
es`^_<(.*?)( )?i
=>s`^_<(.*?) ?i
e sua substituição$1i$2
=>$1i
.Python,
142141134122121 121 bytesEconomizou 19 bytes graças ao xnor.
Exemplo:
Explicação:
fonte
i
sempre fica maior queI
?I
, pontosi
, sem necessidade de listas e junções.GNU sed, 81 bytes
(incluindo +1 para
-r
sinalizador)Isso cria um novo programa sed a partir da entrada (que você pode ver removendo a última linha) e o aplica ao estado inicial
Ii
.Explicação
<
e>
substituem comandos que mudam paraI
esquerda e direita, respectivamente._
para trabalhar emi
vez deI
i
não estiver delimitado por nenhuma borda direita, portanto, não adicione ou consuma espaço após elaIi
.s///e
sempre usa/bin/sh
como shell, então não pude reduzi-losed '&'<<<Ii
como queria (essa é uma sintaxe de redirecionamento do Bash).Resultado dos testes
fonte
Javascript (ES6)
176 171 168 155 148 147 142141 bytesUso
Degolfado (v6, v7 não é muito diferente)
fonte
=>{ ... }
que você pode fazer é uma expressão e salvar algumas bytesMATL ,
5655504947 bytesExperimente online!
fonte
Retina,
9186 bytesProvavelmente não adotei a melhor abordagem, por isso provavelmente pode ser mais praticada. E não, eu não copiei o FryAmTheEggman (eu sei que eles são realmente semelhantes em nossas abordagens). Eu nem vi a resposta dele até depois de postar a minha.
Experimente online
fonte
( |)
final da última linha de jogo, pois nunca haverá espaço depoisi
. Além disso, novamente na última linha da partida, você não precisa de colchete para o loop. O loop não fechado é fechado automaticamente no final do arquivo na Retina.i
e algo depois disso substituir. Esqueceu de mudar isso.Javascript (ES6) 166 bytes
Usando a resposta de Charlie Wynn, consegui economizar 10 bytes definindo Math.max como M e chamando M cada vez que seu script usa
(Eu não escrevi esse golfe, Charlie Wynn fez aqui . Apenas o modifiquei para torná-lo mais curto)
fonte
SyntaxError: missing : in conditional expression
no Firefox. Você pode consertá-lo com_=>{I=0,i=1,M=Math.max;_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?M(0,I-1):M(i-1,I+1))+(i=m[1]=='<'?M(I+1,i-1):i+1));(a=Array(i).fill`.`)[I]='I';return a.join``+'i'}
o mesmo tamanho exato.JavaScript (ES6), 115
118Editar: 3 bytes salvos thx CharlieWynn
p
é o número de espaços anterioresI
;q
é o número de espaços entreI
ei
. Nem pode ser negativo.Menos golfe
Teste
fonte
Retina,
6158 bytes3 bytes salvos graças a @FryAmTheEggman.
A explicação vem um pouco mais tarde.
Experimente online!
Código modificado com teste em lote.
fonte
Python 2,
9692 bytesSolução bonita para um desafio difícil. Entrada como
f('>_> <_>')
, saída como'I i'
.Programa de verificação (supondo que
tests
seja a sequência de casos de teste com várias linhas):O programa lê cada seta uma de cada vez, começando com
I=1, i=2
e usando índices baseados em 1. Os nomes das variáveis são um pouco enganadores, pois trocam de papéis - após cada caractere,I
tornai
-i
se e torna - seI
atualizado. Um caractere é atualizado apenas se não se mover para a posição do outro caractere nem para a posição 0.Por exemplo, para o
>_> <_> >_<
que fazemos:Isso dá
' Ii'
como desejado.fonte
Lua, 104 bytes
Uso:
fonte
Javascript (ES5),
153125 bytesrecebe uma entrada definindo uma variável
a
antes de executarUm pouco não-destruído:
fonte
Mathematica, 125 bytes
Função pura com o primeiro argumento
#
. A idéia é que cada um<_
,>_
,<
, e>
nos corresponde entrada para uma regra de substituição de string."<_"|">_"|">"|"<"
é um padrão de sequência que corresponde a qualquer uma dessas quatro expressões.StringCases[#,"<_"|">_"|">"|"<"]
encontrará todas essas correspondências. Em seguida, substituímos (/.
) cada um"<_"
pela regra de substituição de cadeia".I"->"I."
, cada um">_"
pela regra"I."->".I"
e assim por diante. Desejo aplicar sequencialmente cada regra de substituição à sequência"Ii"
, masStringReplace
procurarei apenas correspondências nas partes da sequência que não foram substituídas. Portanto, deixamosFold
a funçãoStringReplace
sobre a lista de regras de substituição com valor inicial"Ii"
.Talvez seja mais claro com um exemplo (aqui
%
se refere à saída da célula anterior):fonte