Traversée d'arbre de préfixe


13

Écrire un programme qui prend (via stdin ou ligne de commande) une chaîne au format récursif

PREFIX[SUFFIXES]

  • PREFIX peut être n'importe quelle chaîne de lettres minuscules (az), y compris la chaîne vide, et
  • SUFFIXESpeut être n'importe quelle séquence de chaînes avec la forme récursive PREFIX[SUFFIXES]concaténée ensemble, y compris la séquence vide.

Générez une liste de chaînes en lettres minuscules à partir de l'entrée en évaluant récursivement la liste des chaînes dans chacun des suffixes et en les ajoutant au préfixe. Sortie pour stdout les chaînes de cette liste dans n'importe quel ordre, une par ligne (plus une nouvelle ligne de fin facultative).

Exemple

Si l'entrée est

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

le préfixe est catet et les suffixes sont s[up[][]], [], ch[e[r[]s[]]]et a[maran[]comb[]pult[[]ing[]]]. Chaque suffixe a son propre préfixe et suffixes à son tour.

La sortie serait ces 9 mots dans n'importe quel ordre

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

parce que l'entrée code cet arbre

diagramme d'arbre

et chacun des 9 mots de sortie peut être formé en parcourant l'arbre de la racine à la feuille.

Remarques

  • N'oubliez pas que le préfixe peut être la chaîne vide, donc quelque chose comme

    [donut[][]cruller[]]
    

    est une entrée valide dont la sortie serait (dans n'importe quel ordre)

    donut
    
    cruller
    

    où la ligne vide correspond à la chaîne vide à laquelle correspond le deuxième suffixe.

  • La séquence de suffixes peut également être vide, donc le cas d'entrée trivial

    []
    

    a une seule ligne vide en sortie:

    
    
  • Vous pouvez supposer que l'entrée ne produira que des mots de sortie uniques.
    • par exemple, ce hat[s[]ter[]s[]]serait une entrée non valide car elle hatsest codée deux fois.
    • De même, [[][]]n'est pas valide car la chaîne vide est codée deux fois.
  • Vous ne pouvez pas supposer que l'entrée est aussi courte ou compressée que possible.
    • Par exemple, le 'e'nœud dans l'exemple principal ci-dessus pourrait être combiné avec le 'ch'nœud, mais cela ne signifie pas que l'entrée n'est pas valide.
    • De même, [[[[[]]]]]est valide, malgré l'encodage uniquement de la chaîne vide d'une manière sous-optimale.
  • Au lieu d'un programme, vous pouvez écrire une fonction qui prend la chaîne d'entrée comme argument et imprime la sortie normalement ou la renvoie sous forme de chaîne ou de liste.

Le code le plus court en octets gagne.

Réponses:


2

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

Exemple

Essayez-le: http://ideone.com/NW0CNB

La description

Le programme obtient l'entrée de stdin et renvoie le résultat à stdout.

Il parcourt l'arborescence en conservant la branche courante dans une pile. Il existe également une pile différente, appelée, weightsqui garde la trace du nombre d'enfants de chaque nœud. Cela est nécessaire pour déterminer si un nœud est vraiment une feuille ou s'il a eu des enfants dans le passé.

Le programme lisible:

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

6

Haskell, 125 octets

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 fonction est t(pour la traversée):

λ: 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 "[[[[[]]]]]"
[""]

Votre code est de 124 octets, pas 125 :)
Cristian Lupascu

je pense que le modèle (a,(_:t))peut être à la (a,_:t)place
fier haskeller

2

Java, 206 octets

Définit une fonction qui accepte une chaîne comme argument et renvoie une liste de chaînes. Pour un bonus supplémentaire, il renvoie les chaînes dans le même ordre que la question.

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

Exemple d'utilisation:

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

Étendu:

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

J'ajouterai une explication demain.


0

Python, 212 caractères

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,

J'espérais avoir moins de 200, mais je suis quand même assez content de cela.


0

Javascript ES6, 142 octets

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

0

Q: 70 octets

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

définit une fonction f qui accepte une chaîne et retourne une liste de chaînes (mots)

En tant que lambda (fonction anonyme), nous supprimons les 2 premiers caractères f :, donc la longueur est de 68 octets

Tester

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[]]"

("beignet"; ""; "cruller")

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

, ""

Remarques

, "" indique une liste de chaînes qui contient uniquement une chaîne vide

Les symboles sont atomiques. Pousser / éclater un symbole sur la pile est une opération simple qui n'est pas affectée par la longueur du symbole (voir explication)

Explication

Q est un cousin d'APL (kx.com)

Pseudocode:

  • Divise la chaîne (arg x) à "[" car. Résultat (liste de chaînes) en w
  • Compte les caractères "]" dans chaque élément. de w. Résultat en b
  • Modifie chaque élément de w pour filtrer le caractère "]" et convertit chaque chaîne en symbole
  • Génère une séquence logique (bitmap) pour marquer les éléments> 0 dans b
  • Itère les résultats partiels avec une pile: si l'élément est marqué, nous devons supprimer un ou plusieurs symboles (selon la valeur en b). Toujours ajouter le symbole réel à empiler
  • Après l'itération, nous avons tous les états intermédiaires de la pile. Nous sélectionnons les états précédemment marqués
  • enfin pour chaque résultat, nous convertissons les symboles en chaînes et les concaténons

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

Si le downvoter laissait un commentaire disant ce qui ne va pas, ce serait apprécié.
21urous
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.