Analysieren Sie eine 1D-Sprache

13

Bei einer Zeichenfolge, die nur Nullen, Einsen, Zweisen und Klammern enthält, wird der Grammatikbaum der Zeichenfolge ausgegeben.

A 2erfordert zwei Argumente - eines nach links und eines nach rechts

A 1erfordert ein einzelnes Argument - entweder nach links oder nach rechts

A 0benötigt keine Argumente und ist der Basisfall

Ein Klammerpaar zählt als ein Argument, und der Inhalt der Klammern wird getrennt vom Rest der Zeichenfolge ausgewertet. Verschachtelte Klammern sind möglich

Eine Eingabezeichenfolge ist immer ein vollständiger Baum, aus dem keine Zeichen herausfallen. Die Zeichenfolge hat auch nur eine einzige richtige Lösung. Beachten Sie, dass die Funktionen kommutativ sind und jede Anordnung von Argumenten 2zulässig ist. Sie müssen keine Eingaben verarbeiten, die diesen Anforderungen nicht entsprechen.

Das Ausgabeformat für die Grammatik wird function(arguments)rekursiv angegeben

Testfälle

0 --> 0
01 --> 1(0)
020 --> 2(0,0)
101 --> 1(1(0))
0120 --> 2(1(0),0)
0120210 --> 2(1(0),2(0,1(0)))
01210 --> 2(1(0),1(0))
(020)210 --> 2(2(0,0),1(0))
((020)20)1 --> 1(2(0,2(0,0)))
Blau
quelle
Ist 10201gültige Eingabe?
Neil
Nein, es könnte 1 (2 (0,1 (0)) oder 2 (1 (0), 1 (0))
Blau
Eigentlich dachte ich, es wäre 1 (2 (1 (0), 0)) ;-)
Neil
1
Ich verstehe immer noch nicht, warum 0120210nicht auch analysiert werden kann, 2[4](2[2](1[1](0[0]), 0[3]), 1[5](0[6]))wo die Zahlen in Klammern die Position in der Zeichenfolge angeben.
Feersum
101ist auch mehrdeutig.
Feersum

Antworten:

3

Python 3.6 (Vorabversion), 199

6 Bytes gespart dank Morgan Thrapp

import re
def f(s):s=s.strip('()');i,j=[m.start()if m else-1for m in(re.search(c+'(?![^(]*\))',s)for c in'21')];return i>0and f'2({f(s[:i])},{f(s[i+1:])})'or j>=0and f'1({f(s[:j])or f(s[j+1:])})'or s

Erklärung & ungolfed version:

import re

def f(s):
    s=s.strip('()')
    # Search for '2' and '1' outside of brackets
    i, j = [m.start() if m else -1
            for m in (re.search(c + '(?![^(]*\))', s) for c in '21')]

    if i > 0:
        # Call `f(s[:i])` and `f(s[i+1:])`, concatenate the results
        return f'2({f(s[:i])},{f(s[i+1:])})'
    elif j>=0:
        # Call `f(s[:j])` and `f(s[j+1:])`, choose the non-empty result
        return f'1({f(s[:j]) or f(s[j+1:])})'
    else:
        return s
Vaultah
quelle