Quebrar guias ao meio


31

As guerras sagradas foram travadas por espaços versus abas. (E, claro, os espaços, sendo objetivamente superiores, venceram.) - Alex A.

S OMe PEO p le ainda se recusam a uma ccept que WHI c h é Cl e arly s upreme. Você acaba de receber um arquivo usando o InCor re ct, b ad, e inf e forma rior do whi t espace, e agora t ele cont e nts do arquivo a r e contaminado e arruinado.

Você decide que também pode mostrar à pessoa que lhe enviou o arquivo o quão errado eles estão - violentamente.

Descrição

Como o título sugere, seu desafio é pegar um arquivo que contenha uma ou mais guias:

this is an evil tab    onoes

e os despedaça sem piedade.

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Observe que o software Stack Exchange transforma abas literais em quatro espaços (porque é correto); portanto, as abas nesta postagem serão exibidas como quatro espaços. A entrada para o seu programa, no entanto, conterá guias reais.

Desafio

A solução deve ter uma única string como entrada, que pode conter ASCII, novas linhas e guias imprimíveis. Sempre haverá pelo menos uma única guia na entrada.

A saída deve ser a mesma sequência, com as seguintes regras aplicadas:

  • Inicie o cursor nas coordenadas (0,0) e com uma direção à direita. As coordenadas são (coluna, linha), indexadas a zero e a direção é para que lado você deve mover o cursor após imprimir um caractere.

  • Para cada caractere na sequência:

    • Se for uma nova linha, vá para as coordenadas (0, n), onde n é o número de novas linhas na sequência até agora (incluindo esta) e redefina a direção para a direita.

    • Se for uma guia, produza dois espaços, gire a direção do cursor 90 graus no sentido horário e produza mais dois espaços, efetivamente "quebrando" a guia ao meio. Aqui está um exemplo visual, onde uma guia é representada como --->e espaços como ·:

      foo--->bar--->baz
      

      torna-se

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • Caso contrário, basta imprimir o caractere no cursor e mover o cursor um passo na direção atual.

Como você está lendo a string do começo ao fim, é possível que você tenha que escrever "em cima" dos caracteres existentes - tudo bem. Por exemplo, a entrada

foo--->bar


spaces are superior

deve resultar em uma saída de

foo

     b
spaces are superior
     r

Você pode escolher se "abas quebradas" devem substituir outros caracteres - a intenção original era que não, mas a especificação era ambígua, portanto, essa é sua decisão.

Além disso, depois de aplicar essas regras, você também pode

  • adicione ou remova quantos espaços finais você desejar.

  • adicione no máximo uma única nova linha à direita.

A entrada nunca conterá espaços à direita; também nunca conterá novas linhas iniciais ou finais. Você também pode sempre assumir que nunca precisará gravar em uma coluna ou linha menor que 0 (ou seja, fora da tela).

Caso de teste

As guias neste caso de teste são representadas como --->porque, caso contrário, o SE as devora.

Entrada:

Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah

Saída:

Test case. Here's a tab
blah
blah                     t
blah blah blah blah blah blah
                        blaablah
                         r     b
                         e     l  b
                      h  'h    a  l
                      a  sa    a  a
                      l   l    h  h
       this is some mobe tbxt

                         haalhalb
     b                   a
     a                   b
     t

        bat a erehwyreve

Animação chique:

Regras

  • Isso é , então o código mais curto em bytes vencerá!

Quando você diz que o cursor precisa começar, (0,0)você quer dizer que precisamos limpar o console primeiro ou você apenas quer dizer a posição padrão do cursor?
Martin Ender

18
Estou votando para encerrar esta questão como fora de tópico, porque está cheia de ódio e blasfêmia.
aditsu 21/09/2015

1
Sua animação se parece tanto com o intérprete> <> que agora quero ver uma entrada> <> auto-modificável.
Sanchises

1
Gostei da mensagem oculta no parágrafo inicial, mas tenho que discordar.
wf4 21/09/2015

@ MartinBüttner Isso significa apenas a posição padrão.
Maçaneta

Respostas:


8

MATLAB, 144 bytes

A arma de escolha para lidar com strings é, obviamente, uma linguagem projetada para manipular números [citação necessário]. Brincadeiras à parte, o melhor do Matlab é que não importa se você atribui a uma matriz 'fora dos limites': ela simplesmente cria uma matriz maior. Além disso, o elemento da matriz padrão,, 0é renderizado como um espaço em vez de um nullcaractere prescrito pela especificação ASCII.

As guias são simplesmente um salto nas coordenadas, portanto, nenhum espaço é gerado para uma guia.

function o=q(t)
u=2;v=0;x=1;y=1;n=1;for s=t
if s==9 x=x+u-v;y=y+v+u;a=v;v=u;u=-a;elseif s<11
n=n+1;x=1;y=n;else
o(y,x)=s;x=x+u/2;y=y+v/2;end
end

Comecei com 209 bytes, mas um pouco de golfe mais cuidadoso se livrou da maior parte disso; há muita repetição nesse código, então fiz algumas tentativas e erros de quais alternativas funcionavam melhor. Eu não acho que haja muito espaço para mais otimização com esse código, mas estou sempre feliz por provar que estou errado. Edit: Tom Carpenter conseguiu provar que eu estava errado; ele conseguiu salvar 9 bytes, que eu otimizei para salvar 29 bytes. Último byte salvo, assumindo que não há caracteres de controle (ASCII <9) na entrada - as strings do MATLAB não são nullterminadas.


