Implode a caixa

17

As caixas ASCII ficam assim:

++    +---+    +------+    +---+    +---+
++    |   |    |      |    |   |    |   |
      |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    +---+
      +---+    |      |    |   |
+--+           |      |    |   |    ++
|  |           |      |    |   |    ||
|  |           +------+    |   |    ||
+--+                       |   |    ||
                           +---+    ||
                                    ||
                  +-----+           ||
+------------+    |     |           ++
|            |    |     |
|            |    |     |
+------------+    +-----+

Aqui estão alguns exemplos das mesmas caixas ASCII, implodidas:

++    +- -+    +-    -+    +- -+    +- -+
++    | - |    | -  - |    | - |    | - |
       | |      | -- |      | |      | |
+-+    | |       |  |        "      | - |
+-+   | - |       ||        | |     +- -+
      +- -+      |  |      |   |
+--+            | -- |      | |     ++
|  |           | -  - |      "      ||
|  |           +-    -+     | |     ||
+--+                       | - |   |  |
                           +- -+   |  |
      --                            ||
     -  -         +-   -+           ||
+-  -    -  -+    | - - |           ++
| --      -- |     | = |
| --      -- |    | - - |
+-  -    -  -+    +-   -+
     -  -
      --

Aqui está um link para todas essas caixas de casos de teste em um formato mais fácil de copiar. A ordem é todas as entradas seguidas por todas as saídas na mesma ordem.

Seu objetivo é pegar uma caixa ASCII como entrada e retornar a caixa implodida. As regras de implosão são:

  1. "+" nunca muda; nem "-" ou "|" diretamente adjacente a "+"
  2. A partir dos cantos, os "-" e "|" mova-se para dentro em um espaço a mais do que o mesmo caractere mais perto da esquina. Se um "-" e "|" jamais se moveria para o mesmo local, nem se move.
  3. Se um "-" e "-" forem movidos para o mesmo local, coloque um "=" nesse local. Se um "|" e "|" mova para o mesmo local, coloque um "nesse local. Eles contam como dois de seus respectivos personagens no mesmo local, movendo-se em direções opostas.
  4. Dois "-" ou dois "|" podem passar um do outro, como pode ser visto no exemplo inferior esquerdo.
  5. Se a caixa for fina o suficiente, ela começará a se expandir para fora da mesma maneira, sempre se afastando do lado em que começou parte.
  6. O resultado deve ser simétrico na linha central nas direções x e y (ignorando novas linhas); isso inclui espaços; portanto, o resultado pode precisar ser preenchido com espaços para satisfazer isso.

Detalhes da regra:

  1. Isso é código-golfe, e o programa mais curto em bytes vence.
  2. Aplicam-se brechas padrão.
  3. Você pode assumir que cada linha termina em um caractere de nova linha.
  4. Os únicos caracteres na sequência de entrada serão "+", "-", "|", "" e "\ n" (nova linha), e a sequência de saída deverá seguir as mesmas regras, com a adição de "=" e "como possíveis caracteres.
  5. Opcionalmente, você pode ter uma nova linha final à direita no final da última linha.
  6. A menor caixa ASCII que você precisa manipular é o exemplo superior esquerdo. Cada caixa ASCII terá exatamente 4 "+" s, exatamente nos cantos.
  7. Você precisará manipular caixas de tamanho m x npara números inteiros, m,ntais como 2<=m,n<256(o maior tamanho possível de string 255*(255+1))
  8. Você pode assumir que sempre receberá uma única caixa ASCII válida como entrada.
Melão Fricativo
fonte
. Eu acho que você esqueceu de acrescentar "possível caráter na saída no numeral 4 da Regra Detalhes Editar: Pode nós assumimos a entrada não tem linhas vazias?
Theraot
Esse exemplo 1x6 é descolado, por que implode para fora? Eu acho que um daqueles ||em que o exemplo necessidade de ser um "ou algo assim ...
Magia Octopus Urna
@carusocomputing igual ao do exemplo inferior esquerdo, as paredes se movem através de um ao outro (de modo que o volume da caixa é negativo) - Regras 4 e 5.
Lyth
@ Lyth ainda não deveria haver um pensamento "? Eu acho que o "único aparece em 3 de largura ou superior?
Magic Octopus Urn
@carusocomputing Considere o seguinte: para onde iria "? À esquerda ou à direita? Não pode ser os dois, mas também não pode ser porque o resultado é simétrico.
HyperNeutrino

