Recorrido del árbol de prefijo

13

Escriba un programa que tome (a través de stdin o línea de comando) una cadena con la forma recursiva

PREFIX[SUFFIXES]

dónde

  • PREFIX puede ser cualquier cadena de letras minúsculas (az), incluida la cadena vacía, y
  • SUFFIXESpuede ser cualquier secuencia de cadenas con la forma recursiva PREFIX[SUFFIXES]concatenada, incluida la secuencia vacía.

Genere una lista de cadenas con letras minúsculas a partir de la entrada evaluando recursivamente la lista de cadenas en cada uno de los sufijos y agregándolas al prefijo. Salida para stdout las cadenas en esta lista en cualquier orden, una por línea (más una nueva línea final opcional).

Ejemplo

Si la entrada es

cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]

a continuación, el prefijo es caty y los sufijos son s[up[][]], [], ch[e[r[]s[]]], y a[maran[]comb[]pult[[]ing[]]]. Cada sufijo tiene su propio prefijo y sufijos a su vez.

La salida sería estas 9 palabras en cualquier orden

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

porque la entrada codifica este árbol

diagrama de árbol

y cada una de las 9 palabras de salida se puede formar atravesando el árbol de raíz a hoja.

Notas

  • Recuerde que el prefijo puede ser la cadena vacía, así que algo así como

    [donut[][]cruller[]]
    

    es una entrada válida cuya salida sería (en cualquier orden)

    donut
    
    cruller
    

    donde la línea vacía es para la cadena vacía que coincide con el segundo sufijo.

  • La secuencia de sufijo también puede estar vacía, por lo que el caso de entrada trivial

    []
    

    tiene una sola línea vacía como salida:

    
    
  • Puede suponer que la entrada solo producirá palabras de salida únicas.
    • por ejemplo, hat[s[]ter[]s[]]sería una entrada no válida porque hatsse codifica dos veces.
    • Del mismo modo, [[][]]no es válido porque la cadena vacía se codifica dos veces.
  • Es posible que no se supone que la entrada sea lo más corta o se comprime como sea posible.
    • por ejemplo, el 'e'nodo en el ejemplo principal anterior podría combinarse con el 'ch'nodo, pero eso no significa que la entrada no sea válida.
    • Del mismo modo, [[[[[]]]]]es válido, a pesar de solo codificar la cadena vacía de una manera subóptima.
  • En lugar de un programa, puede escribir una función que tome la cadena de entrada como argumento e imprima la salida normalmente o la devuelva como una cadena o lista.

El código más corto en bytes gana.

Pasatiempos de Calvin
fuente

Respuestas:

2

Ruby, 119 115

t=['']
l=[0]
gets.chars{|c|c<?]?t<<''&&(l<<0)[-2]+=1:c<?^?(x=l.pop;t.pop==''&&(puts t*''if x<1;t[-1]='')):t[-1]<<c}

Ejemplo

Pruébalo: http://ideone.com/NW0CNB

Descripción

El programa obtiene la entrada de stdin y genera el resultado en stdout.

Atraviesa el árbol manteniendo la rama actual en una pila. También hay una pila diferente, llamada weightsque realiza un seguimiento de la cantidad de hijos de cada nodo. Esto es necesario para determinar si un nodo es realmente una hoja o si tuvo hijos en el pasado.

El programa legible:

stack = ['']
weights = [0]

gets.chars do |c|
  case c
  when '['
    weights[-1] += 1
    stack << ''
    weights << 0
  when ']'
    last_weight = weights.pop

    if stack.pop == ''
      puts stack.join if last_weight < 1
      stack[-1] = ''
    end
  else
    stack[-1] << c
  end
end
Cristian Lupascu
fuente
6

Haskell, 125 bytes

t=tail.p
p=g.break(=='[')
g(a,(_:t))=(:)&(map(a++).z)$t#[]
z[]=[""];z x=x
(']':u)#a=u:a
s#a=(#)&(a++)$p s
(g&f)(x:y)=g x$f y

La función es t(para atravesar):

λ: t "cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"
["catsup","cats","cat","catcher","catches","catamaran","catacomb","catapult","catapulting"]
λ: t "[donut[][]cruller[]]"
["donut","","cruller"]
λ: t "[[[[[]]]]]"
[""]
MtnViewMark
fuente
Su código es de 124 bytes, no de 125 :)
Cristian Lupascu
Creo que el patrón (a,(_:t))puede ser (a,_:t)en su lugar
Haskeller orgulloso
2

