เขียนโปรแกรมที่สั้นที่สุดเพื่อคำนวณความสูงของต้นไม้ไบนารี


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 ไบต์

ŒḊ’

Monadic Link ยอมรับรายการที่แสดงถึง tree: [root_value, left_tree, right_tree]โดยที่แต่ละตัวleft_treeและright_treeมีโครงสร้างคล้ายกัน (ว่างถ้าจำเป็น) ซึ่งให้ความสูง

ลองออนไลน์!

อย่างไร?

เล็กน้อยในเยลลี่:

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

Jonathon Allen นั่นเป็นภาษาที่น่าสนใจที่คุณใช้ ในฐานะผู้มาใหม่คุณอาจให้ลิงค์หรือการอ้างอิงเว็บไซต์ที่สอนผู้คนถึงวิธีการใช้ Jelly?
T. Salim

4
คลิกที่ลิงก์ในส่วนหัว - เป็นภาษากอล์ฟที่พัฒนาโดยDennisซึ่งเป็นหนึ่งในผู้ดูแลเว็บไซต์
Jonathan Allan

2
ฉันสงสัยว่าขัดแย้งมันจะเป็นตัวแทนของใบเป็นxแทน[x, [], []]...
เอริก Outgolfer

@EriktheOutgolfer เพื่อให้สอดคล้องกับ "ตัวชี้" และ "struct" ธรรมชาติของคำถามฉันคิดว่าทุกโหนดควรอยู่ในรูปแบบเดียวกัน
Jonathan Allan

10

Python 2 ,  35  33 ไบต์

ขอบคุณ Arnauld ที่คอยกำกับดูแลและประหยัด 4

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

ฟังก์ชั่นวนซ้ำรับรายการที่แสดงถึง tree: [root_value, left_tree, right_tree]โดยที่แต่ละตัวleft_treeและright_treeเป็นโครงสร้างที่คล้ายกัน (ว่างถ้าต้องการ) ซึ่งจะส่งกลับความสูง

ลองออนไลน์!

โปรดทราบว่า[]จะกลับมาแต่ในหลามFalseFalse==0


บุคคลเดียวกันได้รับอนุญาตให้ตอบสองคำถามที่ต่างกัน?
T. Salim

6
ใช่แน่นอนกอล์ฟเป็นการแข่งขันในระดับภาษา แม้แต่รายการที่สองในภาษาเดียวกันก็สามารถยอมรับได้ในบางครั้งหากวิธีการนั้นแตกต่างกันมาก
Jonathan Allan

@Arnauld เดาดังนั้น (ผมสันนิษฐานว่าไม่ใช่จำนวนเต็ม-ปัจจุบันอาจจะด้วยเหตุผลบางอย่าง)
โจนาธานอัลลัน

6

Haskell, 33 ไบต์

h L=0 
h(N l r _)=1+max(h l)(h r)

ใช้ประเภทต้นไม้ที่กำหนดเองdata T = L | N T T Intซึ่งเป็น Haskell เทียบเท่ากับโครงสร้าง C ที่กำหนดในการท้าทาย

ลองออนไลน์!


6

Perl 6 , 25 ไบต์

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

(l, r, v)การป้อนข้อมูลเป็นรายการที่ 3 องค์ประกอบ ต้นไม้ที่ว่างเปล่าเป็นรายการที่ว่างเปล่า

ลองออนไลน์!

คำอธิบาย

{                       }  # 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เคล็ดลับที่น่าสนใจ แต่มันเป็นคู่ของไบต์สั้นเพื่อกำหนดบล็อกถึง $!
โจคิง

@ โจกิ้งฉันไม่รู้ การเก็บโซลูชันความท้าทายในโลกที่มีความผันผวนเช่น$!หรือ$/รู้สึกอยากโกง
nwellnhof

(Ab) ใช้ตัวแปรเช่น $! และ $ / เป็นมาตรฐานการปฏิบัติที่เป็นธรรมสำหรับการเล่นกอล์ฟ P6
0721090601

6

