Dada uma árvore gerar seu código Prüfer


9

Na um código de Prüfer é uma sequência única de números inteiros que denota uma árvore específica.

Você pode encontrar o código Prüfer de uma árvore com o seguinte algoritmo retirado da Wikipedia:

Considere uma árvore rotulada T com vértices {1, 2, ..., n}. Na etapa i , remova a folha com a menor etiqueta e defina o i- ésimo elemento da sequência Prüfer como a etiqueta do vizinho dessa folha.

(Observe que, como é uma folha, ela terá apenas um vizinho).

Você deve parar a iteração quando apenas dois vértices permanecerem no gráfico.

Tarefa

Dada uma árvore rotulada como entrada, imprima seu código Prüfer. Você pode receber sugestões de qualquer maneira razoável. Como uma matriz de adjacência ou a representação gráfica integrada em seus idiomas. ( Você não pode receber entrada como um código Prüfer ).

Isso é então você deve tentar minimizar os bytes em sua fonte.

Casos de teste

Aqui estão algumas entradas em ASCII com suas saídas abaixo. Você não precisa suportar entrada ASCII como esta.

    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}

Podemos receber uma árvore enraizada como entrada?
Xnor

Podemos considerar a entrada como algo semelhante [[2,1],[2,3],[2,5],[2,4,6]]ao primeiro caso? (ou seja, cada ramo)
HyperNeutrino

@xnor Sim, você pode
Ad Hoc Garf Hunter

11
Eu sinto que pegar uma entrada com bordas ou caminhos direcionados para uma raiz é pré-computação para o Código Prüfer. De qualquer forma, acho que você deve ter uma idéia mais clara de "Você pode receber informações de qualquer maneira razoável (você não pode receber informações como um código Prüfer)".
Xnor

@ xnor Oh, eu não entendi o que o Hyper Neutrino estava perguntando.
Ad Hoc Garf Hunter

Respostas:


9

Mathematica, 34 bytes

<<Combinatorica`
LabeledTreeToCode

Alguém tinha que fazer isso ....

Após carregar o Combinatoricapacote, a função LabeledTreeToCodeespera uma entrada em árvore como um gráfico não direcionado com arestas e vértices explicitamente listados; por exemplo, a entrada no segundo caso de teste poderia ser Graph[{{{1, 4}}, {{4, 3}}, {{4, 2}}, {{2, 5}}, {{2, 6}}, {{6, 7}}, {{5, 8}}}, {1, 2, 3, 4, 5, 6, 7, 8}].


5
Claro que há um built-in para fazer isso. > _>
HyperNeutrino

3

Python 3, 136 131 127 bytes

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)

Recebe entrada como uma matriz de adjacência. Primeiro exemplo:

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

bem, eu falhei ...
HyperNeutrino

@HyperNeutrino Você foi cerca de 4 segundos mais rápido!
L3viathan

Hehe sim! E cerca de 2,7 vezes mais! : D gg
HyperNeutrino

11
delexiste? > _>
HyperNeutrino

11
@WheatWizard você está certo sobre o ponto e vírgula, mas misturar tabulações e espaços é um erro em Python 3.
L3viathan

2

Gelatina , 31 bytes

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

Um link monádico que pega uma lista de pares de nós (definindo as arestas) em qualquer ordem (e cada um em qualquer orientação) e retorna o Código Prüfer como uma lista.

Experimente online!

Como?

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 bytes

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

Experimente online!

Explicação

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

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

Requer que a entrada seja um mapa de hash, tendo rótulos "em forma de folha" como chaves e rótulos "em forma de raiz" como valores. Por exemplo:

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

Em cada iteração, encontra a menor chave que não é referenciada por nenhum outro nó, a adiciona ao resultado re remove o nó da definição de gráfico G. if-letvai para o caso contrário, quando Gestá vazio, como firstretornos nil. Além disso, o último elemento deve ser descartado.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.