Java, 206 bytes

Define una función que acepta una cadena como argumento y devuelve una lista de cadenas. Para obtener una bonificación adicional, devuelve cadenas en el mismo orden que la pregunta.

int c,i;List a(String a){String b=a.substring(c,c=a.indexOf(91,c));List d=new ArrayList();for(;a.charAt(++c)!=93;)d.addAll(a(a));if(d.isEmpty())d.add("");for(i=0;i<d.size();)d.set(i,b+d.get(i++));return d;}

Ejemplo de uso:

class A{
    public static void main(String[] args){
        System.out.println(new A.a("cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"));
    }

    int c,i;List a(String a){String b=a.substring(c,c=a.indexOf(91,c));List d=new ArrayList();for(;a.charAt(++c)!=93;)d.addAll(a(a));if(d.isEmpty())d.add("");for(i=0;i<d.size();)d.set(i,b+d.get(i++));return d;}
}

Expandido:

int c, i;
List a(String a){
    String b = a.substring(c, c = a.indexOf(91, c));
    List d = new ArrayList();
    for(; a.charAt(++c) != 93 ;)
        d.addAll(a(a));
    if (d.isEmpty())
        d.add("");
    for (i = 0; i < d.size();)
        d.set(i, b + d.get(i++));
    return d;
}

Agregaré una explicación mañana.

El numero uno
fuente
0

Python, 212 caracteres

def p(t,f="",o="",d=0):
 if[]==t:return
 b=[""]
 for c in t:d+=c=="[";b[-1]+=c;d-=c=="]";b+=[""]*(d==0)*(c=="]")
 for r in b[:-1]:i=r.index("[");w,s=f+r[:i],r[i:][1:-1];p(s,w);o+= ["",w+"\n"][""==s]
  if o:print o,

Esperaba llegar a menos de 200, pero aún así estoy bastante feliz con esto.

Loovjo
fuente
0

Javascript ES6, 142 bytes

s=>(o=[],x=_=>s[0]==']'?s=s.slice(1):0,(g=d=>{while(s&&!x())[o[d],s]=s.split(/\[(.*)/).concat``,x()?console.log(o.join``):g(d+1),o.pop()})(0))
Dendrobium
fuente
0

Q: 70 bytes

f:{,/'$({(z_x),y}\[();{`$x@&~x="]"}'w;-b])@-1+&0<b:(+/"]"=)'w:"["\:x}

define una función f que acepta una cadena y devuelve una lista de cadenas (palabras)

Como lambda (función anónima) soltamos los primeros 2 caracteres f :, entonces la longitud es 68 Bytes

Prueba

f "cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"

("catsup"; "cats"; "cat"; "catcher"; "catches"; "catamaran"; "catacomb"; "catapult"; "catapulting")

f "[donut[][]cruller[]]"

("donut"; ""; "cruller")

f "[[[[[]]]]]"

, ""

Notas

, "" indica que una lista de cadenas que contiene solo tiene una cadena vacía

Los símbolos son atómicos. Empujar / hacer estallar un símbolo en la pila es una operación simple que no se ve afectada por la longitud del símbolo (ver explicación)

Explicación

Q es primo de APL (kx.com)

Pseudocódigo:

  • Divide la cadena (arg x) en "[" char. Resultado (lista de cadenas) en w
  • Cuenta los caracteres "]" en cada elemento. de w. Resultado en b
  • Modifica cada elemento en w para filtrar el carácter "]" y convierte cada cadena en un símbolo
  • Genera una secuencia lógica (mapa de bits) para marcar elementos> 0 en b
  • Itera los resultados parciales con una pila: si el elemento marcado debemos soltar uno o más símbolos (de acuerdo con el valor en b). Siempre agregue el símbolo real para apilar
  • Después de iterar, tenemos todos los estados intermedios de la pila. Seleccionamos estados previamente marcados
  • finalmente para cada resultado convertimos símbolos en cadenas y los concatenamos
J. Sendra
fuente
-1

Cobra - 181

def f(s='')as String*
    for m in RegularExpressions.Regex.matches(s,r'(\w*)\[((?:(?<B>\[)|\w|(?<-B>]))*)](?(B)(?!))'),for r in.f('[(u=m.groups)[2]]'),yield'[u[1]]'+r
    if''==s,yield''
Οurous
fuente
Si el votante dejara un comentario diciendo qué está mal con esto, eso sería apreciado.
2015