二分木の高さを計算する最短プログラムを書く


18

二分木の高さは、ルートノードからルートから最も遠いノードの子までの距離です。

以下に例を示します。

           2 <-- root: Height 1
          / \
         7   5 <-- Height 2
        / \   \
       2   6   9 <-- Height 3
          / \  /
         5  11 4 <-- Height 4 

バイナリツリーの高さ:4

二分木の定義

ツリーは、符号付き整数値と、他の2つのツリーまたはそれらへのポインターを含むオブジェクトです。

二分木構造体の構造は次のようになります。

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;

チャレンジ:

入力

二分木の根

出力

二分木の高さを表す数

入力としてバイナリツリーのルートが与えられたと仮定して、バイナリツリーの高さを計算して高さを返す最短のプログラムを作成します。最小バイト数(空白を含む)のプログラムが優先されます。


4
ポインターのない言語は何をしますか?
ジョナサンアラン

4
...しかし、私のツリーオブジェクトはプロパティを持つことができますh。この課題のために、リストだけで構成された特定の構造を定義する方が良いかもしれません。
ジョナサンアラン

11
@ T.Salim将来的には、まずサンドボックスに投稿することを検討してください。
wizzwizz4

1
では、有効な表現は長さ3のリストで[root_value, left_node, right_node]あり、ここでleft_nodeおよびright_nodeはそれぞれ二分木も受け入れ可能ですか?多くの言語では簡単ですが、他の言語では楽しいかもしれません。
ジョナサンアラン

3
有効なバイナリ構造を構成するものを含めるように質問を編集できますか?おそらくのような定義a tree is an object that contains a value and either two other trees or pointers to them。オブジェクトのない言語を含む定義もいいでしょう。
ジョーキング

回答:


11

ゼリー、3 バイト

ŒḊ’

tree:を表すリストを受け入れるモナドリンク[root_value, left_tree, right_tree]。ここで、left_treeおよびright_treeは類似の構造(必要な場合は空)であり、高さを生成します。

オンラインでお試しください!

どうやって?

ゼリーではかなり簡単です:

ŒḊ’ - Link: list, as described above
ŒḊ  - depth
  ’ - decremented (since leaves are `[value, [], []]`)

Jonathon Allen、それはあなたが使用している興味深い言語です。新規参入者として、ゼリーの使用方法を指導するリンクまたはWebサイトの紹介を提供できますか?
T.サリム

4
ヘッダーのリンクをクリックします。これは、サイトのモデレーターの1人であるDennisが開発したゴルフ言語です。
ジョナサンアラン

2
...のx代わりに葉を表現することは、どのように議論されるのだろうか?[x, [], []]
Erik the Outgolfer

@EriktheOutgolfer質問の「ポインタ」と「構造」の性質を維持するには、すべてのノードが同じ形式である必要があると思います。
ジョナサンアラン

10

Python 2 35の  33バイト

見落としに気づき、節約したArnauldに感謝します4。

f=lambda a:a>[]and-~max(map(f,a))

ツリーを表すリストを受け入れる再帰関数:[root_value, left_tree, right_tree]、各left_treeおよびright_treeはそれぞれ類似した構造(必要に応じて空)であり、高さを返します。

オンラインでお試しください!

[]が返りますFalseが、Pythonでは注意してくださいFalse==0


同じ人が同じ質問に対して2つの異なる回答をすることは許可されていますか?
T.サリム

6
ええ、もちろん、ゴルフは言語レベルでの競争です。アプローチが非常に異なる場合、同じ言語の2番目のエントリでさえ許容される場合があります。
ジョナサンアラン

@Arnauldはそう推測します(何らかの理由で非整数が存在する可能性があると想定していました)
Jonathan Allan


6

Perl 6、25バイト

{($_,{.[*;*]}...*eqv*)-2}

入力は3要素リスト(l, r, v)です。空のツリーは空のリストです。

オンラインでお試しください!

説明