Respostas:

15

Python 2 , 591 555 545 527 525 496 436 351 334 333 303 bytes

s=input()
w=len(s[0])
h=len(s)
V=max(0,w/2-h)
H=max(0,h/2-w)
p=[[' ']*w]*V
q=[' ']*H
s=[q+k+q for k in p+s+p]
d,c=' -=',' |"'
exec"c,d,V,H,w,h=d,c,H,V,h,w;s=map(list,zip(*s))[::-1]\nfor j in range(h-4):q=s[V+j+2];q[H]=c[q[H]==c[2]];r=H+min(j+1,h-4-j);q[r]=c[1+(q[r]>' ')]\n"*4
for x in s:print''.join(x)

Experimente online!

EDIT : Meu método antigo primeiro implodiu a parte superior e inferior e, em seguida, a esquerda e direita. Em vez disso, podemos implodir o topo, girar 90 graus e fazer isso 4 vezes. Além disso, eu estava usando o código amigável, este requer que a entrada seja do tipo [['+', '-', '-', '-', '-', '-', '+'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['+', '-', '-', '-', '-', '-', '+']]feio, mas mais curto para o programa: P (Obrigado a Phoenix por entender isso)

Créditos à Leaky Nun pelo código do cabeçalho no link TIO usado para converter entradas legíveis por humanos em entradas legíveis por computador.

-85 bytes graças a Leaky Nun!
-17 bytes, alternando da implosão superior para a esquerda, o que permite que toda a linha seja armazenada em uma variável e modificada. Obrigado a Leaky Nun pela sugestão!
-1 byte alternando as coisas para remover um espaço.
-30 bytes graças a Leaky Nun!

HyperNeutrino
fonte
Atribuir s[0]e S[0]variáveis para economizar alguns bytes
Caird coinheringaahing
@Ilikemydog Oh, certo. Obrigado!
HyperNeutrino 27/05
Você pode substituir p=s[0]e P=S[0]com p=z(s[0])e P=z(S[0]), respectivamente, e depois substituir todas as ocorrências de z(p)com pe tudo z(P)com Ppara salvar 18 bytes.
R. Kap
Você também pode substituir (z(s)-1)/2-ppor z(s)/2-.5-pe (p-1)/2-z(s)com p/2-.5-z(s)para salvar mais 2 bytes.
R. Kap
@ R.Kap Oh ok. Obrigado por ambas as sugestões!
precisa saber é o seguinte
1

C (clang) , 693 bytes

Novas linhas adicionadas para facilitar a leitura. Os dois primeiros são obrigatórios, mas o restante não.

#define P B[i][l]
#define m malloc(8)
I(B,h,V,S,J,Z,i,j,l,n,H,W,c,C,a,z,_,L,G,u,N,M)char**B,**Z;char*L,*G,*u;{
V=strlen(B[0]);
S=J=0;
Z=m;
for(i=0,j=h-1;i<h/2+h%2;i++,j--){
for(l=0,n=V-1;l<V/2+V%2;l++,n--){
if(P!=43&&((B[i][l-1]!=43&&i<1)||(B[i-1][l]!=43&&l<1))){
H=P==45;
W=P=='|';
P=B[j][l]=B[i][n]=B[j][n]=32;
if(H){
c=(N=i+l-1)==(M=j-l+1)?61:45;
if(M<0)L=m,sprintf(L,"%*s",V,""),L[l]=L[n]=c,Z[J]=L,J++;
else B[N][l]=B[N][n]=B[M][l]=B[M][n]=c;
}
if(W){
c=(N=l+i-1)==(M=n-i+1)?34:'|';
if(M<0)G=m,sprintf(G,"|%*s%s%*s|",i-n-2,"",B[i],i-n-2,""),B[i]=B[j]=G,S++;
else B[i][N]=B[j][N]=B[i][M]=B[j][M]=c;
}
}
}
}
for(a=-J+1;a<=h+J;u=a<1?Z[-a]:a<=h?B[a-1]:Z[a-h-1],C=S+1-strlen(u)/2,printf("%*s%s\n",C>0?C:0,"",u),a++);
}

Obrigado pelo grande desafio! Foi bastante complicado, mas ainda me diverti muito.

Isso leva a entrada como argumentos da linha de comando e gera STDOUT uma seqüência de várias linhas da caixa implodida. Como sempre, as dicas de golfe são muito apreciadas.

Experimente online!

R. Kap
fonte