Sequenze tra parentesi in ordine lessicografico


9

Sfida presa da qui e anche qui

Una sequenza di n parentesi è composta da n ( s e n ) s.

Una sequenza di parentesi valida è definita come la seguente:

È possibile trovare un modo per ripetere la cancellazione della parentesi adiacente "()" fino a quando non diventa vuota.

Ad esempio, (())è una parentesi valida, puoi cancellare la coppia nella seconda e terza posizione e diventa (), quindi puoi renderla vuota. )()(non è una parentesi valida, dopo aver cancellato la coppia in seconda e terza posizione, diventa )(e non è più possibile cancellare

Compito

Dato un numero n è necessario generare tutta la sequenza di parentesi corretta in ordine lessicografico

L'output può essere una matrice, un elenco o una stringa (in questo caso una sequenza per riga)

È possibile utilizzare un paio di parentesi, come diverso {}, [], ()o alcun segno open-close

Esempio

  • n = 3

    ((()))    
    (()())    
    (())()    
    ()(())    
    ()()()
    
  • n = 2

    (())
    ()()
    

@JoKing Sì, certo. Presumo che comunque non farà alcuna differenza per il concetto principale della sfida.
Luis felipe De jesus Munoz,

Eh, riesco a pensare ad alcune lingue in cui eval le interpreterebbe diversamente, ad esempio
Jo King,

1
Correlati: Numeri catalani (risultato di tale sfida = numero di righe del risultato di questa sfida)
user202729

3
Praticamente lo stesso , ma con alcune strane restrizioni come "Non puoi scrivere funzioni ricorsive". /// Un superset di questa sfida (consenti tutte le parentesi Brain-Flak)
user202729

"Una matrice, un elenco o una stringa" "di sequenze" di "qualsiasi segno di apertura-chiusura" significa che potremmo produrre un elenco di elenchi di due numeri interi (come 1s e -1s)?
Jonathan Allan,

Risposte:


8

Perl 6 , 36 byte

{grep {try !.EVAL},[X~] <[ ]>xx$_*2}

Provalo online!

Trova tutte le combinazioni lessicograficamente ordinate di 2n [] filtra quelle EVALcorrettamente. Nota che tutte le combinazioni valide (anche cose simili [][]) valutano [](che è falso, ma noi not( !) per distinguere dal tryritorno Nil)

Spiegazione:

{                                  }  # Anonymous code block
                        <[ ]>         # Create a list of ("[", "]")
                             xx$_*2   # Duplicate this 2n times
                   [X~]               # Find all possible combinations
 grep {          },                   # Filter from these
            .EVAL                     # The EVAL'd strings
       try !                          # That do not throw an error

3
Se qualcuno è curioso, [][]è la fetta Zen di un array vuoto che produce l'array stesso. La sezione può essere applicata più volte, quindi [][][][]...valuta []. Inoltre, [[]]non costruisce un array nidificato ma un array vuoto a causa della regola dell'argomento singolo (dovresti scrivere [[],]per un array nidificato). Quindi qualsiasi sequenza bilanciata di []parentesi si traduce in un array vuoto che boolifica su falso.
nwellnhof,

6

R , 112 107 99 byte

Approccio non ricorsivo. Usiamo "<" e ">" perché evita i caratteri di escape nel regex. Per consentirci di utilizzare una specifica più breve per un intervallo ASCII, generiamo stringhe di 3 ^ 2n 2n caratteri di "<", "=" e ">" utilizzandoexpand.grid (tramite i loro codici ASCII 60, 61 e 62) e quindi grep per vedere quali combinazioni danno parentesi aperte e chiuse bilanciate. Le possibilità "=" verranno ignorate, ovviamente.

Via http://rachbelaid.com/recursive-regular-experession/

function(n)sort(grep("^(<(?1)*>)(?1)*$",apply(expand.grid(rep(list(60:62),2*n)),1,intToUtf8),,T,T))

Provalo online!

Spiegazione

"^(<(?1)*>)(?1)*$" = regex for balanced <> with no other characters
^ # match a start of the string
  ( # start of expression 1
    < # open <>
       (?1)* # optional repeat of any number of expression 1 (recursive)
  # allows match for parentheses like (()()())(()) where ?1 is (\\((?1)*\\))
    > # close <>
  ) # end of expression 1
  (?1)* # optional repeat of any number of expression 1
$ # end of string

function(n)
  sort(
    grep("^(<(?1)*>)(?1)*$", # search for regular expression matching open and close brackets
      apply(
        expand.grid(rep(list(60:62),2*n)) # generate 3^(2n) 60,61,62 combinations
      ,1,intToUtf8) # turn into all 3^(2n) combinations of "<","=",">"
    ,,T,T) # return the values that match the regex, so "=" gets ignored
  ) # sort them

R , 107 byte

Solito approccio ricorsivo.

-1 grazie @Giuseppe

f=function(n,x=0:1)`if`(n,sort(unique(unlist(Map(f,n-1,lapply(seq(x),append,x=x,v=0:1))))),intToUtf8(x+40))

Provalo online!


1
ah, stavo cercando di trovare un Mapgolf ma non riuscivo a avvolgerci la testa. Non sono convinto che parse+ evalfunzionerà da allora ()()e simili errori di lancio.
Giuseppe,

4

C (gcc) , 114 byte

f(n,x,s,a,i){char b[99]={};n*=2;for(x=1<<n;x--;s|a<0||puts(b))for(s=a=i=0;i<n;)a|=s+=2*(b[n-i]=41-(x>>i++&1))-81;}

Provalo online!

Dovrebbe funzionare per n <= 15.

Spiegazione

f(n,x,s,a,i){
  char b[99]={};   // Output buffer initialized with zeros.
  n*=2;            // Double n.
  for(x=1<<n;x--;  // Loop from x=2**n-1 to 0, x is a bit field
                   // where 1 represents '(' and 0 represents ')'.
                   // This guarantees lexicographical order.
      s|a<0||puts(b))  // Print buffer if s==0 (as many opening as
                       // closing parens) and a>=0 (number of open
                       // parens never drops below zero).
    for(s=a=i=0;i<n;)  // Loop from i=0 to n-1, note that we're
                       // traversing the bit field right-to-left.
      a|=              // a is the or-sum of all intermediate sums,
                       // it becomes negative whenever an intermediate
                       // sum is negative.
        s+=            // s is the number of closing parens minus the
                       // number of opening parens.
                        x>>i++&1   // Isolate current bit and inc i.
                    41-(        )  // ASCII code of paren, a one bit
                                   // yields 40 '(', a zero bit 41 ')'.
             b[n-i]=               // Store ASCII code in buffer.
          2*(                    )-81;  // 1 for ')' and -1 for '(' since
                                        // we're going right-to-left.
}


3

05AB1E , 13 byte

„()©s·ãʒ®õ:õQ

Provalo online o verifica alcuni altri casi di test .

Spiegazione:

„()            # Push string "()"
   ©           # Store it in the register without popping
    s·         # Swap to get the (implicit) input, and double it
      ã        # Cartesian product that many times
       ʒ       # Filter it by:
        ®      #  Push the "()" from the register
         õ:    #  Infinite replacement with an empty string
           õQ  #  And only keep those which are empty after the infinite replacement


3

Japt, 15 13 byte

ç>i<)á Ôke/<>

