Como programador, você provavelmente já ouviu falar de barras e barras invertidas. Mas você já ouviu falar de desvantagens? É quando você pega um monte de barras, conecta suas extremidades e as desenha descendo.
Para o desafio de hoje, você deve escrever um programa ou função que use uma string que consiste puramente de barras e produza todas as barras desenhadas para baixo em uma linha que os conecta. Isso ficará muito mais claro se você vir um exemplo. Dada a string \\\//\/\\
, você deve gerar:
\
\
\
/
/
\
/
\
\
Aqui estão alguns esclarecimentos:
Deve haver uma barra por linha.
A primeira linha terá 0 espaços à esquerda.
Para cada par de barras:
Se forem diferentes, serão desenhados na mesma coluna. Por exemplo,
\/
dará:\ /
Se eles tiverem o mesmo caractere, o inferior estará na direção apontada , que está se movendo para a direita para uma barra invertida e para a esquerda para uma barra invertida. Então
\\//
vai dar\ \ / /
Cada linha pode ter espaços em branco extras, contanto que isso não altere a aparência visual da saída. Até uma nova linha à direita e à frente também é aceitável. Espaços extras não são permitidos !
Para simplificar, você pode assumir que a string nunca conterá muitas barras. Em outras palavras, nenhum prefixo da entrada conterá mais barras do que barras invertidas; portanto, uma entrada como \\////
ou //
nunca será fornecida. Isso também significa que cada entrada começará com uma barra invertida.
Se sua entrada for tomada como uma string literal, você poderá escapar das barras invertidas, se isso for necessário. Você também nunca precisará manipular uma entrada que esteja vazia ou contenha caracteres que não sejam uma barra.
Você pode imprimir em qualquer formato razoável .
Como de costume, esse é um desafio do código-golfe , portanto, tente tornar a solução mais curta possível, mesmo se você escolher um idioma em que isso seja bastante difícil. Pontos de bônus por explicar qualquer técnica interessante usada para remover bytes!
Exemplos
#Input
\\\\\\\\\\\
#Output
\
\
\
\
\
\
\
\
\
\
\
#Input
\\\//\\/\//\\///
#Output
\
\
\
/
/
\
\
/
\
/
/
\
\
/
/
/
#Input
\/\/\/
#Output
\
/
\
/
\
/
Respostas:
GNU Sed, 20
Observe que
^L
e^H
são caracteres literais de avanço de formulário e backspace (0x12 e 0x8).Essa resposta funciona movendo o cursor usando caracteres de retrocesso e avanço de formulário. As barras / barras invertidas não são preenchidas à esquerda com espaços - Não tenho certeza disso desqualifica esta resposta. Isso não funciona no TIO, mas parece bom em terminais comuns como
xterm
egnome-terminal
.Recrie esse script sed da seguinte maneira:
Execute-o da seguinte maneira:
Explicação:
fonte
Carvão ,
131211 bytesExperimente online! Link é a versão detalhada do código. Suporta
//
s extras . Explicação:fonte
↓¶
= "Mover para a esquerda" na descrição não está certo.\n/
down"print \n/ down
porque achava mais útil descrever o efeito do código do que sua tradução literal.MyCode - Do the spec
). Entendo agora, embora o efeito seja mover para a esquerda; pode valer a pena dizer "Mover para a esquerda (imprimindo uma nova linha com uma direção de impressão para baixo)".Python 2 ,
5554515753 bytes-3 bytes (e uma correção de bug) graças a Felipe Nardi Batista
Experimente online!
fonte
/// , 119 bytes
/// não possui comandos de entrada, portanto, a entrada deve ser incorporada no programa. Para este, a sequência de entrada é simplesmente anexada, sem necessidade de escape.
-d
opção (estado do programa mostrado entre colchetes antes de cada comando ser executado).Como funciona
\\/\//
será anexada ao programa para demonstração.
é usado para representar novas linhas no código embutido.Abreviações
O início
/=/\/\///M/|%%=N/%|||=C/BA=
do programa contém substituições de abreviações de golfe.=
expande para//
,M
para|%%
,N
para%|||
eC
paraBA
.Depois disso, o programa atual se torna
Recodificação de entrada
O próximo estágio transforma a sequência de entrada anexada em um formato mais utilizável. Como ele consiste inteiramente nos dois caracteres de comando de ///, isso toma alguns cuidados para evitar confundir o programa base.
/\/\\/\/BA\\/
, substitui a string/\
por/BA\
./\
no momento, portanto, essa substituição não o afeta.\
s seguidas por sequências de/
s, que, juntamente com oABA
no final do programa base, possibilitam a iteração através das seguintes substituições.ABA
prefixo antes dele, a sequência de entrada de exemplo agora se tornaABA\\/BA\//
./BA\\/BAbBA/
, substituiBA\
porBAbBA
.\
s da sequência de entrada, que com o prefixo agora se tornaABAbBAbBA/BAbBA//
/B\A\//BAfBA/
mudaBA/
paraBAfBA
, iterando através dos/
s.\
nessa substituição é necessário, pois, caso contrário, seria mutilado pela anterior.ABAbBAbBAfBABAbBAfBAfBA
./AB//
remove algumas partes supérfluas da codificação, transformando-as emAbBAbBAfBAbBAfBAfBA
.AB
da/|/AB\\/
substituição posteriormente no programa, necessário para protegê-lo da/\
manipulação acima .\
as strings de entrada originais se tornaramAbB
e todas/
se tornaramAfB
. (b
ef
fique para trás e para frente.) Há um desvioA
no final.A
s eB
s com fragmentos de programa para executar na fase final. Nas cadeias de substituição,%
s e|
s codificam o que se tornará/
s e\
s, respectivamente. Isso tem dois benefícios:/
e\
, os%
s e|
s não precisa escapar a ser copiado./\
, que de outra forma teria sido destruída pelas manipulações anteriores./|/\\/
(anteriormente/|/AB\\/
) agora decodifica os|
s, após o que o seguinte/%/|//
se tornou/%/\//
e decodifica os%
s.Estrutura do programa na fase final
Nesse ponto, o programa base executou todas as suas substituições e tudo o que resta é a codificação do programa da sequência de entrada.
Cada caractere de entrada se tornou um subprograma
(nova linha à direita), onde
*
representaf
um original/
oub
um original\
./\//xy
no final do programa, que não terá efeito, exceto para fornecer um necessário/
para as substituições do subprograma anterior.Subcadeia compartilhada
Antes do início da iteração final através dos subprogramas, há uma substring cruzando o limite após o subprograma de cada caractere do formulário
\//
./
, que ancora as substituições) seja executada para imprimir a linha correspondente. personagem./
, que é a "linha anterior" imaginária correta para fazer com que o primeiro caractere de entrada seja impresso no início de sua linha.\\
ou\/
uma nova linha e uma sequência/
.Executando um Subprograma de Caracteres
Várias das seguintes substituições contêm
\
s extras para evitar que elas sejam correspondidas e mutiladas (incluindo outras cópias em outros subprogramas). Alcançar esta é também a razão pela qual ambosx
ey
são necessários./\//xyf\z/
ou/\//xyb\z/
, faz/
com que o final da subseqüência compartilhada se tornexyfz
ouxybz
, imediatamente após o\/
ou\\
./\\\\x\y/ /
substitui\\xy
por um espaço, e a substituição/\\\/x\y//
substitui\/xy
por nada.\
ou/
, respectivamente.\
próximo, seguido porfz
oubz
./ \fz/\\\/\//
substitui fz
por\//
e/b\z/\\\\\//
substituibz
por\\/
./
ou\
, respectivamente./
corretamente.///
, que é um loop infinito./
no final da substring compartilhada.Após a execução do último subprograma de caracteres, o que resta do programa é
/\//xy
. Como esta é uma substituição incompleta com final ausente/
, o programa a ignora e para normalmente.fonte
Gelatina , 14 bytes
Um programa completo imprimindo o resultado.
Experimente online!
Quão?
fonte
Haskell , 49 bytes
Experimente online!
fonte
Perl 5 , 44 bytes
42 bytes de código + 2 para
-F
sinalizadorExperimente online!
fonte
JavaScript (ES8),
665963 bytes7 bytes salvos graças a Justin Mariner
+4 bytes para corrigir
/\\/\\/
(notado por Neil )Experimente online!
fonte
MATL ,
231918 bytes1 byte de desconto graças a @Sanchises
Entrada é uma cadeia de caracteres entre aspas simples.
Experimente online! Ou verifique os casos de teste: 1 , 2 , 3 .
Explicação
Considere a entrada
'\\\//\/\\'
como um exemplo.fonte
C # (.NET Core) ,
748882787776 + 18 bytes-1 byte graças a Kevin Cruijssen
Produz uma coleção de strings, uma para cada linha. A contagem de bytes também inclui:
Experimente online!
Explicação para resposta de 77 bytes:
fonte
/\\/\\/
.s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1
para #(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
05AB1E , 14 bytes
Experimente online!
Explicação
fonte
/\\/\\/
.Ç¥.¥0<.SηOv¹Nèy<ú,
soluçando em binárioR ,
122121 bytes-1 byte graças a Giuseppe
Experimente online!
Com espaço em branco extra:
Explicação: Esta resposta é baseada na observação de que o número de espaços à esquerda altera cada linha por -1, mais o número de
/
linhas anteriores e atuais.Se tivermos barras N, a variável
y
é um vetor de comprimento N, com 1 para cada posição com\
, 0 caso contrário. Portanto, para obter a alteração no número de espaços à esquerda por linha, calculamosy[1:(N-1)] + y[2:N] - 1
. A funçãodiffinv
converte essas diferenças em uma sequência, começando com 0. O restante é apenas uma questão de montar cada linha como o número necessário de espaços à direita, seguidos pela barra relevante e uma nova linha.fonte
diffinv
;) Também é possível definiry=x>")"
-1 bytestrsplit
, o que é sempre um assassino. Você também pode fazer uso dos famososdiffinv
!library(methods)
no cabeçalho (o que deve ser bom sem penalidade, já que esse pacote faz parte da base R), você pode usarel
. Além disso,diffinv
acabou por ser apenas enquantocumsum
! :)*S
estraga tudo.Brain-Flak , 175 bytes (174 caracteres + 1 sinalizador)
Corra com a
-c
bandeira.Experimente online!
Explicação
fonte
Ruby ,
8076 bytes-4 bytes graças ao manatwork
Experimente online!
Explicação:
fonte
.each_cons(2){…}
. Na alteração, você pode salvar substituindo.each_char
→.chars
.i+=
para o início da expressão ternária aninhada e finalizando-a com-1:1:0
.Java 8,
121118110109102 bytes-7 bytes graças à mágica bit a bit do @Nevay . :)
Explicação:
Experimente aqui.
fonte
a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
>>
/>>>
/<<
... eu só tinha verificado algumas coisas com&
/|
/~
/^
..>.>C (GCC),
13713497 bytesExperimente online!
• 3 bytes graças ao ATaco
• 37 bytes graças ao Digital Trauma e ThePirateBay
Nada muito sofisticado, apenas uma função recursiva simples que pega uma string e imprime as barras, observe que a entrada precisa escapar primeiro das barras invertidas.
Uso
Ungolfed
Esta é a resposta antiga, consulte o link Experimente online para atualizar uma!
Resultado
fonte
c=='\0'
por!c
para o mesmo efeito.printf("%*s%c", n, "", c)
para imprimir o caractere c com n espaços à esquerda?(c!=n)
comc-n
e reorganizando expressões ternários. O mesmo com(c=='/')
. Além disso, você pode substituir'/'
pelo número literal47
. Eu acho que são 7 bytes no total.C, 60 bytes
Experimente online!
fonte
Retina , 47 bytes
Experimente online! O link inclui casos de teste. Explicação:
Adicione um espaço no início de cada linha e antes de cada
\
.Considere os dois primeiros caracteres da sequência. Se o primeiro é a
/
, o recuo precisa ser diminuído; isso é conseguido incluindo o espaço anterior na captura (que sempre existe porque o primeiro estágio foi adicionado); se o segundo for um\\
, ele precisará ser incrementado; isso é alcançado incluindo o espaço que o primeiro estágio adicionou na captura. Tendo dado ao segundo caractere o travessão correto, o estágio é repetido para o segundo e terceiro caracteres etc.Retire o recuo extra.
Eu escrevi uma versão de 94 bytes que (como minha resposta do carvão vegetal) permite qualquer combinação de barras: Experimente on-line! Explicação:
Faça a bola rolar pegando a última barra e recuando-a para a mesma posição em sua própria linha.
Prefixe espaços para todas as barras para que elas possam ser capturadas.
Pegue repetidamente a última barra da entrada e alinhe-a em sua própria linha com a barra na linha abaixo.
Exclua qualquer recuo restante.
Exclua a entrada agora vazia.
fonte
Lua , 96 bytes
Experimente online!
O mais curto que eu poderia encontrar em Lua. A entrada é retirada da linha de comando.
Isso usa alguns truques:
(...):gmatch(
Essa deve ser a forma mais curta de obter uma única string em um programa Lua a partir da linha de comando. A
...
expressão em Lua captura qualquer parâmetro em excesso para uma função que não está especificada na declaração da função e é usada para varargs. Como o corpo principal de um programa Lua é chamado como uma função com os argumentos da linha de comando como seus parâmetros, os argumentos da linha de comando terminam em...
.Os parênteses em torno dele transformam a
...
expressão potencialmente com vários valores em uma expressão de valor único. Considere este exemplo (um tanto surpreendente):and
/or
para a lógica "if x, value1 else value2".O
and
operador de Lua retorna seu primeiro argumento se for falso; caso contrário, ele retornará seu segundo argumento. Oor
operador retorna seu primeiro argumento, se for verdade; caso contrário, o segundo argumento.p
não precisa de nenhuma inicialização.p==s
sempre precisa ser falso na primeira execução do loop, independentemente da entrada. Não definirp
nenhum valor antes de inserir o loop (deixando-onil
) fará com que isso aconteça e salve bytes também.Alguém pode jogar isso (em Lua)?
fonte
c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
gmatch(".")
paragmatch"."
como você fez na sua próxima resposta.Pitão , 28 bytes
Experimente online!
fonte
Q
em vez disso:j.u+?qeNY?>Y\/+PNdPPNPNYtQh
.R , 119 bytes
Experimente online!
Isso difere um pouco da resposta do usuário2390246 . Cada um itera sobre a string, imprimindo um certo número de caracteres de espaço e, em seguida, o
/\
caractere apropriado .No entanto, evitei dividir a sequência, optando por substituir os caracteres pelo valor de codificação UTF-8, o que me permite fazer aritmética nos números diretamente, o que me salvou em apenas alguns bytes.
fonte
diffinv
definitivamente não vai funcionar aqui.C # (.NET Core) , 60/65 bytes
Eu tentei a versão C # mais curta
como foi afirmado: "Isso também significa que todas as entradas começarão com uma barra invertida". Ou um pouco mais, o que resolve o início "/"
Experimente online!
fonte
Lua ,
8884 bytesVersão aprimorada (-4 bytes graças ao QuertyKeyboard)
Experimente online!
Versão original (88 bytes)
Outra tentativa em Lua, desta vez com uma abordagem completamente diferente usando manipulação de string em vez de uma variável de contador.
Ungolfed:
Há uma coisa interessante no código:
(...):gmatch"."
isso usa algumas peculiaridades no analisador Lua. Quando Lua encontra um pedaço de código no formulário
func "string"
, ele o converte emfunc("string")
. Isto é para que se possa escreverprint "string"
para imprimir uma string constante e ela só funcione com uma única string literal após a função. Qualquer outra coisa dará um erro de sintaxe. No entanto, esse açúcar sintático também funciona com chamadas de função no meio de uma expressão e, mais surpreendente, funciona muito bem junto com o:
método chamado açúcar sintático. Então, no final, Lua interpretará o código assim:Se alguém puder pensar em uma maneira de remover uma das três chamadas gsub, informe-me.fonte
s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
Pitão - 33 bytes
Primeira tentativa, vai jogar golfe.
Experimente online aqui .
fonte
Perl, 40 + 2 bytes
Você precisa da
-F
bandeira.fonte
Perl,
3438 + 1 bytespara lidar com os dois casos
para ser executado com
-p
opçãoEDIT: o seguinte comentário não funciona quando o primeiro caractere é
/
no entanto, a saída será deslocada para um caractere à direita se o primeiro caractere for
\
fonte
/\\/\\/
.34
solução original agora é perfeitamente válidaVBA (Excel), 181 bytes
fonte
[...]
notação: Eu tenho-o para 128 BytesSub q
For x=1To[Len(A1)]
c=Mid([A1],x,1)
If c="\"Then Debug.?b;c:b=b+" "
If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c
Next
End Sub
Pitão ,
2421 bytesPorto da resposta de Rod .
Experimente online!
fonte
\
. BTW, onde está o seu código?SOGL V0.12 ,
1613 bytesExperimente aqui! - espera entrada na pilha, portanto, para maior facilidade de uso,
,
é adicionadofonte
Dyalog APL, 31 bytes
Experimente aqui!
fonte
{↑⍵↑¨⍨a-1-+\¯1*a←⍵='\'}