Não parece funcionar. Eu tentei isso q('hello<tab>my name<tab>is tom<tab>c'), mas algo ao longo das linhas de Attempted to access o(11,-2); on line 7. Embora isso possa ter mais a ver com um problema na pergunta - se o cursor estiver voltando para trás e for além da primeira coluna, o que acontece com o restante da linha.
21815 Tom Carpenter

Sim, meu mal, eu perdi esse pedaço. Eu vou embora agora;)
Tom Carpenter

1
Você pode salvar outros 9 caracteres removendo a dvariável e, em vez disso, possui 4 variáveis ​​que, para um loop, formam o padrão [1 0 -1 0] como tal: function o=q(t) u=1;v=0;w=-1;z=0;x=0;y=1;n=1;for s=t if s==9 x=x+2*u-2*v;y=y+2*v+2*u;a=z;z=w;w=v;v=u;u=a;elseif s==10 n=n+1;x=0;y=n;else x=x+u;y=y+v;o(y,x)=s;end end (obviamente, nos comentários, removeu todas as linhas, para que você tenha reformatá-lo como a sua para ver o que eu fiz)
Tom Carpenter

@ TomCarpenter Isso é ... realmente feio. Eu amo isso.
Sanchises 22/09/2015

5

Python 3, 272 270 266 262 255 253 244 bytes

I=[]
try:
 while 1:I+=[input()]
except:r=m=0
M=sum(map(len,I))
O=[M*[' ']for _ in[0]*M]
for l in I:
 x=b=0;y=r;a=1;r+=1
 for c in l:
  if'\t'==c:a,b=-b,a;x+=a+2*b;y+=b-2*a
  else:O[y][x]=c
  x+=a;y+=b;m=max(m,y)
for l in O[:m+1]:print(*l,sep='')

O \tdeve ser um caractere real guia.

O código funciona um pouco como a resposta de Zach Gates, primeiro gerando uma grade Mpor Monde Mé a soma dos comprimentos das linhas. (Isso é uma quantidade enorme de excesso, mas torna o código mais curto.) Em seguida, percorre os caracteres, colocando-os nos pontos corretos, mantendo o controle da linha mais visitada. Por fim, imprime todas as linhas até essa linha.

A saída contém (geralmente uma quantidade enorme de) espaços à direita e 1 nova linha à direita.


3

Javascript (ES6), 264245 bytes

Tentei a abordagem "criar uma grade gigante de espaços, preencher e aparar", que acabou 19 bytes mais curta que a outra.

a=t=>(o=`${' '.repeat(l=t.length)}
`.repeat(l).split`
`.map(q=>q.split``),d=x=y=z=0,s=c=>o[d>2?y--:d==1?y++:y][d?d==2?x--:x:x++]=c,[...t].map(c=>c=='\t'?(s` `,s` `,++d,d%=4,s` `,s` `):c==`
`?(x=d=0,y=++z):s(c)),o.map(p=>p.join``).join`
`.trim())

Modificando a penúltima linha dessa maneira, você pode remover a grande quantidade de espaços à direita em cada linha:

...o.map(p=>p.join``.trimRight())...

Experimente aqui:

Explicação em breve; sugestões bem-vindas!


3

JavaScript (ES6), 180 183

Usando cadeias de modelo, existem algumas linhas novas que são significativas e contadas.

Essa é uma função que retorna a saída solicitada (preenchida com toneladas de espaços à direita)

Há pouco a explicar: as linhas são construídas conforme necessário. Não há uma variável de direção, apenas o deslocamento 2 para x e y, pois na rotação no sentido horário eles são facilmente gerenciados:dx <= -dy, dy <= dx

Teste a execução do snippet abaixo no Firefox

f=s=>[...s].map(c=>c<`
`?(x+=2*(d-e),y+=2*(e+d),[d,e]=[-e,d]):c<' '?(y=++r,e=x=0,d=1):(t=[...(o[y]||'')+' '.repeat(x)],t[x]=c,o[y]=t.join``,x+=d,y+=e),o=[r=x=y=e=0],d=1)&&o.join`
`

// TEST  

// Avoid evil tabs even in this source 
O.innerHTML = f(`Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah`
 .replace(/--->/g,'\t'))
<pre id=O></pre>


Desejo a todos os idiomas teve [x, y] = [expr1, expr2] ...
Sanchises

1

Python 2, 370 369 368 bytes

Obrigado a @sanchises e @ edc65 por me salvar um byte cada.

J=''.join
u=raw_input().replace('\t','  \t  ')
w=u[:]
G=range(len(u))
d,r=0,[[' 'for _ in G]for _ in G]
u=u.split('\n')
for t in G:
 x,y=0,0+t
 for c in u[t]:
  if c=='\t':d=(d+1)%4
  if c!='\t':
   if c.strip():r[y][x]=c
   if d<1:x+=1
   if d==1:y+=1
   if d==2:x-=1
   if d>2:y-=1
r=r[:max(i for i,n in enumerate(r)if J(n).strip())+1]
for i in r:print J(i).rstrip()

Ele gera a maior grade possível e circula, caractere por caractere, alternando a direção em cada guia.


Dica: if !deif d>2
Sanchises

!dnão é uma sintaxe válida. @sanchises Obrigado pela d>2dica, no entanto.
Zach Gates

Desculpe, na verdade eu não conheço python :) Apenas pensei que funcionaria assim.
Sanchises 21/09/2015

Eu também não entendo python, mas se d em 0 ... 3, d==0->d<1
edc65

Sim, você está certo. Obrigado pelo byte. @ edc65
Zach Gates
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.