Provalo


Spiegazione

ç                 :Input times repeat the following string
 >i<              :  ">" prepended with "<"
    )             :End repeat
     á            :Get unique permutations
       Ô          :Reverse
        k         :Remove any that return true (non-empty string)
         e/<>     :  Recursively replace Regex /<>/

3

K (ngn / k) , 36 35 byte

{"()"(&/-1<+\1-2*)#(x=+/)#+!2|&2*x}

Provalo online!

+!2|&2*x tutti i vettori binari di lunghezza 2 * n

(x=+/)# solo quelli che sommano a n

(&/-1<+\1-2*)# solo quelli le cui somme parziali, trattando 0/1 come 1 / -1, non sono affatto negative

"()" usa 0/1 come indici in questa stringa



2

Perl 6 , 42 byte

{grep {!S:g/\(<~~>*\)//},[X~] <( )>xx$_*2}

Provalo online!

Usa una regex ricorsiva. Sostituzione alternativa:S/[\(<~~>\)]*//

38 byte con 0 e 1 come simboli di apertura / chiusura:

{grep {!S:g/0<~~>*1//},[X~] ^2 xx$_*2}

Provalo online!

Spiegazione

{                                        }  # Anonymous block
                              <( )>         # List "(", ")"
                                   xx$_*2   # repeated 2n times
                         [X~]  # Cartesian product with string concat
                               # yields all strings of length 2n
                               # consisting of ( and )
 grep {                },  # Filter strings
        S:g/             # Globally replace regex match
            \(           #   literal (
              <~~>       #   whole regex matched recursively
                  *      #   zero or more times
                   \)    #   literal )
                     //  # with empty string
       !                 # Is empty string?

2

Retina 0.8.2 , 50 byte

.+
$*
1
11
+%1`1
<$'¶$`>
Gm`^(?<-1>(<)*>)*$(?(1).)

Provalo online! Usa <>s. Spiegazione:

.+
$*

Converti in unario.

1
11

Raddoppia il risultato.

+%1`1
<$'¶$`>

Enumera tutti i numeri binari 2² 2n-bit, mappando le cifre su <>.

Gm`^(?<-1>(<)*>)*$(?(1).)

Mantieni solo sequenze bilanciate. Questo utilizza un trucco tra parentesi bilanciato scoperto da @MartinEnder.



2

Rosso , 214, 184 136 byte

func[n][g: func[b n][either n = length? b[if not error? try[load b][print b]return 0][g append copy b"["n g append copy b"]"n]]g""2 * n]

Provalo online!

Utilizza l'approccio di Jo King. Trova tutte le disposizioni possibili delle parentesi usando la ricorsione (sono generate in ordine lessicografico) e stampale se la disposizione viene valutata come un blocco valido.


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.