ó
    ‰*£h/  ã                   ór   • S SK Jr  S SKJr  S SKJr  S SKJr  S SKJ	r	J
r
  S SKJr  S SKJr   " S S	\5      rg
)é    )ÚBasic)ÚTuple)ÚArray©Ú_sympify)ÚflattenÚiterable)Úas_int)Údefaultdictc                   óØ   • \ rS rSrSrSrSrSrSr\	S 5       r
\	S 5       r\	S 5       r\	S 5       r\	S 5       r\S	 5       r\S
 5       r\S 5       rS r\S 5       rS rSS jrSS jrSrg)ÚPruferé   ap  
The Prufer correspondence is an algorithm that describes the
bijection between labeled trees and the Prufer code. A Prufer
code of a labeled tree is unique up to isomorphism and has
a length of n - 2.

Prufer sequences were first used by Heinz Prufer to give a
proof of Cayley's formula.

References
==========

.. [1] https://mathworld.wolfram.com/LabeledTree.html

Nc                 ó�   • U R                   c.  U R                  U R                  SS U R                  5      U l         U R                   $ )aØ  Returns Prufer sequence for the Prufer object.

This sequence is found by removing the highest numbered vertex,
recording the node it was attached to, and continuing until only
two vertices remain. The Prufer sequence is the list of recorded nodes.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer([[0, 3], [1, 3], [2, 3], [3, 4], [4, 5]]).prufer_repr
[3, 3, 3, 4]
>>> Prufer([1, 0, 0]).prufer_repr
[1, 0, 0]

See Also
========

to_prufer

N)Ú_prufer_reprÚ	to_pruferÚ
_tree_reprÚnodes©Úselfs    ÚW/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/combinatorics/prufer.pyÚprufer_reprÚPrufer.prufer_repr    s<   € ð. ×ÑÑ$Ø $§¡¨t¯©¹qÐ/AÀ4Ç:Á:Ó NˆDÔØ× Ñ Ð ó    c                 óz   • U R                   c#  U R                  U R                  SS 5      U l         U R                   $ )aB  Returns the tree representation of the Prufer object.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer([[0, 3], [1, 3], [2, 3], [3, 4], [4, 5]]).tree_repr
[[0, 3], [1, 3], [2, 3], [3, 4], [4, 5]]
>>> Prufer([1, 0, 0]).tree_repr
[[1, 2], [0, 1], [0, 3], [0, 4]]

See Also
========

to_tree

N)r   Úto_treer   r   s    r   Ú	tree_reprÚPrufer.tree_repr;   s3   € ð& �?‰?Ñ"Ø"Ÿl™l¨4×+<Ñ+<¹QÐ+?Ó@ˆDŒOØ�‰Ðr   c                 ó   • U R                   $ )zËReturns the number of nodes in the tree.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer([[0, 3], [1, 3], [2, 3], [3, 4], [4, 5]]).nodes
6
>>> Prufer([1, 0, 0]).nodes
5

)Ú_nodesr   s    r   r   ÚPrufer.nodesR   s   € ð �{‰{Ðr   c                 ó^   • U R                   c  U R                  5       U l         U R                   $ )a  Returns the rank of the Prufer sequence.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> p = Prufer([[0, 3], [1, 3], [2, 3], [3, 4], [4, 5]])
>>> p.rank
778
>>> p.next(1).rank
779
>>> p.prev().rank
777

See Also
========

prufer_rank, next, prev, size

)Ú_rankÚprufer_rankr   s    r   ÚrankÚPrufer.rankb   s(   € ð, �:‰:ÑØ×)Ñ)Ó+ˆDŒJØ�z‰zÐr   c                 ón   • U R                  U R                  5      R                  5       R                  S-   $ )zîReturn the number of possible trees of this Prufer object.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer([0]*4).size == Prufer([6]*4).size == 1296
True

See Also
========

prufer_rank, rank, next, prev

