이진 트리의 높이를 계산하는 가장 짧은 프로그램 작성


18

이진 트리의 높이는 루트 노드에서 루트에서 가장 먼 노드 자식까지의 거리입니다.

아래는 예입니다.

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

이진 트리의 높이 : 4

이진 트리의 정의

트리는 부호있는 정수 값과 다른 두 개의 트리 또는 포인터를 포함하는 객체입니다.

이진 트리 구조체의 구조는 다음과 같습니다.

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;

도전 과제 :

입력

이진 트리의 루트

산출

이진 트리의 높이를 나타내는 숫자

이진 트리의 루트가 입력으로 주어 졌다고 가정하면 이진 트리의 높이를 계산하고 높이를 반환하는 가장 짧은 프로그램을 작성하십시오. 바이트 수가 가장 적은 프로그램 (공백 공백)이 이깁니다.


4
포인터가없는 언어는 무엇을 사용합니까?
Jonathan Allan

4
...하지만 내 트리 객체는 속성을 가질 수 있습니다 h. 이 도전의 목적을 위해 목록으로 구성된 특정 구조를 정의하는 것이 좋습니다.
Jonathan Allan

11
@ T.Salim 앞으로 샌드 박스에 게시하는 것을 고려하십시오 .
wizzwizz4

1
따라서, 올바른 표현은 길이 3의 목록입니다 [root_value, left_node, right_node]각각의 경우 left_node와는 right_node이진 트리가 허용도 있습니까? 많은 언어에서 사소한 것이지만 다른 언어에서는 재미있을 수 있습니다.
Jonathan Allan

3
유효한 이진 구조를 구성하는 것을 포함하도록 질문을 편집 할 수 있습니까? 아마도 같은 정의 a tree is an object that contains a value and either two other trees or pointers to them입니다. 객체가없는 언어를 포함하는 정의도 좋습니다.
Jo King

답변:


11

젤리 , 3 바이트

ŒḊ’

트리를 나타내는 목록을 받아들이는 모나드 링크 : [root_value, left_tree, right_tree], 각각의 경우 left_tree와는 right_tree유사한 구조가 (필요가있을 경우 비어 있음), 높이를 산출한다.

온라인으로 사용해보십시오!

어떻게?

젤리에서 아주 사소한 :

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

Jonathon Allen, 이것은 당신이 사용하고있는 흥미로운 언어입니다. 새로 온 사람으로서 사람들에게 젤리 사용법을 가르치는 링크 나 웹 사이트 소개를 제공 할 수 있습니까?
T. Salim

4
헤더의 링크를 클릭하십시오 . 사이트의 중재자 중 하나 인 Dennis가 개발 한 골프 언어입니다 .
Jonathan Allan

2
나는 x대신에 잎을 나타내는 것이 얼마나 논란이 될지 궁금합니다 [x, [], []].
Erik the Outgolfer

@EriktheOutgolfer 질문의 "포인터"와 "구조"특성을 유지하려면 모든 노드가 동일한 형식이어야한다고 생각합니다.
Jonathan Allan

10

파이썬 2 ,  35  33 바이트

감독과 비용 절감을 알리는 Arnauld에게 감사드립니다.

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

트리를 나타내는 목록을 받아들이는 재귀 함수 : [root_value, left_tree, right_tree], 각각의 경우 left_tree와는 right_tree유사한 구조가 (필요가있을 경우 비어 있음), 높이를 반환합니다.

온라인으로 사용해보십시오!

참고 []반환 False하지만, 파이썬 False==0.


같은 사람이 같은 질문에 대해 서로 다른 두 가지 대답을 할 수 있습니까?
T. Salim

6
물론 골프는 언어 수준의 경쟁입니다. 접근 방식이 매우 다른 경우 같은 언어로 된 두 번째 항목조차도 허용됩니다.
Jonathan Allan

@Arnauld 추측 (그래서 나는 어떤 이유가 아닌 경우 비 정수자가 있다고 가정했을 것입니다)
Jonathan Allan


6

펄 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트릭은 재미있다하지만 A의 짧은 바이트의 몇 $에 블록을 할당 할!
Jo King

@JoKing 몰라요. 챌린지 솔루션을 휘발성 글로벌에 저장 $!하거나 $/바람 피우는 것처럼 느낍니다.
nwellnhof

(Ab) $!와 같은 변수 사용 그리고 $ /는 골프 P6의 표준 연습입니다.
user0721090601

6

05AB1E , 11 7 5 바이트

Δ€`}N

덕분에 -4 바이트 @ExpiredData . @Grimy
덕분에 -2 바이트 .

입력 형식은 젤리 답변과 비슷합니다 : 트리를 나타내는 목록 : [root_value, left_tree, right_tree] 여기서 각 left_treeright_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을 기반으로하지만 changes-loop Δ는 더 이상 변경되지 않는지 확인하기 위해 추가 반복이 필요하기 때문에 출력 인덱스가 정확합니다.



@ExpiredData 아, 물론 .. 감사합니다! :)
Kevin Cruijssen


@Grimy 루프 외부에서 인덱스를 사용하는 것이 레거시 코드에서만 작동한다고 생각했습니다. : : S 감사합니다!
Kevin Cruijssen

5

자바 스크립트 (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&&-~.
얽히고 설킨


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;

2
55 바이트 온라인으로 사용해보십시오! 일부 C 관련 골프 트릭 이 있습니다!
ErikF

1
@ErikF 또는 45 바이트
Arnauld


3
제출물이 플래그를 사용하는 경우 제출물 헤더에 추가 할 수 있습니까?
Jo King

1
@nwellnhof 42 바이트
ceilingcat



3

하스켈, 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)

  • 알고리즘 : 평평한 벡터가 될 때까지 트리를 한 수준 씩 반복적으로 평탄화합니다. 반복 횟수는 최대 깊이에 해당합니다.

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

  • @Giuseppe 덕분에 -2

d=1그리고 d-1마지막에 사용합니까? 시작할 수 0없습니까?
주세페

또한 테스트 케이스를보다 쉽게 ​​입력 할 수 있도록 여기 로 전환 >했습니다.~
Giuseppe

@Giuseppe : 물론 ... 나는 명백한 🤦‍♂️
digEmAll


1

K (ngn / k) , 4 바이트

해결책:

#,/\

온라인으로 사용해보십시오!

설명:

요점을 놓친 것 같습니다.

트리를 3 가지 항목 목록 (parent-node; left-child; right-child)으로 나타내면 예제는 다음과 같이 표현 될 수 있습니다.

(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θ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 처리하는 동안 트리를 임시로 수정합니다. 설명:

⊞θ⁰

루트 노드로 0을 밉니다.

⊞υθ

루트 노드를 모든 노드 목록으로 푸시하십시오.

Fυ«

트리의 너비 우선 탐색을 수행하십시오.

≔⊕⊟ιθ

이 노드의 깊이를 얻습니다.

FΦι∧κλ

모든 자식 노드를 반복합니다.

⊞υ⊞Oκθ

자식 노드에 부모의 깊이를 알려주고 모든 노드 목록으로 밉니다.

»Iθ

모든 노드가 이송되면 마지막 노드의 깊이를 인쇄합니다. 순회가 너비 우선이기 때문에 이것이 나무의 높이가됩니다.


0

Stax , 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

줄리아, 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.