Analisar uma linguagem 1D

13

Dada uma sequência contendo apenas zeros 1, 2 e colchetes, produza a árvore gramatical da sequência.

A 2requer 2 argumentos - um para a esquerda e outro para a direita

A 1requer um único argumento - à esquerda ou à direita

A 0não requer argumentos e é o caso base

Um par de colchetes conta como um argumento e o conteúdo dos colchetes é avaliado separadamente do restante da string. São possíveis colchetes aninhados

Uma sequência de entrada sempre será uma árvore completa sem caracteres caindo. A cadeia também terá apenas uma única solução correta. Observe que as funções são comutativas e qualquer disposição de argumentos 2será aceitável. Você não precisará manipular entradas que não estejam em conformidade com esses requisitos.

O formato da gramática de saída será no formato function(arguments)recursivo

Casos de teste

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)))
Azul
fonte
É 10201uma entrada válida?
251 Neil
Não, pode ser 1 (2 (0,1 (0))) ou 2 (1 (0), 1 (0))
azul
Na verdade, eu estava pensando que era 1 (2 (1 (0), 0)) ;-)
Neil
1
Ainda não vejo por 0120210que também não pode ser analisado, pois 2[4](2[2](1[1](0[0]), 0[3]), 1[5](0[6]))os números entre colchetes indicam a posição na string.
feersum
101também é ambíguo.
feersum

Respostas:

3

Python 3.6 (pré-lançamento), 199

Economizou 6 bytes graças a 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

Explicação e versão não destruída:

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
fonte