Bolla le staffe!


27

questo sito sono alcune domande sul bilanciamento delle parentesi e sul controllo del bilanciamento delle parentesi. Propongo che è ora di usare quelle parentesi bilanciate per qualcosa!

In matematica e programmazione, le parentesi sono come bolle, isolando tutto dentro da tutto fuori, in modo che tutto ciò che è dentro possa fare la sua cosa in pace e tutto ciò che è fuori vede solo un oggetto. Tuttavia, una stringa di parentesi è monodimensionale, mentre le bolle di solito sono almeno bidimensionali. Ciò significa che le bolle sono libere di muoversi l'una intorno all'altra purché non si tocchino mai o si incrociano tra l'interno e l'esterno di altre bolle.

Sfida

L'input è una stringa di parentesi corrispondenti di un singolo tipo, rotonda (), quadrata [], riccia{} o angolare <>. Sta a te decidere quale tipo accettare il tuo programma e viene accettato un programma che accetta solo un solo tipo di parentesi. (Bonus immaginario se il tuo programma è in grado di gestirne uno qualsiasi, enormi punti bonus immaginari se può gestirli tutti nello stesso input.) L'input non può contenere nulla tra le parentesi, sebbene siano consentiti spazi bianchi finali.

L'output è tutte le possibili riorganizzazioni (in ordine arbitrario e incluso l'input originale) di quelle parentesi che producono la stessa configurazione di bolle, senza due stringhe identiche. Ciò significa che con un input di ()(), anche l'output è giusto ()(), anche se tecnicamente sono due bolle che potrebbero scambiare posizioni. Per l'enorme bonus immaginario, un input di {}[]()volontà ovviamente porta ad un output di 6 diversi elementi / stringhe / linee.

Due configurazioni di bolle sono "uguali" se riesci a farne una spostando le bolle in giro, senza far attraversare alcuna bolla dall'interno verso l'esterno o dall'interno verso l'esterno. Se si paragonano parentesi annidate ad alberi (ogni coppia abbinata è un nodo e ogni coppia abbinata all'interno è un nodo secondario, e ogni coppia abbinata all'interno contiene di nuovo un nodo secondario, e così via) in cui sono ordinati i nodi secondari di un dato nodo , quindi una singola configurazione di bolle è un albero in cui i nodi non sono ordinati.

Qualsiasi formato di output ragionevole farà, come restituire un elenco di stringhe o un elenco di elenchi di singoli caratteri o una singola stringa con un qualche tipo di spazio bianco, oppure stampare su stdouto stderrcon una qualche forma di carattere di spazio bianco visibile (più comunemente newline o spazio) tra ogni riorganizzazione.

Spazi di trascinamento per ogni riorganizzazione e trascinamento e precedenti righe precedenti / elementi di elenco vuoti prima e dopo l'output effettivo sono consentiti. Dovresti usare lo stesso tipo di parentesi nell'output che accetti nel tuo input. A parte le parentesi, le nuove linee e gli spazi specificati qui e qualunque sia il separatore che usi, non dovrebbe essere stampato nulla (inclusi i caratteri invisibili / di larghezza zero).

Il punteggio è il numero di byte nel codice; vince il conteggio più basso per ogni lingua. Puoi notare se ricevi un bonus immaginario, regolare o massiccio, ma non influisce sul tuo punteggio. I bonus effettivi sono troppo difficili da bilanciare nel modo giusto.

Esempi di input-output

Esempio 1:

Ingresso:

()(())

Produzione:

()(())
(())()

Esempio 2:

Ingresso:

(()())()()

Produzione:

(()())()()
()(()())()
()()(()())

Esempio 3:

Ingresso:

(()(()))()

Produzione:

((())())()
()((())())
(()(()))()
()(()(()))

Perché non possiamo ottenere ((()))nell'esempio 1? o ()()()? Sembra che manchi le permutazioni per ogni input.
Wheat Wizard

