Prefisso Traversal Tree


13

Scrivi un programma che accetta (tramite stdin o riga di comando) una stringa con il modulo ricorsivo

PREFIX[SUFFIXES]

dove

  • PREFIX può essere una qualsiasi stringa di lettere minuscole (az), inclusa la stringa vuota, e
  • SUFFIXESpuò essere qualsiasi sequenza di stringhe con la forma ricorsiva PREFIX[SUFFIXES]concatenata insieme, inclusa la sequenza vuota.

Genera un elenco di stringhe con lettere minuscole dall'input valutando ricorsivamente l'elenco di stringhe in ciascuno dei suffissi e aggiungendole al prefisso. Output per stdout le stringhe in questo elenco in qualsiasi ordine, una per riga (più una nuova riga finale facoltativa).

Esempio

Se l'ingresso è

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

poi il prefisso è cate ed i suffissi sono s[up[][]], [], ch[e[r[]s[]]], e a[maran[]comb[]pult[[]ing[]]]. Ogni suffisso ha il proprio prefisso e suffissi a turno.

L'output sarebbe di queste 9 parole in qualsiasi ordine

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

perché l'input codifica questo albero

Diagramma ad albero

e ciascuna delle 9 parole in uscita può essere formata attraversando l'albero da radice a foglia.

Appunti

  • Ricorda che il prefisso può essere la stringa vuota, quindi qualcosa di simile

    [donut[][]cruller[]]
    

    è un input valido il cui output sarebbe (in qualsiasi ordine)

    donut
    
    cruller
    

    dove la riga vuota è per la stringa vuota che corrisponde al secondo suffisso.

  • La sequenza dei suffissi può anche essere vuota, quindi il banale caso di input

    []
    

    ha una sola riga vuota come output:

    
    
  • Si può presumere che l'input produrrà solo parole di output univoche.
    • ad es. hat[s[]ter[]s[]]sarebbe un input non valido perché hatsè codificato due volte.
    • Allo stesso modo, [[][]]non è valido perché la stringa vuota viene codificata due volte.
  • Si può non dare per scontato che l'ingresso è il più breve o compresso il più possibile.
    • ad esempio il 'e'nodo nell'esempio principale sopra potrebbe essere combinato con il 'ch'nodo, ma ciò non significa che l'input non sia valido.
    • Allo stesso modo, [[[[[]]]]]è valido, nonostante codifica solo la stringa vuota in modo non ottimale.
  • Invece di un programma è possibile scrivere una funzione che accetta la stringa di input come argomento e stampa l'output normalmente o lo restituisce come stringa o elenco.

Vince il codice più breve in byte.

Risposte:


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}

Esempio

Provalo: http://ideone.com/NW0CNB

Descrizione

Il programma ottiene l'input da stdin e invia il risultato a stdout.

Attraversa l'albero mantenendo il ramo corrente in una pila. C'è anche uno stack diverso, chiamato weightsche tiene traccia del numero di figli di ciascun nodo. Ciò è necessario per determinare se un nodo è davvero una foglia o se in passato aveva figli.

Il programma leggibile:

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 byte

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 funzione è t(per l'attraversamento):

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

Il tuo codice è di 124 byte, non 125 :)
Cristian Lupascu,

penso che il modello (a,(_:t))possa essere (a,_:t)invece
orgoglioso haskeller il

2

Java, 206 byte

Definisce una funzione che accetta una stringa come argomento e restituisce un elenco di stringhe. Per un bonus aggiuntivo restituisce le stringhe nello stesso ordine della domanda.

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

Esempio di utilizzo:

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

Allargato:

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

Aggiungerò una spiegazione domani.


0

Python, 212 caratteri

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,

Speravo di ottenere meno di 200, ma sono ancora abbastanza contento di questo.


0

Javascript ES6, 142 byte

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 byte

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

definisce una funzione f che accetta una stringa e restituisce un elenco di stringhe (parole)

Come lambda (funzione anonima) eliminiamo i primi 2 caratteri f :, quindi la lunghezza è di 68 byte

Test

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

( "Ketchup"; "gatti", "gatto", "Catcher", "catture", "catamarano"; "catacomba", "catapulta", "catapultando")

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

( "Ciambella"; ""; "cruller")

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

, ""

Appunti

, "" indica un elenco di stringhe che contiene solo una stringa vuota

I simboli sono atomici. Spingere / far apparire un simbolo in pila è una semplice operazione non influenzata dalla lunghezza del simbolo (vedi spiegazione)

Spiegazione

Q è cugino di APL (kx.com)

pseudocodice:

  • Divide la stringa (arg x) nel carattere "[". Risultato (elenco di stringhe) in w
  • Conta "]" caratteri in ogni elemento. di w. Risultato in b
  • Modifica ogni elemento in w per filtrare il carattere "]" e converte ogni stringa in un simbolo
  • Genera una sequenza logica (bitmap) per contrassegnare gli elementi> 0 in b
  • Scorre i risultati parziali con una pila: se l'oggetto marcato dobbiamo far cadere uno o più simboli (secondo il valore in b). Aggiungi sempre il simbolo reale allo stack
  • Dopo l'iterazione abbiamo tutti gli stati intermedi di stack. Selezioniamo stati precedentemente contrassegnati
  • infine per ogni risultato convertiamo i simboli in stringhe e li concateniamo

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

Se il downvoter lasciasse un commento dicendo ciò che non va in questo, sarebbe apprezzato.
Augurous
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.