Retângulos de suporte de engenharia reversa

24

Todo programador sabe que os retângulos são realmente divertidos. Para exacerbar essa diversão, esses diagramas fofos e confusos podem ser transformados em grupos de colchetes entrelaçados.

Este desafio é o inverso do meu anterior .

Digamos que você tenha um grupo de retângulos entrelaçados como este:

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

Notas Adicionais:

  • Dois +s nunca serão adjacentes
  • Dois retângulos nunca compartilharão uma borda ou canto
  • Só haverá no máximo uma aresta vertical em cada coluna

O primeiro passo é observar a borda mais à esquerda de qualquer retângulo. Atribua a ele um dos quatro tipos de colchetes ({[<. Eu escolho [.

   +------------+
   |            |
[--+-]     +----+-+
[  | ]     |    | |
[  | ] +---+--+ | |
[  | ] |   |  | | |
[--+-] | +-+--+-+-+-+
   |   | | |  | | | |
   |   | | |  | | | |
   |   | | |  | | | |    +-+
   |   +-+-+--+ | | |    | |
   |     | |    | | |  +-+-+-+
   +-----+-+----+ | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

Agora olhe para o segundo retângulo mais à esquerda. Como ele se sobrepõe a um [retângulo, ele deve ser de um tipo diferente. Eu escolho (.

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] +---+--+ ) |
[  ( ] |   |  | ) |
[--(-] | +-+--+-)-+-+
   (   | | |  | ) | |
   (   | | |  | ) | |
   (   | | |  | ) | |    +-+
   (   +-+-+--+ ) | |    | |
   (     | |    ) | |  +-+-+-+
   (-----+-+----) | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

O próximo retângulo mais à esquerda não cruza com nenhum retângulo anterior, mas aninha-se dentro do anterior. Eu escolho atribuí-lo (novamente. Normalmente, é aconselhável atribuir um retângulo ao mesmo tipo do que está aninhado dentro, se possível, mas às vezes é necessário voltar atrás.

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] (---+--) ) |
[  ( ] (   |  ) ) |
[--(-] ( +-+--)-)-+-+
   (   ( | |  ) ) | |
   (   ( | |  ) ) | |
   (   ( | |  ) ) | |    +-+
   (   (-+-+--) ) | |    | |
   (     | |    ) | |  +-+-+-+
   (-----+-+----) | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

Este próximo retângulo pode ser atribuído [novamente.

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] (---+--) ) |
[  ( ] (   |  ) ) |
[--(-] ( [-+--)-)-+-]
   (   ( [ |  ) ) | ]
   (   ( [ |  ) ) | ]
   (   ( [ |  ) ) | ]    +-+
   (   (-[-+--) ) | ]    | |
   (     [ |    ) | ]  +-+-+-+
   (-----[-+----) | ]  | | | |
         [ |      | ]  | +-+ |
         [ +------+ ]  |     |
         [          ]  |     |
         [----------]  +-----+

Este próximo retângulo é meio divertido. Ele cruza (um [retângulo e um , para que eu possa chamá-lo de {retângulo (ou <mas ninguém gosta disso).

   (------------)
   (            )
[--(-]     {----)-}
[  ( ]     {    ) }
[  ( ] (---{--) ) }
[  ( ] (   {  ) ) }
[--(-] ( [-{--)-)-}-]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]    +-+
   (   (-[-{--) ) } ]    | |
   (     [ {    ) } ]  +-+-+-+
   (-----[-{----) } ]  | | | |
         [ {      } ]  | +-+ |
         [ {------} ]  |     |
         [          ]  |     |
         [----------]  +-----+

Os dois últimos retângulos não são tão ruins. Eles podem ser de dois tipos diferentes.

   (------------)
   (            )
[--(-]     {----)-}
[  ( ]     {    ) }
[  ( ] (---{--) ) }
[  ( ] (   {  ) ) }
[--(-] ( [-{--)-)-}-]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]    {-}
   (   (-[-{--) ) } ]    { }
   (     [ {    ) } ]  <-{-}->
   (-----[-{----) } ]  < { } >
         [ {      } ]  < {-} >
         [ {------} ]  <     >
         [          ]  <     >
         [----------]  <----->

Lendo os retângulos, entendi [(]([{))}]<{}>. Essa seria uma saída possível para a entrada acima. Aqui está uma lista de muitas opções possíveis, não exaustivas:

[(]([{))}]<{}>
<(>(<{))}>{()}
{<}[{(]>)}[<>]
any of the 4! permutations of ([{<, you get the idea...

Entrada

Retângulos de arte ASCII, com a premissa de que não são ambíguos (consulte as notas acima) e podem ser adequadamente convertidos em uma sequência de colchetes. Você pode assumir que não há espaços à direita ou preenchido com um retângulo, com a nova linha à direita opcional. Não haverá espaço em branco à esquerda.

Saída

Qualquer uma das cadeias de colchetes válidas que obedeça às restrições de interseção dos retângulos. Além de uma nova linha à direita opcional, não deve haver outros caracteres além de colchetes. A regra principal é que, se dois quadrados se cruzarem, eles deverão receber diferentes tipos de colchetes.

Objetivo

Isso é código-golfe, (falta de) quantidade acima da qualidade.

PhiNotPi
fonte
3
Para sua informação, "exacerbar" significa "piorar uma coisa ruim".
Paul R
@PaulR Eu acredito que esse era o ponto #
cat
Oh, ok, evidentemente, qualquer que seja o ponto, passou direto pela minha cabeça!
Paul R
Podemos assumir que cada retângulo tem alguma altura? ou seja, ele não pode ter um +para o canto superior esquerdo e depois (imediatamente abaixo) o +para o canto inferior esquerdo?
Tersosauros 28/03

Respostas:

2

Python 3, 519 bytes

def c(i):
 a,b,c,d={},0,[],{}
 for e in map("".join,zip(*i.split("\n"))):
  if"+"in e:
   f=e.index("+"),e.rindex("+")
   if f in a:j=a.pop(f);d[j]=f+(d[j],len(c));c.append(j)
   else:a[f]=b;d[b]=len(c);c.append(b);b+=1
 g,h={},0
 while d:
  i={list(d)[0]};
  for j,(k,l,m,n)in d.items():
   for(o,p,q,r)in(d[v]for v in i):
    if not(m>r or n<q or k>p or l<o or(q<m<n<r and o<k>l<p)):break
   else:i.add(j)
  for j in i:del d[j];g[j]=h
  h+=1
 s,u=set(),""
 for t in c:u+="[{(<]})>"[g[t]+4*(t in s)];s.add(t)
 return u

Aqui está uma primeira tentativa de solução. O algoritmo usado puramente examina os cantos do diagrama, abusando do fato de que apenas uma linha vertical pode ocorrer em uma coluna e, portanto, o primeiro e o último + em uma coluna devem ser os cantos de um retângulo. Em seguida, ele coleta todos os retângulos e realiza uma pesquisa ingênua (e um tanto não determinística) por grupos sem colisão. Não tenho certeza se isso sempre encontrará a solução ideal, mas funcionou para todos os exemplos que tentei até agora. Como alternativa, poderia ser substituído por uma busca de força bruta pela menor quantidade de grupos.

Entrada: uma sequência contendo a arte ascii. Nenhuma nova linha à direita e todas as linhas devem ser preenchidas com o mesmo comprimento usando espaços. Também é muito bom você não colocar nenhum dos | ou 's lá, pois apenas olha para os cantos.

Como o golfe é bastante simples (principalmente minimalização de espaços em branco e renomeação de variáveis), provavelmente pode ser mais curto, mas como ainda não há outras respostas sobre isso, vou deixar assim por enquanto.

CensoredUsername
fonte
Você recebe a recompensa, porque não vejo outras respostas em menos de um dia. Obrigado por responder, continue jogando golfe!
Rɪᴋᴇʀ