ให้ต้นไม้สร้างรหัสPrüferของมัน


10

ใน รหัสPrüferเป็นลำดับที่ไม่ซ้ำกันของจำนวนเต็มว่าหมายถึงต้นไม้ที่เฉพาะเจาะจง

คุณสามารถค้นหารหัสPrüferของต้นไม้ด้วยอัลกอริทึมต่อไปนี้นำมาจาก Wikipedia:

พิจารณา T {1, 2, ..., n}ต้นไม้ที่มีป้ายกำกับจุด ที่ขั้นตอนที่1ให้นำใบไม้ที่มีฉลากขนาดเล็กที่สุดออกแล้วตั้งค่าองค์ประกอบที่iของลำดับPrüferให้เป็นป้ายกำกับของเพื่อนบ้านของใบไม้นี้

(โปรดทราบว่าเนื่องจากเป็นใบไม้จึงมีเพียงเพื่อนบ้านเดียว)

คุณควรหยุดการทำซ้ำเมื่อเหลือเพียงสองจุดยอดในกราฟ

งาน

ให้ต้นไม้ที่มีข้อความเป็นอินพุตเอาต์พุตโค้ดPrüfer คุณสามารถป้อนข้อมูลในลักษณะที่สมเหตุสมผล เช่นเมทริกซ์ adjacency หรือภาษาของคุณแสดงกราฟในตัว ( คุณไม่สามารถรับรหัสPrüferได้ )

นี่คือ ดังนั้นคุณควรมุ่งหวังที่จะลดจำนวนไบต์ในแหล่งที่มาของคุณ

กรณีทดสอบ

นี่คืออินพุตบางส่วนใน ASCII พร้อมกับเอาต์พุตด้านล่าง คุณไม่จำเป็นต้องรองรับอินพุต ASCII เช่นนี้

    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}

เราสามารถนำต้นไม้ที่รูทไปเป็นอินพุตได้หรือไม่?
xnor

เราสามารถนำสิ่งที่ชอบ[[2,1],[2,3],[2,5],[2,4,6]]สำหรับกรณีแรกมาได้หรือไม่? (เช่นแต่ละสาขา)
HyperNeutrino

@xnor ใช่คุณสามารถ
Ad Hoc Garf Hunter

1
ฉันรู้สึกว่าการป้อนข้อมูลด้วยขอบหรือเส้นทางที่มุ่งไปยังรูทคือการประมวลผลล่วงหน้าสำหรับรหัสPrüfer ทั้งสองวิธีฉันคิดว่าคุณควรมีความชัดเจนมากขึ้นใน "คุณอาจป้อนข้อมูลด้วยวิธีการที่สมเหตุสมผล (คุณไม่สามารถป้อนข้อมูลเป็นรหัสPrüfer)"
xnor

@xnor โอ้ฉันไม่เข้าใจสิ่งที่ Hyper Neutrino ถาม
Ad Hoc Garf Hunter

คำตอบ:


9

Mathematica, 34 ไบต์

<<Combinatorica`
LabeledTreeToCode

บางคนต้องทำมัน ....

หลังจากโหลดCombinatoricaแพ็กเกจแล้วฟังก์ชันLabeledTreeToCodeคาดว่าอินพุตทรีเป็นกราฟที่ไม่ได้บอกทิศทางพร้อมขอบและจุดยอดที่ระบุไว้อย่างชัดเจน Graph[{{{1, 4}}, {{4, 3}}, {{4, 2}}, {{2, 5}}, {{2, 6}}, {{6, 7}}, {{5, 8}}}, {1, 2, 3, 4, 5, 6, 7, 8}]ตัวอย่างเช่นการป้อนข้อมูลในกรณีทดสอบที่สองอาจจะเป็น


5
แน่นอนว่ามีสิ่งที่ต้องทำในตัว > _>
HyperNeutrino

4

Python 3, 136 131 127 ไบต์

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)

รับอินพุตเป็นเมทริกซ์ adjacency ตัวอย่างแรก:

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

ฉันล้มเหลว ...
HyperNeutrino

@HyperNeutrino คุณเร็วขึ้นประมาณ 4 วินาที!
L3viathan

ฮี่ ๆ ๆ ! และยาวประมาณ 2.7 เท่า! : D gg
HyperNeutrino

1
delอยู่? > _>
HyperNeutrino

1
@WheatWizard คุณถูกต้องเกี่ยวกับเครื่องหมายอัฒภาค แต่การผสมแท็บและช่องว่างเป็นข้อผิดพลาดใน Python 3
L3viathan

2

เยลลี่ 31 ไบต์

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

ลิงก์ monadic ซึ่งรับรายการคู่ของโหนด (กำหนดขอบ) ในลำดับใด ๆ (และแต่ละทิศทางในทิศทางใดก็ได้) และส่งคืนรหัสPrüferเป็นรายการ

ลองออนไลน์!

อย่างไร?

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

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

ลองออนไลน์!

คำอธิบาย

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

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

ต้องการอินพุตเป็น hash-map โดยมีป้ายกำกับ "leaf-like" เป็นคีย์และป้ายกำกับ "root-like" เป็นค่า ตัวอย่างเช่น:

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

ในแต่ละซ้ำพบที่สำคัญที่เล็กที่สุดซึ่งไม่ได้รับการอ้างอิงจากโหนดอื่น ๆ เพิ่มไปยังผลและลบโหนดจากนิยามกราฟr ไปกับกรณีอื่น ๆ เมื่อเป็นที่ว่างเปล่าเป็นผลตอบแทน นอกจากนี้องค์ประกอบสุดท้ายจะต้องมีการลดลงGif-letGfirstnil


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