Ausdrücke in Klammern vollständig

11

Heute besteht Ihre Herausforderung darin, alle möglichen vollständigen Klammern eines Ausdrucks zu erstellen.

Ihre Eingabe ist eine einzelne Zeile druckbaren ASCII, die einen oder mehrere durch Operatoren getrennte Begriffe enthält. Die Eingabe kann auch Leerzeichen enthalten - Sie müssen diese ignorieren. Ein Begriff ist [a-zA-Z0-9], ein Operator ist [^ ()a-zA-Z0-9]. Sie können davon ausgehen, dass die Eingabe immer gültig ist.

Geben Sie alle möglichen Möglichkeiten aus, um den angegebenen Ausdruck vollständig in Klammern zu setzen, getrennt durch Zeilenumbrüche mit einem optionalen nachgestellten Zeilenumbruch.

Haben nicht :

  • Begriffe in Klammern - nur in Klammern um Operatoren.
  • Ordnen Sie die Bedingungen neu.
  • Geben Sie Leerzeichen aus.

Beispiel Eingabe / Ausgabe:

N
N

a * b
(a*b)

x_x_0
(x_(x_0))
((x_x)_0)

a * b|c|d
(a*(b|(c|d)))
(a*((b|c)|d))
((a*b)|(c|d))
((a*(b|c))|d)
(((a*b)|c)|d)

Der kleinste Code in Bytes gewinnt.

orlp
quelle
Sie müssen die genauen Operatoren auflisten, die wir berücksichtigen müssen. Ist !ein Betreiber? Was ist mit ?
Optimierer
@Optimizer Ich habe den genauen regulären Ausdruck eines Operators aufgelistet. !passt zur Regex, kann aber auch nicht Teil der Eingabe sein, da es kein druckbares ASCII ist.
Orlp
Ah okay. Also alles außer einem Begriff ist ein Operator ...
Optimizer
Also sind sowohl Begriffe als auch Operatoren immer ein Zeichen lang?
user81655
1
Fügen Sie hier das obligatorische Wortspiel im Zusammenhang mit LISP ein
Katze

Antworten:

2

Pyth, 38 Bytes

L?tbsmmjj@bdk"()"*y<bdy>bhd:1lb2bjy-zd

Probieren Sie es online aus.

Es definiert eine rekursive Funktion, die:

  • Gibt die Eingabe zurück, wenn ihre Länge 1 ist
  • Nimmt alle zwei Teilungen der Eingabe für Operatoren und für jede Teilung:
    • ruft sich rekursiv auf jeder der Hälften auf
    • nimmt das kartesische Produkt der Ergebnisse jeder Hälfte
    • verbindet jedes Ergebnis durch den Operator bei der Aufteilung
    • Klammert das verknüpfte Ergebnis in Klammern
  • und verkettet schließlich die resultierenden Arrays.

Die Funktion wird dann mit der Eingabezeichenfolge aufgerufen, wobei Leerzeichen entfernt werden, und die Ergebnisse werden durch Zeilenumbrüche verbunden.

PurkkaKoodari
quelle
3

JavaScript (ES6), 208 197 Bytes

s=>((q=x=>x.map((_,i)=>(a=[...x.slice(0,i*=2),p="("+x[i]+x[++i]+x[++i]+")",...x.slice(i+1)],x[i]?a[1]?q(a):r.push(p):0)))([...s.replace(/ /g,o="")],r=[]),r.map((l,i)=>r.indexOf(l)<i?0:o+=l+`
`),o)

Erläuterung

Verwendet eine rekursive Funktion, die ein Array von [ t, o, t, o, etc... ]und nimmt jedes aufeinanderfolgende Paar von zwei Begriffen in Klammern zusammen [ (tot), o, etc... ]und wiederholt diesen Vorgang, bis nur noch ein Element im Array vorhanden ist, und filtert dann die doppelten Werte heraus.

s=>(                                  // s = input string
  (q=x=>                              // q = parenthesise array function
    x.map((_,i)=>(
      a=[                             // a = p with parenthesised pair of terms
        ...x.slice(0,i*=2),
        p="("+x[i]+x[++i]+x[++i]+")", // parenthesise and join 2 terms and an operator
        ...x.slice(i+1)
      ],
      x[i]?a[1]                       // make sure the loop is not over
        ?q(a)                         // check next level of permutations
        :r.push(p)                    // add the permutation to the results
      :0
    ))
  )([...s.replace(/ /g,               // remove spaces and parenthesise all expressions
    o="")],                           // o = output string
    r=[]),                            // r = array of result strings
  r.map(                              // filter out duplicates
    (l,i)=>r.indexOf(l)<i?0:o+=l+`
`
  ),o)                                // return o

Prüfung

user81655
quelle