Bir Ağacın Prüfer Kodunu Üretmesi


10

İçinde Bir Prüfer kodu belirli ağacı gösterir tamsayılar benzersiz bir dizisidir.

Vikipedi'den alınan aşağıdaki algoritmaya sahip bir ağacın Prüfer kodunu bulabilirsiniz:

Köşeleri olan etiketli bir ağaç T'yi düşünün {1, 2, ..., n}. İ adımında , en küçük etikete sahip olan yaprağı çıkarın ve Prüfer dizisinin i . Elemanını bu yaprağın komşusunun etiketi olarak ayarlayın.

(Bir yaprak olduğu için sadece bir komşusu olacağını unutmayın).

Grafikte yalnızca iki köşe kaldığında yinelemeyi durdurmalısınız.

Görev

Girdi olarak etiketlenmiş bir ağaç verildiğinde Prüfer kodu. Girdiyi makul bir şekilde alabilirsiniz. Bitişiklik matrisi veya dillerinizde yerleşik grafik gösterimi gibi. ( Girişi Prüfer kodu olarak alamazsınız ).

Bu bu yüzden kaynağınızdaki baytları en aza indirmeyi hedeflemelisiniz.

Test senaryoları

ASCII'de bazı çıktılar aşağıda verilmiştir. ASCII girişini bu şekilde desteklemenize gerek yoktur.

    3
    |
1---2---4---6
    |
    5

{2,2,2,4}

1---4---3
    |
5---2---6---7
|
8

{4,4,2,6,2,5}

5---1---4   6
    |       |
    2---7---3

{1,1,2,7,3}

Köklü bir ağacı girdi olarak alabilir miyiz?
xnor

[[2,1],[2,3],[2,5],[2,4,6]]İlk vaka için girişi girdi olarak alabilir miyiz ? (yani her şube)
HyperNeutrino

@xnor Evet yapabilirsiniz
Ad Hoc Garf Hunter

1
Köklere doğru yönlendirilmiş kenarları veya yolları olan bir girdi almak, Prüfer Koduna doğru ön hesaplamadır. Her iki durumda da, "Girdiyi makul bir şekilde alabilirsin (Prüfer kodu olarak girdiyi alamayabilirsin)."
xnor

@xnor Oh, Hyper Neutrino'nun ne istediğini anlamadım.
Ad Hoc Garf Hunter

Yanıtlar:


9

Mathematica, 34 bayt

<<Combinatorica`
LabeledTreeToCode

Birisi yapmak zorundaydı ....

CombinatoricaPaketi yükledikten sonra , işlev, LabeledTreeToCodebir ağaç girdisinin, açıkça listelenen kenarları ve köşeleri olan yönlendirilmemiş bir grafik olarak olmasını bekler; örneğin, ikinci test durumundaki girdi olabilir Graph[{{{1, 4}}, {{4, 3}}, {{4, 2}}, {{2, 5}}, {{2, 6}}, {{6, 7}}, {{5, 8}}}, {1, 2, 3, 4, 5, 6, 7, 8}].


5
Tabii ki bunu yapacak bir yerleşik var. > _>
HyperNeutrino

4

Python 3, 136 131 127 bayt

def f(t):
 while len(t)>2:
  m=min(x for x in t if len(t[x])<2);yield t[m][0];del t[m]
  for x in t:m in t[x]and t[x].remove(m)

Bir bitişiklik matrisi olarak girdi alır. İlk örnek:

>>> [*f({1:[2],2:[1,3,4,5],3:[2],4:[2,6],5:[2],6:[4]})]
[2, 2, 2, 4]

iyi başarısız oldum ...
HyperNeutrino

@HyperNeutrino Yaklaşık 4 saniye daha hızlıydınız!
L3viathan

Hehe yup! Ve yaklaşık 2.7 kat daha uzun! : D gg
HyperNeutrino

1
delvar? > _>
HyperNeutrino

1
@WheatWizard Noktalı virgüllerle ilgili haklısınız, ancak sekmeleri ve boşlukları karıştırmak Python 3'te bir hata.
L3viathan

2

Jöle , 31 bayt

FĠLÞḢḢ
0ịµÇHĊṙ@µÇCịṪ,
WÇÐĿḢ€ṖṖḊ

Düğüm çiftlerinin listesini (kenarları tanımlayan) herhangi bir sırayla (ve her birini herhangi bir yönde) alan ve Prüfer Kodunu liste olarak döndüren monadik bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

FĠLÞḢḢ - Link 1, find leaf location: list of edges (node pairs)
F      - flatten
 Ġ     - group indices by value (sorted smallest to largest by value)
  LÞ   - sort by length (stable sort, so equal lengths remain in prior order)
    ḢḢ - head head (get the first of the first group. If there are leaves this yields
       -   the index of the smallest leaf in the flattened version of the list of edges)

0ịµÇHĊṙ@µÇCịṪ, - Link 2, separate smallest leaf: list with last item a list of edges
0ị             - item at index zero - the list of edges
  µ            - monadic chain separation (call that g)
   Ç           - call last link (1) as a monad (index of smallest leaf if flattened)
    H          - halve
     Ċ         - ceiling (round up)
      ṙ@       - rotate g left by that amount (places the edge to remove at the right)
        µ      - monadic chain separation (call that h)
         Ç     - call last link (1) as a monad (again)
          C    - complement (1-x)
            Ṫ  - tail h (removes and yields the edge)
           ị   - index into, 1-based and modular (gets the other node of the edge)
             , - pair with the modified h
               -    (i.e. [otherNode, restOfTree], ready for the next iteration)

WÇÐĿḢ€ṖṖḊ - Main link: list of edges (node pairs)
W         - wrap in a list (this is so the first iteration works)
  ÐĿ      - loop and collect intermediate results until no more change:
 Ç        -   call last link (2) as a monad
    Ḣ€    - head €ach (get the otherNodes, although the original tree is also collected)
      ṖṖ  - discard the two last results (they are excess to requirements)
        Ḋ - discard the first result (the tree, leaving just the Prüfer Code)

1

05AB1E , 29 bayt

[Dg#ÐD˜{γé¬`U\X.å©Ï`XK`ˆ®_Ï]¯

Çevrimiçi deneyin!

açıklama

[Dg#                           # loop until only 1 link (2 vertices) remain
    ÐD                         # quadruple the current list of links
      ˜{                       # flatten and sort values
        γé                     # group by value and order by length of runs
          ¬`U                  # store the smallest leaf in X
             \X                # discard the sorted list and push X
               .å©             # check each link in the list if X is in that link
                  Ï`           # keep only that link
                    XK`ˆ       # add the value that isn't X to the global list
                        ®_Ï    # remove the handled link from the list of links
                           ]   # end loop
                            ¯  # output global list

1

Clojure, 111 bayt

#(loop[r[]G %](if-let[i(first(sort(remove(set(vals G))(keys G))))](recur(conj r(G i))(dissoc G i))(butlast r)))

Girişin, anahtar olarak "yaprak benzeri" etiketlere ve değer olarak "kök benzeri" etiketlere sahip bir karma harita olmasını gerektirir. Örneğin:

{1 2, 3 2, 5 2, 4 2, 6 4}
{1 4, 3 4, 4 2, 8 5, 5 2, 7 6, 6 2}

Her yinelemede, başka bir düğüm tarafından başvurulmayan en küçük anahtarı bulur, sonuca ekler rve düğümü grafik tanımından kaldırır G. boş if-letolduğunda başka bir duruma döner G, firstdöndürür nil. Ayrıca son elemanın da düşürülmesi gerekir.


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.