@WheatWizard Che non darebbe la stessa configurazione di bolle: una grande bolla con due bolle vuote all'interno.
Arthur,

@WheatWizard per quanto ho capito, non puoi prendere una bolla dall'interno di un'altra bolla verso l'esterno, o viceversa.
Grzegorz Puławski,

@WheatWizard Ho aggiunto una piccola spiegazione.
Arthur,

7
A proposito, benvenuto in PPCG! Bella prima sfida!
Mr. Xcoder,

Risposte:


4

CJam , 18 byte

{~{_{{B}%e!}&}:B~}

Provalo online!

-2 grazie a Business Cat .

Riceve input come una stringa contenente solo []. Restituisce un elenco di permutazioni (gli elenchi vuoti sono gli stessi delle stringhe vuote in CJam, quindi invece di []ottenere "").


Perché l'output è [][]solo ""? - L'ingresso deve essere racchiuso in un set aggiuntivo di []? In caso affermativo, perché esiste un set aggiuntivo di []ciò che (forse?) È l'output per l'esempio di cui sopra? Inoltre la domanda afferma "Dovresti usare lo stesso tipo di parentesi nel tuo output come accetti nel tuo input. A parte le parentesi, le nuove righe e gli spazi come specificato qui, e qualunque sia il separatore che usi, nulla dovrebbe essere stampato", quindi io ' Non sono sicuro che un mix di []ed ""è accettabile.
Jonathan Allan,

@JonathanAllan Sì, penso che devi racchiuderlo [][]in un paio extra di []. Per gli altri non sono proprio sicuro che non siano validi.
Erik the Outgolfer,

Penso che tu possa fare _{{B}%e!}&invece di_!!{{B}%e!}*
Business Cat

@BusinessCat &Corto circuito o qualcosa del genere?
Erik the Outgolfer,

&esegue il blocco solo se l'altro valore è true
Business Cat,

4

Haskell , 227 210 208 205 byte

import Data.List
l=last
a!x=init a++[l a++[x]]
h[]=[""]
h(x:y)=["("++z++")"++t|z<-v x,t<-h y]
g(a,r)x|x=='('=(a+1,l$(r++h[]):[r!x|a>0])|1>0=(a-1,l$r:[r!x|a>1])
v s=nub$h=<<(permutations.snd$foldl g(0,[])s)

Provalo online!

Questo è stato difficile!

Ho giocato a golf un po '

Salvato due byte grazie a Laikoni

Risparmia due byte grazie a Bruce Forte

