Analizuj język 1D


13

Biorąc pod uwagę ciąg zawierający tylko 0, 1, 2 i nawiasy, wyprowadzaj drzewo gramatyki łańcucha.

2Wymaga 2 argumenty - jeden po lewej i jeden w prawo

1Wymaga jednego argumentu - do lewej lub prawej

A 0nie wymaga żadnych argumentów i jest podstawowym przypadkiem

Para nawiasów liczy się jako jeden argument, a zawartość nawiasów jest oceniana oddzielnie od reszty ciągu. Możliwe są zagnieżdżone nawiasy

Ciąg wejściowy zawsze będzie kompletnym drzewem bez spadających znaków. Ciąg będzie miał tylko jedno poprawne rozwiązanie. Zauważ, że funkcje są przemienne i każde ustawienie argumentów dla 2jest dopuszczalne. Nie będziesz musiał obsługiwać danych wejściowych, które nie spełniają tych wymagań.

Wyjściowy format gramatyki będzie miał postać function(arguments)rekurencyjną

Przypadki testowe

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)))

Czy 10201prawidłowe dane wejściowe?
Neil

Nie, może to być 1 (2 (0,1 (0))) lub 2 (1 (0), 1 (0))
niebieski

Właściwie myślałem, że to 1 (2 (1 (0), 0)) ;-)
Neil

1
Nadal nie rozumiem, dlaczego 0120210nie można go również przeanalizować, ponieważ 2[4](2[2](1[1](0[0]), 0[3]), 1[5](0[6]))liczby w nawiasach wskazują pozycję w ciągu.
feersum

101jest również niejednoznaczny.
feersum

Odpowiedzi:


3

Python 3.6 (wersja wstępna), 199

Zaoszczędź 6 bajtów dzięki 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

Wyjaśnienie i wersja bez golfa:

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.