é   )Úprevr$   r   s    r   ÚsizeÚPrufer.size|   s+   € ð" �y‰y˜Ÿ™Ó#×(Ñ(Ó*×/Ñ/°!Ñ3Ð3r   c                 óÚ  • [        [        5      n/ nU  H!  nX$S   ==   S-  ss'   X$S   ==   S-  ss'   M#     [        US-
  5       H   n[        U5       H  nX&   S:X  d  M    O   SnU  H$  nWUS   :X  a  US   nOXdS   :X  a  US   nUc  M$    O   UR                  U5        WU4 H+  nX(==   S-  ss'   X(   (       a  M  UR	                  U5        M-     U R                  W5        M¢     U$ )a}  Return the Prufer sequence for a tree given as a list of edges where
``n`` is the number of nodes in the tree.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> a = Prufer([[0, 1], [0, 2], [0, 3]])
>>> a.prufer_repr
[0, 0]
>>> Prufer.to_prufer([[0, 1], [0, 2], [0, 3]], 4)
[0, 0]

See Also
========
prufer_repr: returns Prufer sequence of a Prufer object.

r   r'   é   N)r   ÚintÚrangeÚappendÚpopÚremove)	ÚtreeÚnÚdÚLÚedgeÚiÚxÚyÚjs	            r   r   ÚPrufer.to_prufer�   s÷   € ô( œÓˆØˆÛˆDð �1‰g‹J˜!‰O‹JØ�1‰g‹J˜!‰O�Jñ ô �q˜1‘u–ˆAä˜1–X�Ø‘4˜1•9Ùñ ð ˆAÛ�Ø˜˜Q™“<Ø˜Q™‘AØ˜q™'“\Ø˜Q™�AØ“=Ùñ ð �H‰H�QŒKØ˜“V�Ø“˜‘	“Ø—t‘tØ—E‘E˜!–Hñ ð �K‰K˜Öñ) ð* ˆr   c                 ó¬  • / n/ n[        U 5      S-   n[        S 5      nU  H  nXE==   S-  ss'   M     U  HS  n[        U5       H  nXG   S:X  d  M    O   XF==   S-  ss'   UW==   S-  ss'   UR                  [	        Xg/5      5        MU     [        U5       Vs/ s H  odU   S:X  d  M  UPM     sn=(       d    SS/nUR                  U5        U$ s  snf )aÊ  Return the tree (as a list of edges) of the given Prufer sequence.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> a = Prufer([0, 2], 4)
>>> a.tree_repr
[[0, 1], [0, 2], [2, 3]]
>>> Prufer.to_tree([0, 2])
[[0, 1], [0, 2], [2, 3]]

References
==========

.. [1] https://hamberg.no/erlend/posts/2010-11-06-prufer-sequence-compact-tree-representation.html

See Also
========
tree_repr: returns tree representation of a Prufer object.

r,   c                  ó   • g)Nr'   © r>   r   r   Ú<lambda>Ú Prufer.to_tree.<locals>.<lambda>Ý   s   €  r   r'   r   )Úlenr   r.   r/   Úsorted)Úpruferr2   Úlastr3   r4   Úpr7   r:   s           r   r   ÚPrufer.to_treeÂ   sË   € ð0 ˆØˆÜ�‹K˜!‰OˆÜ™	Ó"ˆÛˆAØ‹D�A‰I�Dñ ãˆAÜ˜1–X�à‘4˜1•9Ùñ ð ‹D�A‰I‹DØˆa‹D�A‰I‹DØ�K‰Kœ ˜v›Ö'ñ ô ! œ8Ó1š8�a¨¡t¨q¡y—™8Ñ1×;°a¸°VˆØ�‰�DÔàˆùò 2s   ÂCÂ*Cc                  ó  • [        5       nU S   S   nU  HC  n[        [        U5      S-
  5       H%  nX4US-    u  pVXe:  a  XepeUR                  XV45        M'     ME     / n[        5       nS=p)U H\  n