Non sono sicuro che funzioni in ogni caso. Alcune spiegazioni:

  • a!xaggiungi la stringa xall'ultimo elenco di string in a(a è di tipo [[String]])

  • snd$foldl(\(a,r)x->if x=='('then(a+1,last$(r++[[]]):[r!x|a>0])else(a-1,last$r:[r!x|a>1])usa il condizionale più breve per esprimere l'idea semplice: dividere una stringa su root )( s. Ad esempio, "(()(()))()"["()(())", ""].

  • Dobbiamo elaborare ogni parte della divisione, quindi raccogliere e unire tutte le stringhe per ottenere l'output corretto:

    1. helabora un elenco di parti: si applica valla prima parte e combina il risultato al processo delle parti rimanenti.

    2. v aggrega i risultati per ciascuna permutazione delle parti e rimuove i duplicati.

Per aggiungere una vista più ampia: hai fondamentalmente un albero (non binario) con nodi vuoti. Lasciare sono (). Devi produrre tutte le permutazioni dei rami per ciascun nodo, ma non puoi prendere un ramo da un nodo e metterlo su un altro nodo. Ho fatto una prima ricerca approfondita.


È possibile rilasciare le parentesi init a.
Laikoni,

2

Python 2, 353 350 331 byte

s=input()
f=lambda i,t=0:i+1if t<0else f(i+1,t-1)if"("<s[i+1]else f(i+1,t+1)
c=[(x,f(x))for x in range(len(s))if")">s[x]]
p=lambda l:[[]]if len(l)<1else[x for y in p(l[1:])for x in[y[:i]+[l[0]]+y[i:]for i in range(len(y)+1)]]
print[''.join(x)for x in p([s[c[x][0]:c[x][1]]for x in range(len(c))if all(c[x][1]>y[1]for y in c[:x])])]

Riceve una stringa di ()input e stampa il risultato.

Provalo qui!

Ho evitato di usare itertools.permutationscon l'aiuto della risposta di Paolo a questa domanda .

Grazie a Business Cat per aver trovato 3 byte, e grazie a Mr. Xcoder per un incredibile 19 byte!

Spiegazione

  1. Crea un elenco di tuple degli indici di ciascuna ()coppia nella stringa di input.
  2. Elimina eventuali tuple dall'elenco circondate da un'altra ()coppia.
  3. Taglia la stringa negli indici delle tuple rimanenti.
  4. Crea un elenco di ciascuna permutazione dell'elenco delle sezioni.
  5. Iscriviti alla lista con una nuova linea per la stampa.

Vedo alcuni byte che potrebbero essere rasati. Hai degli spazi bianchi che possono essere rimossi, vale a dire dopo printe in punti come i+1 if(potrebbe essere i+1if). Anche in un punto che hai y[0:i], puoi omettere lo 0.
Business Cat

Grazie, @BusinessCat! Il mio IDE si lamenta di alcuni di questi, quindi sto ancora imparando alcuni dei trucchi del codice del golf.
Risoluzione

342 byte (-8 byte) riordinando alcuni condizionali per rimuovere gli spazi bianchi.
Mr. Xcoder,

340 byte (-10 byte) utilizzando il confronto lessicografico sul controllo dell'uguaglianza.
Mr. Xcoder,

331 byte (-19 byte) perché la sfida consente di restituire un elenco di stringhe. yay, abbiamo battuto Mathematica :-)
Mr. Xcoder il

2

JavaScript (Firefox 30-57), 222 byte

s=>(g=a=>a+a?[for(x of g(a[0]))for(y of a.keys())for(z of g(a.slice(1)))(z.splice(y,0,x),z)]:[a])(eval(`[${s.replace(/]\[/g,`],[`)}]`)).map(g=a=>`[`+a.map(g).join``+`]`).sort().filter(s=>t<(t=s),t=``).map(s=>s.slice(1,-1))

Prende []stringhe. Spiegazione:

s=>(                                Inner function to permute an array
 g=a=>a+a?[                         If array is not empty
  for(x of g(a[0]))                 Permute the first element of the array
  for(y of a.keys())                Generate a list of insertion points
  for(z of g(a.slice(1)))           Permute the rest of the array
  (z.splice(y,0,x),z)]:             Make all possible permutations
  [a]                               Otherwise return a list of an empty array
)(eval(`[${                         Convert the string to a nested array
   s.replace(/]\[/g,`],[`)}]`)      ... inserting commas where necessary
).map(                              Process the results
 g=a=>`[`+a.map(g).join``+`]`       Recursively convert back to string
).sort().filter(s=>t<(t=s),t=``     Check for duplicates
).map(s=>s.slice(1,-1))             Remove outer `[]`s

0

Mathematica, 337 byte

Non per ottenere punti di golf code, ma per mostrare l'utilizzo Permutationse Distributein questo problema. Tuttavia, potrebbero esserci approcci migliori.

( seq: sequenza,: altalternative)

SetAttributes[alt, {Flat, OneIdentity}]
StringTake[
  StringReplace[ToString[
    ToExpression["{" <> StringReplace[#, "}{" -> "},{"] <> "}"]
        /. List -> Permutations@*seq
       /. List -> alt
      /. seq -> (Distribute[seq@##, alt] &)
     /. {seq -> List, alt -> Alternatives}],
   {", " -> "", "} | {" -> "\n"}],
  {2, -2}] &

Prendi l'input come stringa, usando parentesi graffe {e }. Emette una stringa multilinea.

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.