트리가 Prüfer 코드를 생성하면


10

Prüfer 코드는 특정 나무를 나타낸다 정수의 고유 한 순서입니다.

Wikipedia에서 가져온 다음 알고리즘을 사용하여 트리의 Prüfer 코드를 찾을 수 있습니다.

꼭짓점이있는 레이블이 지정된 트리 T를 고려하십시오 {1, 2, ..., n}. i 단계 에서 가장 작은 레이블이있는 리프를 제거하고 Prüfer 시퀀스 의 i 번째 요소를이 리프의 이웃 레이블로 설정하십시오.

(잎이기 때문에 이웃이 하나뿐입니다).

두 개의 정점이 그래프에 남아 있으면 반복을 중지해야합니다.

직무

레이블이 지정된 트리에 Prüfer 코드의 출력이 제공됩니다. 합리적인 방법으로 입력 할 수 있습니다. 인접 행렬 또는 언어 내장 그래프 표현과 같은. ( 당신은 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 Code를 향한 사전 계산이라고 생각합니다. 어느 쪽이든, "당신은 합리적인 방법으로 입력을받을 수 있습니다 (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

파이썬 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)

인접 행렬로 입력을받습니다. 첫 번째 예 :

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

잘 실패했습니다 ...
HyperNeutrino

@HyperNeutrino 당신은 약 4 초 더 빨랐습니다!
L3via5

he! 그리고 약 2.7 배 길이! : D gg
HyperNeutrino

1
del존재합니까? > _>
HyperNeutrino

1
@WheatWizard 세미콜론에 대해서는
맞지만

2

젤리 , 31 바이트

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

임의의 순서로 (및 각 방향으로) 노드 쌍 목록 (가장자리 정의)을 가져와 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

클로저, 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)))

입력은 "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하고 그래프 정의에서 노드를 제거합니다 G. if-letG비어있는 경우 else 로 이동 first합니다 nil. 또한 마지막 요소를 삭제해야합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.