05AB1E , 11 7 5 ไบต์

Δ€`}N

-4 ไบต์ขอบคุณที่@ExpiredData
-2 ไบต์ขอบคุณที่@Grimy

รูปแบบการป้อนข้อมูลจะคล้ายกับคำตอบของเยลลี่: รายการที่แสดงถึงต้นไม้: [root_value, left_tree, right_tree]ซึ่งแต่ละรายการleft_treeและright_treeมีโครงสร้างที่คล้ายกัน (ว่างเปล่าทางเลือก) Ie [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 อาแน่นอน .. ขอบคุณ! :)
Kevin Cruijssen


@Grimy ฉันคิดว่าการใช้ดัชนีนอกลูปใช้ได้กับรหัสดั้งเดิมเท่านั้น .. : S ขอบคุณ!
Kevin Cruijssen

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 ที่จะนำไปสู่การเปรียบเทียบกับที่ไม่ได้กำหนด
Arnauld

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
หากการส่งของคุณอาศัยธงคุณสามารถเพิ่มพวกเขาไปยังส่วนหัวของการส่งของคุณ?
โจคิง

1
อาคารบน @nwellnhof 42 ไบต์
เพดานแมว

4

JavaScript (Node.js)ขนาด 32 ไบต์

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

ลองออนไลน์!

ใช้ชื่อflatแทนflattenหรือsmooshเป็นความคิดที่ดีสำหรับการเล่นกอล์ฟ

ใช้[]สำหรับโหนด 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)

  • อัลกอริทึม:ทวนแบนต้นไม้ซ้ำ ๆ ในระดับหนึ่งจนกว่ามันจะกลายเป็นเวกเตอร์แบน: จำนวนการวนซ้ำนั้นสอดคล้องกับความลึกสูงสุด

แรงบันดาลใจจากโซลูชัน @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ไม่ได้เหรอ
จูเซปเป้

ฉันเปลี่ยน>ไป~ ที่นี่เพื่อให้กรณีทดสอบง่ายต่อการป้อนข้อมูล
Giuseppe

@Giuseppe: แน่นอน ... ฉันหายตัวไปอย่างเห็นได้ชัด 5
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θ

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด แก้ไขแผนผังชั่วคราวระหว่างการประมวลผล คำอธิบาย:

⊞θ⁰

ดันศูนย์ให้เป็นโหนดรูท

⊞υθ

พุชโหนดรูทไปยังรายการโหนดทั้งหมด

Fυ«

ทำการค้นหาต้นไม้อย่างกว้าง ๆ

≔⊕⊟ιθ

รับความลึกของโหนดนี้

FΦι∧κλ

วนซ้ำโหนดย่อยใด ๆ

⊞υ⊞Oκθ

บอกโหนดย่อยกับความลึกของพาเรนต์และส่งไปยังรายการโหนดทั้งหมด

»Iθ

เมื่อโหนดทั้งหมดถูก traversed แล้วพิมพ์ความลึกของโหนดสุดท้าย เนื่องจากการสำรวจเส้นทางกว้างก่อนนี่จะเป็นความสูงของต้นไม้


0

Stax , 5 ไบต์

▐▌µ╡⌂

เรียกใช้และแก้ไขข้อบกพร่อง

สแตกซ์มีค่าตัวชี้มิได้ค่า null [2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]]ดังนั้นฉันแทนการป้อนข้อมูลเช่น อาจจะเป็นข้อได้เปรียบที่ไม่เป็นธรรม แต่มันก็ใกล้เคียงที่สุดที่ฉันจะได้รับ

คลายไฟล์ ungolfed และแสดงความคิดเห็นโค้ดมีลักษณะเช่นนี้

        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

Julia, 27 ไบต์

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

ด้วย struct ต่อไปนี้เป็นตัวแทนของต้นไม้ไบนารี:

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

cคือ tuple ที่แสดงถึงโหนดด้านซ้ายและขวาและ tuple ที่ว่างเปล่า()ถูกใช้เพื่อส่งสัญญาณว่าไม่มีโหนด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.