Analizza una lingua 1D


13

Dato una stringa contenente solo 0 di 1, 2 e parentesi, genera l'albero grammaticale della stringa.

A 2richiede 2 argomenti: uno a sinistra e uno a destra

A 1richiede un singolo argomento: a sinistra oa destra

A 0non richiede alcun argomento ed è il caso base

Una coppia di parentesi conta come un argomento e il contenuto delle parentesi viene valutato separatamente dal resto della stringa. Le parentesi nidificate sono possibili

Una stringa di input sarà sempre un albero completo senza caratteri che cadono. La stringa avrà anche un'unica soluzione corretta. Si noti che le funzioni sono commutative e qualsiasi accordo per argomenti 2sarà accettabile. Non dovrai gestire input non conformi a questi requisiti.

Il formato grammaticale di output sarà function(arguments)ricorsivamente nella forma

Casi test

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

L' 10201input è valido?
Neil,

No, potrebbe essere 1 (2 (0,1 (0))) o 2 (1 (0), 1 (0))
Blu

In realtà stavo pensando che fosse 1 (2 (1 (0), 0)) ;-)
Neil

1
Continuo a non capire perché 0120210non possa essere analizzato anche 2[4](2[2](1[1](0[0]), 0[3]), 1[5](0[6]))se i numeri tra parentesi indicano la posizione nella stringa.
febbraio

101è anche ambiguo.
feersum

Risposte:


3

Python 3.6 (pre-release), 199

6 byte salvati grazie 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

Spiegazione e versione non registrata:

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