Prefix Tree Traversal

13

Escreva um programa que receba (via stdin ou linha de comando) uma string com a forma recursiva

PREFIX[SUFFIXES]

Onde

  • PREFIX pode ser qualquer sequência de letras minúsculas (az), incluindo a sequência vazia, e
  • SUFFIXESpode ser qualquer sequência de seqüências de caracteres com a forma recursiva PREFIX[SUFFIXES]concatenada em conjunto, incluindo a sequência vazia.

Gere uma lista de cadeias de letras minúsculas a partir da entrada, avaliando recursivamente a lista de cadeias de caracteres em cada um dos sufixos e anexando-as ao prefixo. Saída para stdout as strings nesta lista em qualquer ordem, uma por linha (mais uma nova linha à direita opcional).

Exemplo

Se a entrada for

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

em seguida, o prefixo é cate os sufixos e são s[up[][]], [], ch[e[r[]s[]]], e a[maran[]comb[]pult[[]ing[]]]. Cada sufixo possui seu próprio prefixo e sufixos.

A saída seria essas 9 palavras em qualquer ordem

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

porque a entrada codifica esta árvore

diagrama de árvore

e cada uma das 9 palavras de saída pode ser formada atravessando a árvore da raiz para a folha.

Notas

  • Lembre-se de que o prefixo pode ser a string vazia, então algo como

    [donut[][]cruller[]]
    

    é uma entrada válida cuja saída seria (em qualquer ordem)

    donut
    
    cruller
    

    onde a linha vazia é para a sequência vazia que o segundo sufixo corresponde.

  • A sequência de sufixos também pode estar vazia, portanto, o caso de entrada trivial

    []
    

    tem uma única linha vazia como saída:

    
    
  • Você pode assumir que a entrada produzirá apenas palavras de saída exclusivas.
    • por exemplo, hat[s[]ter[]s[]]seria uma entrada inválida porque hatsé codificada duas vezes.
    • Da mesma forma, [[][]]é inválido porque a cadeia vazia é codificada duas vezes.
  • Você não pode presumir que a entrada seja a mais curta ou compactada possível.
    • por exemplo, o 'e'nó no exemplo principal acima pode ser combinado com o 'ch'nó, mas isso não significa que a entrada seja inválida.
    • Da mesma forma, [[[[[]]]]]é válido, apesar de codificar apenas a sequência vazia de uma maneira subótima.
  • Em vez de um programa, você pode escrever uma função que pega a string de entrada como argumento e imprime a saída normalmente ou a retorna como uma string ou lista.

O código mais curto em bytes vence.

Passatempos de Calvin
fonte

Respostas:

2

Rubi, 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}

Exemplo

Experimente: http://ideone.com/NW0CNB

Descrição

O programa obtém a entrada de stdin e gera o resultado em stdout.

Atravessa a árvore, mantendo o ramo atual em uma pilha. Há também uma pilha diferente, chamadaweights que monitora o número de filhos de cada nó. Isso é necessário para determinar se um nó é realmente uma folha ou se teve filhos no passado.

O programa legível:

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

A função é t(para travessia):

λ: 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
fonte
Seu código é de 124 bytes, não 125 :)
Cristian Lupascu
Eu acho que o padrão (a,(_:t))pode ser em (a,_:t)vez disso
proud haskeller
2

Java, 206 bytes

Define uma função que aceita uma string como argumento e retorna uma lista de strings. Para um bônus adicional, ele retorna as strings na mesma ordem que a pergunta.

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;}

Exemplo 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;
}

Vou adicionar uma explicação amanhã.

O número um
fonte
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,

Eu esperava ter menos de 200 anos, mas ainda estou muito feliz com isso.

Loovjo
fonte
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
fonte
0

Q: 70 bytes

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

define uma função f que aceita uma string e retorna uma lista de strings (palavras)

Como lambda (função anônima), eliminamos os 2 primeiros caracteres f :, então o comprimento é de 68 bytes

Teste

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

("ketchup"; "cats"; "cat"; "catcher"; "catchs"; "catamaran"; "catacomb"; "catapult"; "catapulting")

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

("rosquinha"; ""; "cruller")

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

, ""

Notas

, "" indica uma lista de cadeias que contém apenas uma cadeia vazia

Símbolos são atômicos. Pressionar / estourar um símbolo na pilha é uma operação simples, não afetada pelo comprimento do símbolo (consulte a explicação)

Explicação

Q é um primo da APL (kx.com)

Pseudo-código:

  • Divide a string (arg x) no caractere "[". Resultado (lista de strings) em w
  • Conta "]" caracteres em cada elem. de w. Resultar em b
  • Modifica cada item em w para filtrar o caractere "]" e converte cada sequência em um símbolo
  • Gera uma sequência lógica (bitmap) para marcar itens> 0 em b
  • Repete os resultados parciais com uma pilha: se o item estiver marcado, devemos soltar um ou mais símbolos (de acordo com o valor em b). Anexe sempre o símbolo real à pilha
  • Após a iteração, temos todos os estados intermediários da pilha. Selecionamos estados marcados anteriormente
  • finalmente, para cada resultado, convertemos símbolos em strings e os concatenamos
J. Sendra
fonte
-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''
Furioso
fonte
Se o downvoter deixasse um comentário dizendo o que há de errado nisso, isso seria apreciado.
Οurous