プレフィックスツリートラバーサル


13

(stdinまたはコマンドラインを介して)再帰形式の文字列を取り込むプログラムを作成します。

PREFIX[SUFFIXES]

どこ

  • PREFIX 空の文字列を含む、小文字(az)の任意の文字列を指定できます。
  • SUFFIXESPREFIX[SUFFIXES]空のシーケンスを含む、再帰形式が連結された任意の文字列シーケンスです。

各サフィックスの文字列のリストを再帰的に評価してプレフィックスに追加することにより、入力から小文字の文字列のリストを生成します。このリスト内の文字列を任意の順序で、1行に1つずつ(およびオプションの末尾の改行も)標準出力します。

入力が

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

その後、接頭辞があるcatとし、接尾辞はs[up[][]][]ch[e[r[]s[]]]、とa[maran[]comb[]pult[[]ing[]]]。各サフィックスには、独自のプレフィックスとサフィックスが順番にあります。

出力は、これらの9ワードで任意の順序になります

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

入力はこのツリーをエンコードするため

樹形図

そして、9つの出力ワードのそれぞれは、ルートからリーフへツリーを走査することによって形成できます。

ノート

  • プレフィックスは空の文字列である可能性があることに注意してください。

    [donut[][]cruller[]]
    

    出力が(任意の順序で)有効な入力です

    donut
    
    cruller
    

    空の行は、2番目のサフィックスが一致する空の文字列です。

  • 接尾辞シーケンスも空にすることができるため、些細な入力の場合

    []
    

    出力として単一の空行があります:

    
    
  • 入力は一意の出力ワードのみを生成すると想定できます。
    • たとえば、2回エンコードされるhat[s[]ter[]s[]]ため、無効な入力になりますhats
    • 同様に、[[][]]空の文字列が2回エンコードされるため、無効です。
  • 入力が可能な限り短い、または圧縮されていると想定することはできません
    • たとえば、'e'上記の主な例の'ch'ノードはノードと組み合わせることができますが、それは入力が無効であることを意味しません。
    • 同様に、[[[[[]]]]]空の文字列を次善の方法でエンコードしているにもかかわらず、有効です。
  • プログラムの代わりに、入力文字列を引数として受け取り、出力を通常どおり印刷するか、文字列またはリストとして返す関数を作成できます。

バイト単位の最短コードが優先されます。

回答:


2

ルビー、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}

試してください:http : //ideone.com/NW0CNB

説明

プログラムは、stdinから入力を取得し、結果をstdoutに出力します。

現在のブランチをスタックに保持したままツリーを走査します。またweights、各ノードの子の数を追跡する別のスタックがあります。これは、ノードが実際にリーフであるか、過去に子がいたかを判断するために必要です。

読み取り可能なプログラム:

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バイト

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

関数はt(トラバーサル用)です:

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

あなたのコードは125バイトではなく、124バイトです:)
クリスチャンルパスク

パターン(a,(_:t))(a,_:t)代わりにできると思います
誇りに思っているhaskeller

2

Java、206バイト

引数として文字列を受け取り、文字列のリストを返す関数を定義します。追加のボーナスについては、質問と同じ順序で文字列を返します。

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

使用例:

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

拡張:

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

明日説明を追加します。


0

Python、212文字

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,

私は200未満になりたいと思っていましたが、それでもかなり満足しています。


0

Javascript ES6、142バイト

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バイト

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

文字列を受け入れ、文字列(単語)のリストを返す関数fを定義します

ラムダ(匿名関数)として、最初の2文字f:を削除するため、長さは68バイトになります

テスト

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

( "ドーナツ"; ""; "クローラー")

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

、 ""

ノート

、 ""は、空の文字列のみを含む文字列のリストを示します

シンボルはアトミックです。スタック上のシンボルのプッシュ/ポップは、シンボルの長さの影響を受けない単純な操作です(説明を参照)

説明

QはAPLのいとこです(kx.com)

擬似コード:

  • 文字列(arg x)を「[」文字で分割します。wの結果(文字列のリスト)
  • 各elemの「]」文字をカウントします。wの bの結果
  • wの各項目を変更して文字「]」を除外し、各文字列を記号に変換します
  • 論理シーケンス(ビットマップ)を生成して、bの項目> 0をマークします
  • 部分的な結果をスタックで繰り返します:マークされたアイテムがある場合、1つ以上のシンボルをドロップする必要があります(bの値に従って)。常に実際のシンボルをスタックに追加します
  • 反復後、スタックのすべての中間状態が得られます。以前にマークされた状態を選択します
  • 最後に、結果ごとにシンボルを文字列に変換し、それらを連結します

-1

コブラ-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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.