{                       }  # Anonymous block
    ,        ...  # Sequence constructor
  $_  # Start with input
     {.[*;*]}  # Compute next element by flattening one level
               # Sadly *[*;*] doesn't work for some reason
                *eqv*  # Until elements doesn't change
 (                   )-2  # Size of sequence minus 2

古いソリューション、30バイト

{+$_&&1+max map &?BLOCK,.[^2]}

オンラインでお試しください!


この&?BLOCKトリックは興味深いものですが、ブロックを$に割り当てるには数バイト短くなります
ジョーキング

@JoKingわかりません。チャレンジソリューションを揮発性のグローバルな場所に保存し$!たり$/、私にごまかしたりします。
nwellnhof

(Ab)$!などの変数を使用する また、$ /はゴルフP6のかなり標準的な方法です。
user0721090601

6

05AB1E11 7 5 バイト

Δ€`}N

@ExpiredDataのおかげで-4バイト。@Grimyの
おかげで-2バイト。

入力形式は、Jellyの答え:tree:を表すリストに似ています。[root_value, left_tree, right_tree]ここで、left_treeおよびright_treeはそれぞれ類似した構造です(オプションで空)。すなわち[2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]]チャレンジ記述からツリーを表します。

オンラインそれを試してみたり、さらにいくつかのテストケースを検証します

説明:

Δ     # Loop until the (implicit) input-list no longer changes:
  €`  #  Flatten the list one level
}N    # After the loop: push the 0-based index of the loop we just finished
      # (which is output implicitly as result)

05AB1Eは0から始まりますが、変更ループΔは出力インデックスを修正します。これは、変更されていないことを確認するために追加の反復が必要なためです。



@ExpiredDataああ、もちろん。ありがとう。:)
ケビンクルーッセン


@Grimyループ外でインデックスを使用すると、レガシーコードでしか機能しないと思った。:Sありがとう!
ケビンクルーッセン

5

JavaScript(ES6)、 35  33バイト

入力構造: [[left_node], [right_node], value]

f=([a,b])=>a?1+f(f(a)>f(b)?a:b):0

オンラインでお試しください!

コメント済み

f =                       // f is a recursive function taking
([a, b]) =>               // a node of the tree split into
                          // a[] = left child, b[] = right child (the value is ignored)
  a ?                     // if a[] is defined:
    1 +                   //   increment the final result for this branch
    f(                    //   and add:
      f(a) > f(b) ? a : b //     f(a) if f(a) > f(b) or f(b) otherwise
    )                     //
  :                       // else:
    0                     //   stop recursion and return 0

でバイトを保存できるようですa&&-~
シャギー

1
@Shaggyそれはundefinedとの比較につながります。
アーナウド

4

C、43バイト

h(T*r){r=r?1+(int)fmax(h(r->l),h(r->r)):0;}

バイナリツリーの構造は次のとおりです。

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;


1
@ErikFまたは45バイト
Arnauld


3
提出がフラグに依存している場合、提出のヘッダーにフラグを追加してください。
ジョーキング

1
@nwellnhof 42バイトで
ceilingcat

4

JavaScript(Node.js)、32バイト

f=a=>/,,/.test(a)&&f(a.flat())+1

オンラインでお試しください!

またはのflat代わりに名前を使用することは、コードゴルフでは素晴らしいアイデアです。flattensmoosh

[]ツリーのnullノード、およびノー​​ドに使用します[left, right, value]valueこれは整数です。



3

Haskell、28バイト

次のデータ定義を使用します。

data T a = (:&) a [T a]

高さは次のとおりです。

h(_:&x)=foldr(max.succ.h)0 x

2

スキーム、72バイト

(define(f h)(if(null? h)0(+ 1(max(f(car(cdr h)))(f(car(cdr(cdr h))))))))

より読みやすいバージョン:

(define (f h)
   (if (null? h)
      0
      (+ 1 
         (max
             (f (car (cdr h)))
             (f (car (cdr (cdr h))))
         )
      )
   )
)

フォームのリスト(データ、左、右)を使用してツリーを表します。例えば

   1
  / \
  2  3
 /\
 4 5