UR	                  U
5        Ub  [        U
S   U5      OU
S   nU	b  [        U
S   U	5      OU
S   n	UR                  [        U
5      5        M^     [        [        X)S-   5      5      U-
  nU(       aP  U Vs/ s H  oDU-   PM	     nn[        U5      S:X  a  SUR                  5       -  nOS[        U5      -  n[        U5      eUS:w  a/  [        U5       H  u  pJU
 Vs/ s H  oÝU-
  PM	     snXt'   M     X’-  n	[        U5      U	S-   4$ s  snf s  snf )aÉ  Return a list of edges and the number of nodes from the given runs
that connect nodes in an integer-labelled tree.

All node numbers will be shifted so that the minimum node is 0. It is
not a problem if edges are repeated in the runs; only unique edges are
returned. There is no assumption made about what the range of the node
labels should be, but all nodes from the smallest through the largest
must be present.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer.edges([1, 2, 3], [2, 4, 5]) # a T
([[0, 1], [1, 2], [1, 3], [3, 4]], 5)

Duplicate edges are removed:

>>> Prufer.edges([0, 1, 2, 3], [1, 4, 5], [1, 4, 6]) # a K
([[0, 1], [1, 2], [1, 4], [2, 3], [4, 5], [4, 6]], 7)

r   r'   r,   NúNode %s is missing.úNodes %s are missing.)Úsetr.   rA   ÚaddÚupdateÚminÚmaxr/   Úlistr0   rB   Ú
ValueErrorÚ	enumerate)ÚrunsÚeÚnminÚrr7   ÚaÚbÚrvÚgotÚnmaxÚeiÚmissingÚmsgr3   s                 r   ÚedgesÚPrufer.edgesï   sŠ  € ô0 ‹EˆØ�A‰w�q‰zˆÛˆAÜœ3˜q›6 A™:Ö&�Ø˜A ™E�{‘�Ø“5Ø�qØ—‘�q�f–ó	 'ñ ð ˆÜ‹eˆØÐˆÛˆBØ�J‰J�rŒNØ'+Ñ'7”3�r˜!‘u˜dÔ#¸RÀ¹UˆDØ'+Ñ'7”3�r˜!‘u˜dÔ#¸RÀ¹UˆDØ�I‰I”d˜2“hÖñ	 ô
 ”e˜D¨¡(Ó+Ó,¨sÑ2ˆÞÙ)0Ó1ª A˜4”x©ˆGÐ1Ü�7‹|˜qÓ Ø+¨g¯k©k«mÑ;‘à-´°w³Ñ?�Ü˜S“/Ð!Ø�1‹9Ü" 2ž‘�Ù+-Ó.ª2 a˜Tœ©2Ñ.�“ñ 'à‰LˆDÜ�b‹z˜4 !™8Ð#Ð#ùò 2ùò /s   Ã2FÅFc                 ó”   • SnSn[        U R                  S-
  SS5       H%  nXU R                  U   -  -  nX R                  -  nM'     U$ )zÙComputes the rank of a Prufer sequence.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> a = Prufer([[0, 1], [0, 2], [0, 3]])
>>> a.prufer_rank()
0

See Also
========

rank, next, prev, size

r   r'   é   éÿÿÿÿ)r.   r   r   )r   rU   rE   r7   s       r   r#   ÚPrufer.prufer_rank%  sS   € ð" ˆØˆÜ�t—z‘z A‘~ r¨2Ö.ˆAØ�4×#Ñ# AÑ&Ñ&Ñ&ˆAØ—‘‰OŠAñ /ð ˆr   c                 ó  • [        U5      [        U5      p[        [        5      n[        US-
  SS5       H  nX-  X4'   XU   -
  U-  nM     [	        [        [        U5      5       Vs/ s H  oCU   PM	     sn5      $ s  snf )z’Finds the unranked Prufer sequence.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> Prufer.unrank(0, 4)
Prufer([0, 0])

ra   rb   )r
   r   r-   r.   r   rA   )r   r$   r3   r5   r7   s        r   ÚunrankÚPrufer.unrank=  sv   € ô ˜“)œV D›\ˆ4ÜœÓˆÜ�q˜1‘u˜b "Ö%ˆAØ‘8ˆA‰DØ˜Q™4‘K !Ñ#ŠDñ &ô ¤U¬3¨q«6¤]Ó3¢] ˜”t¡]Ñ3Ó4Ð4ùÒ3s   Á'A<c                 ó&  • US   (       a  [        US   5      O	[        5       nU4[        S USS  5       5      -   n[        R                  " U /UQ70 UD6n[        US   5      /nUS   (       aö  [        US   S   5      (       aà  US   S   (       d  [        S5      e[        U5      S:”  a  US   nO‡[        [        US   5      5      n[        U5      S-   nU[        U5      :w  aS  [        [        U5      5      U-
  n[        U5      S:X  a  SUR                  5       -  nOS[        U5      -  n[        U5      eUS    V	s/ s H  n	[        U	5      PM     sn	Ul        XTl        U$ US   Ul        [        UR"                  5      S-   Ul        U$ s  sn	f )	a>  The constructor for the Prufer object.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer

A Prufer object can be constructed from a list of edges:

>>> a = Prufer([[0, 1], [0, 2], [0, 3]])
>>> a.prufer_repr
[0, 0]

If the number of nodes is given, no checking of the nodes will
be performed; it will be assumed that nodes 0 through n - 1 are
present:

>>> Prufer([[0, 1], [0, 2], [0, 3]], 4)
Prufer([[0, 1], [0, 2], [0, 3]], 4)

A Prufer object can be constructed from a Prufer sequence:

>>> b = Prufer([1, 3])
>>> b.tree_repr
[[0, 1], [1, 3], [2, 3]]

r   c              3   ó8   #   • U  H  n[        U5      v •  M     g 7f)Nr   )Ú.0Úargs     r   Ú	<genexpr>Ú!Prufer.__new__.<locals>.<genexpr>m  s   é € ÐAº°œx¨Ÿ}˜}ºùs   ‚r'   Nz-Prufer expects at least one edge in the tree.rH   rI   r,   )r   r   Útupler   Ú__new__rO   r	   rP   rA   rJ   r   rN   r.   r0   rB   r   r   r   )
ÚclsÚargsÚkw_argsÚarg0Úret_objÚnnodesr   r\   r]   r7   s
             r   rn   ÚPrufer.__new__P  sv  € ð8 "& a§Œu�T˜!‘WŒ~¬e«gˆØˆwœÑA¸¸Q¸R¹ÓAÓAÑAˆÜ—-’- Ð6 dÒ6¨gÑ6ˆÜ�T˜!‘W“ˆˆØ��7”x  Q¡¨¡
×+Ñ+Ø˜‘7˜1—:Ü ØCóEð Eä�4‹y˜1‹}Ø˜a™‘äœG D¨¡GÓ,Ó-�Ü˜U› a™�ØœS ›ZÓ'Ü!¤%¨£-Ó0°5Ñ8�GÜ˜7“| qÓ(Ø3°g·k±k³mÑC™à5¼¸w»ÑG˜Ü$ S›/Ð)Ø37¸²7Ó!;²7¨a¤$ q¦'±7Ñ!;ˆGÔØ#ŒNð ˆð $(¨¡7ˆGÔ Ü  ×!5Ñ!5Ó6¸Ñ:ˆGŒNØˆùò "<s   Å Fc                 ó\   • [         R                  U R                  U-   U R                  5      $ )a<  Generates the Prufer sequence that is delta beyond the current one.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> a = Prufer([[0, 1], [0, 2], [0, 3]])
>>> b = a.next(1) # == a.next()
>>> b.tree_repr
[[0, 2], [0, 1], [1, 3]]
>>> b.rank
1

See Also
========

prufer_rank, rank, prev, size

©r   re   r$   r   ©r   Údeltas     r   ÚnextÚPrufer.next‡  s"   € ô( �}‰}˜TŸY™Y¨Ñ.°·
±
Ó;Ð;r   c                 ó\   • [         R                  U R                  U-
  U R                  5      $ )a4  Generates the Prufer sequence that is -delta before the current one.

Examples
========

>>> from sympy.combinatorics.prufer import Prufer
>>> a = Prufer([[0, 1], [1, 2], [2, 3], [1, 4]])
>>> a.rank
36
>>> b = a.prev()
>>> b
Prufer([1, 2, 0])
>>> b.rank
35

See Also
========

prufer_rank, rank, next, size

rw   rx   s     r   r(   ÚPrufer.prev�  s"   € ô, �}‰}˜TŸY™Y¨Ñ-¨t¯z©zÓ:Ð:r   )r   r"   r   )r'   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   r   r"   Úpropertyr   r   r   r$   r)   Ústaticmethodr   r   r^   r#   Úclassmethodre   rn   rz   r(   Ú__static_attributes__r>   r   r   r   r      sç   † ñð €LØ€JØ€FØ€Eàñ!ó ð!ð4 ñó ðð, ñó ðð ñó ðð2 ñ4ó ð4ð$ ñ0ó ð0ðd ñ*ó ð*ðX ñ3$ó ð3$òjð0 ñ5ó ð5ò$5ôn<÷,;r   r   N)Ú
sympy.corer   Úsympy.core.containersr   Úsympy.tensor.arrayr   Úsympy.core.sympifyr   Úsympy.utilities.iterablesr   r	   Úsympy.utilities.miscr
   Úcollectionsr   r   r>   r   r   Ú<module>rŽ      s(   ðÝ Ý 'Ý $Ý 'ß 7Ý 'å #ôh;ˆUõ h;r   