Diberi Pohon menghasilkan Kode Prugfernya


10

Dalam yang kode Prüfer adalah urutan yang unik dari bilangan bulat yang menunjukkan pohon tertentu.

Anda dapat menemukan kode Prüfer dari pohon dengan algoritma berikut yang diambil dari Wikipedia:

Pertimbangkan pohon berlabel T dengan simpul {1, 2, ..., n}. Pada langkah saya , menghapus daun dengan label terkecil dan mengatur saya th unsur urutan Prüfer menjadi label dari tetangga daun ini.

(Perhatikan bahwa karena daun itu hanya akan memiliki satu tetangga).

Anda harus menghentikan iterasi ketika hanya dua simpul yang tersisa di grafik.

Tugas

Diberikan pohon berlabel sebagai input keluaran kode Prüfer-nya. Anda dapat mengambil input dengan cara yang masuk akal. Seperti matriks kedekatan atau bahasa Anda yang dibangun dalam representasi grafik. ( Anda tidak boleh mengambil input sebagai kode Prüfer ).

Ini adalah sehingga Anda harus berusaha meminimalkan byte di sumber Anda.

Uji kasus

Berikut adalah beberapa input dalam ASCII dengan outputnya di bawah ini. Anda tidak perlu mendukung input ASCII seperti ini.

    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}

Bisakah kita mengambil pohon yang sudah di-root sebagai input?
xnor

Bisakah kita mengambil input seperti [[2,1],[2,3],[2,5],[2,4,6]]untuk kasus pertama? (Yaitu masing-masing cabang)
HyperNeutrino

@xnor Ya, Anda bisa
Ad Hoc Garf Hunter

1
Saya merasa seperti mengambil input dengan tepi atau jalur yang diarahkan ke root adalah prakomputasi terhadap Kode Prüfer. Either way, saya pikir Anda harus lebih jelas pada "Anda dapat mengambil input dengan cara yang masuk akal (Anda tidak dapat mengambil input sebagai kode Prüfer)."
xnor

@ xnor Oh saya tidak mengerti apa yang diminta Hyper Neutrino.
Ad Hoc Garf Hunter

Jawaban:


9

Mathematica, 34 byte

<<Combinatorica`
LabeledTreeToCode

Seseorang harus melakukannya ....

Setelah memuat Combinatoricapaket, fungsi LabeledTreeToCodemengharapkan input pohon sebagai grafik tidak terarah dengan tepi dan simpul yang terdaftar secara eksplisit; misalnya, input dalam test case kedua bisa Graph[{{{1, 4}}, {{4, 3}}, {{4, 2}}, {{2, 5}}, {{2, 6}}, {{6, 7}}, {{5, 8}}}, {1, 2, 3, 4, 5, 6, 7, 8}].


5
Tentu saja ada built-in untuk melakukan ini. > _>
HyperNeutrino

4

Python 3, 136 131 127 byte

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)

Mengambil input sebagai matriks kedekatan. Contoh pertama:

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

baik saya gagal ...
HyperNeutrino

@HyperNeutrino Anda sekitar 4 detik lebih cepat!
L3viathan

Hehe yup! Dan sekitar 2,7 kali lebih lama! : D gg
HyperNeutrino

1
delada > _>
HyperNeutrino

1
@WheatWizard Anda benar tentang titik koma, tetapi menggabungkan tab dan spasi adalah kesalahan dalam Python 3.
L3viathan

2

Jelly , 31 byte

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

Tautan monadik yang mengambil daftar pasangan node (menentukan tepi) dalam urutan apa pun (dan masing-masing dalam orientasi apa pun) dan mengembalikan Kode Prüfer sebagai daftar.

Cobalah online!

Bagaimana?

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 byte

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

Cobalah online!

Penjelasan

[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 byte

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

Membutuhkan input untuk menjadi peta-hash, yang memiliki label "daun-seperti" sebagai kunci dan label "seperti-akar" sebagai nilai. Sebagai contoh:

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

Pada setiap iterasi ia menemukan kunci terkecil yang tidak direferensikan oleh simpul lain, menambahkannya ke hasil rdan menghilangkan simpul dari definisi grafik G. if-letpergi ke kasus lain ketika Gkosong, sebagai firstpengembalian nil. Juga elemen terakhir harus dijatuhkan.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.