İkili Ağacın Yüksekliğini Hesaplamak için En Kısa Programı Yaz


18

İkili bir ağacın yüksekliği, kök düğümden kök çocuğuna kökten en uzak olan mesafedir.

Aşağıda bir örnek verilmiştir:

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

İkili ağacın yüksekliği: 4

İkili Ağacın Tanımı

Ağaç, işaretli bir tam sayı değeri ve bunlara iki ağaç veya işaretçi içeren bir nesnedir.

İkili ağaç yapısının yapısı aşağıdaki gibi görünür:

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;

Meydan okuma:

Giriş

İkili ağacın kökü

Çıktı

İkili bir ağacın yüksekliğini temsil eden sayı

Girdi olarak bir ikili ağacın kökü verildiğini varsayarsak, bir ikili ağacın yüksekliğini hesaplayan ve yüksekliği döndüren en kısa programı yazın. En az bayt (muhasebe boşlukları) olan program kazanır.


4
İşaretçi olmayan diller ne alır?
Jonathan Allan

4
... ama sonra ağaç objemin sadece bir özelliği olabilir h. Bu meydan okuma amacıyla sadece listelerden yapılmış belirli bir yapıyı tanımlamak daha iyi olabilir.
Jonathan Allan

11
@ T.Salim Gelecekte, lütfen önce kum havuzunda yayınlamayı düşünün .
wizzwizz4

1
Peki, geçerli bir gösterim , ikili ağaçların [root_value, left_node, right_node]her birinin left_nodeve right_nodeaynı zamanda kabul edilebilir olduğu uzunluk 3'ün bir listesi mi? Birçok dilde önemsiz olacak, ancak bazılarında eğlenceli olabilir.
Jonathan Allan

3
Soruyu geçerli bir ikili yapı oluşturanı içerecek şekilde düzenleyebilir misiniz? Belki bir tanım gibi a tree is an object that contains a value and either two other trees or pointers to them. Nesne içermeyen dilleri içeren bir tanım da güzel olurdu.
Jo King

Yanıtlar:


11

Jöle , 3 bayt

ŒḊ’

Ağacı temsil eden bir listeyi kabul eden monadik bir Bağlantı: [root_value, left_tree, right_tree]burada her biri left_treeve right_treebenzer yapılardır (gerekirse boştur), bu da yüksekliği verir.

Çevrimiçi deneyin!

Nasıl?

Jelly'de oldukça önemsiz:

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

Jonathon Allen, kullandığınız ilginç bir dildir. Yeni gelen biri olarak, öğretmenlerin insanların Jelly'i nasıl kullanacaklarını gösteren bir bağlantı veya web sitesi tavsiyesi sağlayabilir misiniz?
T. Salim

4
Başlıktaki bağlantıyı tıklayın - sitenin moderatörlerinden Dennis tarafından geliştirilen bir golf Dili .
Jonathan Allan

2
Bunun xyerine bir yaprağı temsil [x, [], []]
etmenin

@EriktheOutgolfer Sorunun "pointer" ve "struct" doğasına uymak için her düğümün aynı formda olması gerektiğini düşünüyorum.
Jonathan Allan

10

Python 2 ,  35  33 bayt

Arnauld'a bir gözetim ve tasarruf sağladığı için teşekkür ederiz 4.

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

Ağacı temsil eden bir listeyi kabul eden özyinelemeli işlev: [root_value, left_tree, right_tree]burada her biri left_treeve right_treebenzer yapılardır (gerekirse boştur), yüksekliği döndürür.

Çevrimiçi deneyin!

[]Geri döneceğini unutmayın False, ancak Python False==0.


Aynı kişi aynı soruya iki farklı cevap verebilir mi?
T. Salim

6
Evet, elbette, golf dil seviyesinde bir yarışmadır. Yaklaşım çok farklıysa, aynı dilde ikinci bir giriş bile bazen kabul edilebilir.
Jonathan Allan

@Arnauld Sanırım (tamsayı olmayanların bir nedenle mevcut olabileceğini varsaydım)
Jonathan Allan

6

Haskell, 33 bayt

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

data T = L | N T T IntMeydan okumada verilen C yapısının Haskell eşdeğeri olan özel ağaç türünü kullanarak .

Çevrimiçi deneyin!


6

Perl 6 , 25 bayt

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

Giriş 3 elemanlı bir listedir (l, r, v) . Boş ağaç boş listedir.

Çevrimiçi deneyin!

açıklama

{                       }  # 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

Eski çözüm, 30 bayt

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

Çevrimiçi deneyin!


&?BLOCKHüner ilginç ama bir var kısa bayt çift $ 'a blok atamak!
Jo King

@JoKing Bilmiyorum. Meydan okuma çözümünü uçucu bir küreselde saklamak gibi $!veya $/beni aldatmak gibi geliyor.
nwellnhof

(Ab) $! ve $ / golf P6 için oldukça standart bir uygulamadır.
user0721090601

6

05AB1E , 11 7 5 bayt

