Rettangoli di staffa per ingegnere inverso


24

Ogni programmatore sa che i rettangoli sono davvero divertenti. Per esasperare questo divertimento, questi diagrammi carini e sfocati possono essere trasformati in gruppi di parentesi intrecciate.

Questa sfida è l'inverso del mio precedente .

Supponiamo che tu abbia un gruppo di rettangoli a incastro in questo modo:

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

Note aggiuntive:

  • Non ci +saranno mai due secondi adiacenti
  • Nessun due rettangoli condivideranno mai un bordo o un angolo
  • Ci sarà sempre e solo un bordo verticale in ogni colonna

Il primo passo è guardare il bordo più a sinistra di qualsiasi rettangolo. Assegnalo a uno dei quattro tipi di parentesi ({[<. Io scelgo [.

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

Ora guarda il secondo rettangolo più a sinistra. Poiché si sovrappone a un [rettangolo, deve essere di tipo diverso. Io scelgo (.

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

Il rettangolo più a sinistra successivo non si interseca con nessun rettangolo precedente, ma si annida all'interno del precedente. Ho scelto di assegnarlo di (nuovo. Normalmente è una buona ipotesi assegnare un rettangolo dello stesso tipo di quello che sta annidando se possibile, ma a volte è necessario il backtracking.

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

Il prossimo rettangolo può essere assegnato di [nuovo.

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

Il prossimo rettangolo è piuttosto divertente. Si interseca con a (e un [rettangolo, quindi potrei chiamarlo un {rettangolo (o <ma a nessuno piace quelli).

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

Gli ultimi due rettangoli non sono poi così male. Possono essere di due tipi diversi.

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

Leggendo i rettangoli, ho capito [(]([{))}]<{}>. Questo sarebbe un possibile output per l'ingresso sopra. Ecco un elenco di molte opzioni possibili, non esaustive:

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

Ingresso

Rettangoli di arte ASCII, partendo dal presupposto che non sono ambigui (vedi note sopra) e possono essere correttamente convertiti in una stringa di parentesi. Si può presumere che non ci siano spazi finali o riempiti con un rettangolo, con newline finale opzionale. Non ci saranno spazi bianchi iniziali.

Produzione

Una qualsiasi delle stringhe di parentesi valide che obbedisce alle restrizioni di intersezione dei rettangoli. A parte una nuova riga finale facoltativa, non ci dovrebbero essere altri caratteri oltre le parentesi. La regola principale è che se due quadrati si intersecano, allora dovrebbero essere assegnati diversi tipi di parentesi.

Obbiettivo

Questo è code-golf, (mancanza di) quantità sulla qualità.


3
FYI "esacerbare" significa "peggiorare le cose".
Paul R,

@PaulR Credo che fosse questo il punto
cat

Oh, ok, evidentemente qualunque fosse il punto è andato dritto sopra la mia testa!
Paul R,

Possiamo supporre che ogni rettangolo abbia un'altezza? cioè non può avere a +per l'angolo in alto a sinistra, e quindi (immediatamente sotto) +per per l'angolo in basso a sinistra?
Tersosauros,

Risposte:


2

Python 3, 519 byte

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

Ecco un primo tentativo di soluzione. L'algoritmo utilizzato guarda solo gli angoli del diagramma, abusando del fatto che in una colonna può verificarsi solo una linea verticale, e quindi il primo e l'ultimo + in una colonna devono essere gli angoli di un rettangolo. Quindi raccoglie tutti i rettangoli ed esegue una ricerca ingenua (e in qualche modo non deterministica) per gruppi senza collisioni. Non sono sicuro se questo troverà sempre la soluzione ottimale, ma ha funzionato per tutti gli esempi che ho provato finora. In alternativa, potrebbe essere sostituito da una ricerca di forza bruta per il minor numero di gruppi.

Input: una stringa contenente l'arte ascii. Nessuna nuova riga finale e tutte le linee devono essere riempite con la stessa lunghezza usando gli spazi. Va anche benissimo che tu non ci metta nessuno dei | o - in quanto osserva solo gli angoli.

Dato che il golf è abbastanza semplice (solo la minimizzazione degli spazi bianchi e la ridenominazione delle variabili per lo più) potrebbe probabilmente essere più breve, ma poiché non ci sono altre risposte su questo, per ora lo lascerò così.


Ottieni la taglia, perché non prevedo altre risposte in <1 giorno. Grazie per aver risposto, continua a giocare a golf!
Rɪᴋᴇʀ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.