is represented as: (1 (2 (4 () ()) (5 () ())) (3 () ())

(1
   (2
      (4 () ())
```   (5 () ())
   (3 () ())
)

オンラインでお試しください!


2

R、51バイト

function(L){while(is.list(L<-unlist(L,F)))T=T+1;+T}

オンラインでお試しください!

  • 入力:形式のネストされたリスト:list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • アルゴリズム:平坦なベクトルになるまで、ツリーを1レベルずつ繰り返し平坦化します。繰り返し回数は最大深度に対応します。

@KevinCruijssenソリューションに触発


再帰的な代替:

R、64バイト

`~`=function(L,d=0)'if'(is.list(L),max(L[[2]]~d+1,L[[3]]~d+1),d)

オンラインでお試しください!

関数/演算子'~'を再定義して、リスト構造に格納されているツリーの最大深さを計算できるようにします。

ツリーのリスト構造の形式は次のとおりです。 list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • -2 @Giuseppeに感謝

なぜあなたは使用しないd=1当時とd-1終わり?で始められませんでした0か?
ジュゼッペ

また、私は切り替え>~ ここでテストケースを入力するのが容易になるよう
ジュゼッペ・

@ジュゼッペ:もちろん...私は明らかな🤦‍♂️が欠けていました
digEmAll


1

K(ngn / k)、4バイト

解決:

#,/\

オンラインでお試しください!

説明:

ポイントを逃したのではないかと思います。

ツリーを3項目リスト(親ノード、左子、右子)として表すと、例は次のように表すことができます。

(2;
  (7;
    (,2);
    (6;
      (,5);
      (,11)
    )
  );
  (5;
    ();
    (9;
      (,4);
      ()
    )
  )
)

または:(2;(7;(,2);(6;(,5);(,11)));(5;();(9;(,4);())))

そのため、解決策は、繰り返しフラット化して、繰り返しをカウントすることです。

#,/\ / the solution
   \ / iterate
 ,/  / flatten
#    / count

0

、29バイト

⊞θ⁰⊞υθFυ«≔⊕⊟ιθFΦι∧κλ⊞υ⊞Oκθ»Iθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。処理中に一時的にツリーを変更します。説明:

⊞θ⁰

ゼロをルートノードにプッシュします。

⊞υθ

ルートノードをすべてのノードのリストにプッシュします。

Fυ«

ツリーの幅優先検索を実行します。

≔⊕⊟ιθ

このノードの深さを取得します。

FΦι∧κλ

子ノードをループします。

⊞υ⊞Oκθ

子ノードに親の深さを伝え、すべてのノードのリストにプッシュします。

»Iθ

すべてのノードを走査したら、最後のノードの深さを出力します。トラバースは幅優先であったため、これはツリーの高さになります。


0

スタックス、5 バイト

▐▌µ╡⌂

実行してデバッグする

StaxにはポインターもNULL値もないため、入力をのように表します[2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]]。たぶんそれは不公平な利点かもしれませんが、私が得ることができる最も近いものでした。

解凍、コメントなし、コメント付きで、コードは次のようになります。

        The input starts on top of the input stack
Z       Tuck a zero underneath the top value in the stack.  Both values end up on the main stack.
D       Drop the first element from array
F       For each remaining element (the leaves) run the rest of the program
  G^    Recursively call the entire program, then increment
  T     Get maximum of the two numbers now ow the stack

これを実行する


0

Kotlin、45バイト

val Tree.h:Int get()=1+maxOf(l?.h?:0,r?.h?:0)

次のクラスが定義されていると仮定します

class Tree(var v: Int, var l: Tree? = null, var r: Tree? = null)

オンラインで試す


0

ジュリア、27バイト

f(t)=t≢()&&maximum(f,t.c)+1

バイナリツリーを表す次の構造体:

struct Tree
    c::NTuple{2,Union{Tree,Tuple{}}}
    v::Int
end

cは左右のノードを表すタプルで、空のタプル()はノードが存在しないことを通知するために使用されます。


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