Δ€`}N

@ExpiredData sayesinde -4 bayt . @Grimy
sayesinde -2 bayt .

Ağaç temsil eden bir listesi: Girdi biçimi jöle yanıt olarak benzer olan [root_value, left_tree, right_tree], her biri burada left_treeve right_treebenzeri yapılardır (isteğe bağlı olarak boş). yani[2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]] meydan okuma açıklamasındaki ağacı temsil eder.

Çevrimiçi deneyin veya birkaç test vakasını doğrulayın .

Açıklama:

Δ     # 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 tabanlı olmasına rağmen, change-loop'un Δçıktı dizininin doğru olmasına neden olduğundan, artık değişmediğini kontrol etmek için ek bir yinelemeye ihtiyaç duyduğunu unutmayın.



@ExpiredData Ah, elbette .. Teşekkürler! :)
Kevin Cruijssen


@Grimy Bir döngü dışında endeksi kullanarak düşündüm sadece eski kodu çalıştı ..: S
Kevin Cruijssen

5

JavaScript (ES6),  35  33 bayt

Giriş yapısı: [[left_node], [right_node], value]

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

Çevrimiçi deneyin!

Yorumlananlar

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

Görünüşe göre bir bayt kaydedebilirsiniz a&&-~.
Shaggy

1
@Shaggy undefined ile karşılaştırmaya yol açacaktır .
Arnauld

4

C, 43 bayt

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

İkili ağacın yapısı aşağıdaki gibidir:

typedef struct tree
{
  struct tree * l;

  struct tree * r;

  int v;

} tree;

2
55 bayt Çevrimiçi deneyin! C'ye özgü bazı golf hileleri burada!
ErikF

1
@ErikF Veya 45 bayt
Arnauld


3
Eğer gönderiminiz bayraklara dayanıyorsa, lütfen bunları gönderiminizin başlığına ekleyebilir misiniz?
Jo King

1
İnşaat @nwellnhof 42 bytes
ceilingcat

4

JavaScript (Node.js) , 32 bayt

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

Çevrimiçi deneyin!

Veya flatyerine adı kullanmak kod golf için harika bir fikirdir.flattensmoosh

Kullanılması []ağacında boş düğüm için ve [left, right, value]düğümleri için. valueİşte bir tamsayı.



3

Haskell, 28 bayt

Aşağıdaki veri tanımını kullanarak:

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

Yükseklik:

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

2

Şema, 72 Bayt

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

Daha Okunabilir Sürüm:

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

Bir ağacı temsil etmek için form listelerini (veri, sol, sağ) kullanma. Örneğin

   1
  / \
  2  3
 /\
 4 5

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

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

Çevrimiçi deneyin!


2

R , 51 bayt

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

Çevrimiçi deneyin!

  • Girdi: biçiminde iç içe bir liste:list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • Algoritma: Ağacı düz bir vektör haline gelene kadar tek bir düzeye kadar düz olarak düzleştirir: yineleme sayısı maksimum derinliğe karşılık gelir.

@KevinCruijssen çözümünden ilham alındı


Özyinelemeli alternatif:

R , 64 bayt

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

Çevrimiçi deneyin!

'~'Bir liste yapısında depolanan bir ağacın maksimum derinliğini hesaplayabilmesini sağlayan işlevi / operatörü yeniden tanımlar.

Bir ağacın liste yapısı şu biçimdedir: list(ROOT_ELEMENT, LEFT_TREE, RIGHT_TREE)

  • @Giuseppe sayesinde -2

neden kullanıyorsun d=1ve d-1sonunda? Başlayamaz mısın 0?
Giuseppe

Ayrıca ben açık >için ~ buraya test durumları girişine daha kolaydır böylece
Giuseppe

@Giuseppe: tabii ki ... Açık missing‍♂️ eksikti
digEmAll


1

K (ngn / k) , 4 bayt

Çözüm:

#,/\

Çevrimiçi deneyin!

Açıklama:

Bence bu noktayı kaçırmış olabilirim.

Bir ağacı 3 öğeli liste olarak temsil eden (ebeveyn-düğüm; sol-çocuk; sağ-çocuk), örnek şu şekilde temsil edilebilir:

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

veya: (2;(7;(,2);(6;(,5);(,11)));(5;();(9;(,4);()))).

Dolayısıyla çözüm yinelemeli olarak düzleştirmek ve yinelemeleri saymaktır:

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

0

Kömür , 29 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. İşleme sırasında ağacı geçici olarak değiştirir. Açıklama:

⊞θ⁰

Kök düğüme sıfır basın.

⊞υθ

Kök düğümü tüm düğümlerin listesine itin.

Fυ«

Ağacın ilk genişlik aramasını yapın.

≔⊕⊟ιθ

Bu düğümün derinliğini alın.

FΦι∧κλ

Alt düğümlerin üzerinden döngü yapın.

⊞υ⊞Oκθ

Alt düğüme ebeveyninin derinliğini söyleyin ve tüm düğümlerin listesine itin.

»Iθ

Tüm düğümler geçildikten sonra son düğümün derinliğini yazdırın. Geçiş ilk önce genişlik olduğundan, bu ağacın yüksekliği olacaktır.


0

Stax , 5 bayt

▐▌µ╡⌂

Çalıştır ve hata ayıkla

Stax ne işaretçiler ne de null değerlere sahiptir, bu nedenle [2,[7,[2,[],[]],[6,[5,[],[]],[11,[],[]]]],[5,[],[9,[4,[],[]],[]]]] . Belki bu haksız bir avantajdır, ancak alabileceğim en yakın şeydi.

Paketten çıkarılmış, çözülmemiş ve yorum yapılmıştır, kod şöyle görünür.

        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

Bunu çalıştır


0

Kotlin, 45 bayt

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

Aşağıdaki sınıfın tanımlandığı varsayılarak

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

Çevrimiçi deneyin


0

Julia, 27 bayt

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

İkili ağacı temsil eden aşağıdaki yapı ile:

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

csol ve sağ düğümleri temsil eden bir demet olup boş demet ()bir düğümün olmadığını belirtmek için kullanılır.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.