Dada uma mesa, coloque nas cadeiras


41

Desafio

Você receberá uma tabela como entrada, desenhada com ASCII |e _. Sua tarefa é colocar as cadeiras em torno dele.

Exemplo

Entrada:

 ____
|    |
|    |
|    |
|    |
|____|

Saída:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

Essas cadeiras são feitas de <>e v^.

Outro exemplo:

A linha deve ter o máximo de cadeiras possível.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

Deve haver espaços entre todas as cadeiras. E >_^_^_<é inválido, deveria ser |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

Nenhuma cadeira pode estar dentro de uma "rosquinha".

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^e vpriorizar <e >. Nenhuma cadeira por si só (precisa ter pelo menos uma |ou _na fila).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

Isso é código de golfe, então o código mais curto vence.


2
Estou confuso, por que as cadeiras estão embutidas na mesa pelos lados?
Optimizer

Se bem me lembro, sua postagem original da caixa de areia tinha um espaço entre a linha vertical da mesa e a linha da cadeira. Assim como há pouco espaço entre as linhas horizontais da mesa e as cadeiras.
Optimizer

11
parece que as cadeiras são colocadas a uma distância uma da outra, mas a entrada de qualquer entrada não é dividida por 2. como o programa deve começar a colocar cadeiras. no sentido horário ou anti-horário? do canto superior direito, canto superior esquerdo etc?

11
Também acho que há um problema na terceira amostra - há um espaço extra entre segundo e terceiro "top" cadeiras - e também no último exemplo, inferior direito canto

11
O primeiro caso de teste parece estar quebrado. A entrada tem apenas 4 de largura e a saída é 5. #
Wheat Wizard

Respostas:


34

Python 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 bytes

6 bytes salvos graças a Riley

6 bytes salvos graças a Adnan

Como essa pergunta tem mais de um ano e ainda não tem respostas, pensei em tentar.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

Experimente online!

O programa lê na tabela um arquivo nomeado Ie imprime a tabela com suas cadeiras std::out. Eu não tinha certeza de muitos dos casos extremos, por isso tomei meu melhor julgamento (o que foi menos trabalhoso), mas parece passar em todos os casos de teste. Algumas das saídas não correspondem exatamente, mas todas têm o mesmo número de cadeiras.

Explicação

A primeira linha simplesmente configura algumas definições que nos economizarão bytes no futuro:

(Vou descompactar essas macros para facilitar a leitura em linhas futuras)

n,i,o="\nI ";R=lambda x:range(1,x-1)

Em seguida, abriremos um arquivo nomeado Iporque já temos uma variável que é curta para isso, e salva alguns bytes.

b=open("I").read().split("\n")

Dividimos ao longo de novas linhas para criar uma lista de strings (As linhas da imagem)

s=b.split(n)

Em seguida, encontro o comprimento da linha mais longa para poder preencher todas as linhas nesse comprimento. (Também adiciono 3 porque precisamos de um pouco de preenchimento adicional)

 z=max(map(len,s))+3

Em seguida, executamos o preenchimento real e criamos uma borda de Icaracteres ao redor da borda. Isso ocorre porque precisaremos distinguir a diferença entre o interior e o exterior da forma mais tarde. Também mudaremos o tipo de dados de uma lista de strings para uma lista de caracteres (comprimento 1).

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

A próxima linha é apenas outra definição de economia de bytes.

(Eu também vou descompactar este)

B=R(len(a))

Agora, queremos espalhar Icaracteres para todos os lugares fora da forma. Podemos fazer isso com um autômato pseudo-celular. Cada um Ise espalhará para qualquer caractere adjacente . Poderíamos fazer loop até que o autômato se estabilize, no entanto, isso não pode levar mais iterações do que os caracteres b.

for _ in b:

Para cada iteração, queremos passar sobre cada caractere da lista 2D (excluindo o preenchimento mais externo)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

Para cada posição, executamos o seguinte código:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

Vamos quebrar isso.

Temos um if com duas condições separadas por um &(bit a bit and)

A primeira simplesmente verifica se existe uma Iem qualquer uma das células adjacentes e a segunda apenas verifica se a célula atual é a " ". Se passarmos por essas condições, definimos a célula atual como um I.


Agora que determinamos o exterior e o interior da forma, podemos começar a colocar as cadeiras ao redor da mesa.

Mais uma vez, percorremos todas as células (e definimos mais algumas abreviações)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

Agora, aqui está a minha parte favorita. Se você se intrometeu no meu golfe chato, principalmente baseado em definições, até agora, vou recompensá-lo com um bom petisco de golfe inteligente (se é o que digo).

Um pouco de fundo em python:

No Python, se você tentar atribuir uma chave de dicionário duas vezes, ela atribui a última. Por exemplo

>>> {1:"a",1:"b"}[1]
'b'

Abusaremos essa propriedade para atribuir a célula atual a um caractere específico.

A primeira condição é

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

Se a célula estiver no meio de uma aresta de 3 _caracteres, reatribuiremos a célula atual e a célula abaixo dela. Nós o atribuiremos ao resultado da indexação de um dicionário sobrecarregado por I. Primeiro, definimos nosso padrão com o par. "I":"_"+a[x+1][y]Isso significa que, se não houver alteração, atribuiremos as duas células aos seus valores originais. Em seguida, adicionamos o par a[x-1][y]:"^ ". Isso não fará nada (importante), a menos que a célula acima da atual ( a[x-1][y]) seja preenchida com um I. Se houver um I, ele substituirá o padrão, dizendo para colocar uma cadeira na célula atual. Em seguida, passamos para a célula abaixo da célula atual, se essa célula for Inovamente substituída para colocar uma cadeira voltada para cima abaixo do local atual.

A próxima condição é um pouco mais simples

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

Verificamos se a célula atual e a célula acima são ambas |. Nesse caso, criamos um dicionário.

O primeiro par no dicionário "I":"|"define o padrão. Como vamos acessar a chave, Ise Inão for reatribuída, ela retornará ao padrão |(o caractere que já é) e não fará nada.

Nós adicionamos as duas teclas A[y+1]:">",A[y-1]:"<"Se qualquer uma das duas células à esquerda e à direita estiver I, ela reatribuirá a célula atual a uma cadeira apontando na direção do lado de fora.


Agora nós apenas temos que produzir. No entanto, não podemos apenas imprimir, há algumas coisas de limpeza que precisamos fazer primeiro. Temos que converter novamente em uma string e remover todos os Is que criamos. Isso é feito em uma linha.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")

Você não pode usar um espaço para o primeiro nível de recuo, tab para dois, tab e espaço para três? Isso economizará alguns bytes.
Riley #

3
Esta pode ser a resposta mais recolocada.
Magic Octopus Urn

2
Será que em i,o="I "vez de i="I";o=" "trabalhar?
Adnan

11
@ErikGolfer Fazer ncustos 4 bytes e me poupar 6. Embora eu não o use frequentemente, ele economiza 2 bytes.
Wheat Wizard

11
@ Pietu1998 Obrigado por apontar isso. Corrigi o problema
Assistente de trigo
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.