
    wg                       d dl mZ d dlmZmZmZmZmZmZm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# d dl$m%Z%m&Z& d dl'm(Z( d Z)d Z*d Z+d Z,d9dZ-d Z.d Z/d:dZ0e1fdZ2d Z3d Z4d Z5d Z6d Z7d Z8d  Z9d:d!Z:d;d"Z; ed#d$d%&      d'        Z< ed(d$d%&      d)        Z= ed*d$d%&      d+        Z>d<d-Z?d<d.Z@d=d/ZAd>d0ZBd<d1ZCd?d2ZDd?d3ZEd4 ZFd5 ZGd6 ZHd7 ZId8 ZJy,)@    )annotations)gcdlcminvertsqrtjacobi	bit_scan1remove)Poly)ZZ)gf_crt1gf_crt2linear_congruence	gf_csolve   )isprime)
primerange)	factorint_perfect_powercrt)
deprecated)recurrence_memo)as_int)iproduct)_randintrandint)productc                   t        |       t        |      }} |dk  rt        d      | |z  } | dk(  ryt        | |      dk7  rt        d      d}t        |      j	                         D ]  \  }}||z  }|dz
  ||dz
  z  z  }t        |dz
        }|dkD  r|dz
  ||<   d}|j	                         D ]6  \  }	}
t        | ||	|
z  z  |      }|dk7  st        ||	|      }||	z  }|dk7  r8 t        ||      } t        |      S )a%   Returns the order of ``a`` modulo ``n``.

    Explanation
    ===========

    The order of ``a`` modulo ``n`` is the smallest integer
    ``k`` such that `a^k` leaves a remainder of 1 with ``n``.

    Parameters
    ==========

    a : integer
    n : integer, n > 1. a and n should be relatively prime

    Returns
    =======

    int : the order of ``a`` modulo ``n``

    Raises
    ======

    ValueError
        If `n \le 1` or `\gcd(a, n) \neq 1`.
        If ``a`` or ``n`` is not an integer.

    Examples
    ========

    >>> from sympy.ntheory import n_order
    >>> n_order(3, 7)
    6
    >>> n_order(4, 7)
    3

    See Also
    ========

    is_primitive_root
        We say that ``a`` is a primitive root of ``n``
        when the order of ``a`` modulo ``n`` equals ``totient(n)``

    r   %n should be an integer greater than 1*The two numbers should be relatively prime)r   
ValueErrorr   r   itemspowr   int)ana_orderpepepe_orderfactorsorderpxexxs               b/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/ntheory/residue_ntheory.pyn_orderr3      s0   X !9fQiqAAv@AA	AAAv
1ayA~EFFG!""$ &1TEQQZ'AE"q5QGAJmmo 	FBAx2r6)2.Aq&2rN q&	
 gu%& w<    c              #     K    dk(  rd y dz  dv rdnd} dk  r
 dk(  rdn|nWt         d	z
        j                         D cg c]
  } d	z
  |z   }}t        |       D ]  t         fd
|D              s n  t        d d      D ]$  }t	         d	z
  |      d	k(  st        |        & yc c}w w)a	   Generates the primitive roots for a prime ``p``.

    Explanation
    ===========

    The primitive roots generated are not necessarily sorted.
    However, the first one is the smallest primitive root.

    Find the element whose order is ``p-1`` from the smaller one.
    If we can find the first primitive root ``g``, we can use the following theorem.

    .. math ::
        \operatorname{ord}(g^k) = \frac{\operatorname{ord}(g)}{\gcd(\operatorname{ord}(g), k)}

    From the assumption that `\operatorname{ord}(g)=p-1`,
    it is a necessary and sufficient condition for
    `\operatorname{ord}(g^k)=p-1` that `\gcd(p-1, k)=1`.

    Parameters
    ==========

    p : odd prime

    Yields
    ======

    int
        the primitive roots of ``p``

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_iter
    >>> sorted(_primitive_root_prime_iter(19))
    [2, 3, 10, 13, 14, 15]

    References
    ==========

    .. [1] W. Stein "Elementary Number Theory" (2011), page 44

          N   )r      )         r   c              3  >   K   | ]  }t        |      d k7    ywr   Nr$   ).0pwgr)   s     r2   	<genexpr>z-_primitive_root_prime_iter.<locals>.<genexpr>   s     2"3q"a=A%2s   )r   keysrangeallr   r$   )r)   g_minivkrB   s   `    @r2   _primitive_root_prime_iterrK   [   s     V 	Av Q&AaE2vbAe#,QU#3#8#8#:;aa!e\;;ua 	A222	 G1a^ q1ua=AaA, <s   AB>B9&B>=)B>'B>c              #    K   |dk(  rt        |       E d{    y| dz  }t        |       D ]R  t        d| z
  |      z
  |z  }t        d||       D ]*  |k7  s	fdt        d| |z  |      D        E d{    , T y7 k7 w)am   Generates the primitive roots of `p^e`.

    Explanation
    ===========

    Let ``g`` be the primitive root of ``p``.
    If `g^{p-1} \not\equiv 1 \pmod{p^2}`, then ``g`` is primitive root of `p^e`.
    Thus, if we find a primitive root ``g`` of ``p``,
    then `g, g+p, g+2p, \ldots, g+(p-1)p` are primitive roots of `p^2` except one.
    That one satisfies `\hat{g}^{p-1} \equiv 1 \pmod{p^2}`.
    If ``h`` is the primitive root of `p^2`,
    then `h, h+p^2, h+2p^2, \ldots, h+(p^{e-2}-1)p^e` are primitive roots of `p^e`.

    Parameters
    ==========

    p : odd prime
    e : positive integer

    Yields
    ======

    int
        the primitive roots of `p^e`

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_power_iter
    >>> sorted(_primitive_root_prime_power_iter(5, 2))
    [2, 3, 8, 12, 13, 17, 22, 23]

    r   Nr7   r   c              3  .   K   | ]  }z   |z     y wN )r@   mrB   rJ   s     r2   rC   z3_primitive_root_prime_power_iter.<locals>.<genexpr>   s     FaA	F   )rK   r$   rE   )r)   r*   p2trB   rJ   s       @@r2    _primitive_root_prime_power_iterrT      s     D 	Av-a000T+A. 	GASAE2&&",A1b!_ G6F5AqD"3EFFFG	G 	1 Gs(   BBABB:B;
BBc              #  \   K   t        | |      D ]  }|dz  dk(  r| || |z  z     yw)a0   Generates the primitive roots of `2p^e`.

    Explanation
    ===========

    If ``g`` is the primitive root of ``p**e``,
    then the odd one of ``g`` and ``g+p**e`` is the primitive root of ``2*p**e``.

    Parameters
    ==========

    p : odd prime
    e : positive integer

    Yields
    ======

    int
        the primitive roots of `2p^e`

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_power2_iter
    >>> sorted(_primitive_root_prime_power2_iter(5, 2))
    [3, 13, 17, 23, 27, 33, 37, 47]

    r7   r   N)rT   )r)   r*   rB   s      r2   !_primitive_root_prime_power2_iterrV      s;     : .a3 q5A:Gad(N	s   *,c                B   t        |       } | dk  rt        d      | dk  r| dz
  S | dz  dk(  }|s| }n| dz  r| dz  }nyt        |      rd}n t        |d      }|sy|\  }}t        |      sy|s,|rt	        t        ||            S t	        t        ||            S |r(t        d| d      D ]  }||z  s	t        ||       s|c S  t	        t        |            }|dk(  st        ||dz
  |dz        dk7  r|S t        |dz   |       D ]  }||z  s	t        ||       s|c S  y)a   Returns a primitive root of ``p`` or None.

    Explanation
    ===========

    For the definition of primitive root,
    see the explanation of ``is_primitive_root``.

    The primitive root of ``p`` exist only for
    `p = 2, 4, q^e, 2q^e` (``q`` is an odd prime).
    Now, if we know the primitive root of ``q``,
    we can calculate the primitive root of `q^e`,
    and if we know the primitive root of `q^e`,
    we can calculate the primitive root of `2q^e`.
    When there is no need to find the smallest primitive root,
    this property can be used to obtain a fast primitive root.
    On the other hand, when we want the smallest primitive root,
    we naively determine whether it is a primitive root or not.

    Parameters
    ==========

    p : integer, p > 1
    smallest : if True the smallest primitive root is returned or None

    Returns
    =======

    int | None :
        If the primitive root exists, return the primitive root of ``p``.
        If not, return None.

    Raises
    ======

    ValueError
        If `p \le 1` or ``p`` is not an integer.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import primitive_root
    >>> primitive_root(19)
    2
    >>> primitive_root(21) is None
    True
    >>> primitive_root(50, smallest=False)
    27

    See Also
    ========

    is_primitive_root

    References
    ==========

    .. [1] W. Stein "Elementary Number Theory" (2011), page 44
    .. [2] P. Hackman "Elementary Number Theory" (2009), Chapter C

    r   %p should be an integer greater than 1   r7   r   Nr6   )r   r"   r   r   nextrV   rT   rE   is_primitive_rootrK   r$   )r)   smallestp_evenqr*   rP   rH   rB   s           r2   primitive_rootr_      sK   | 	q	AAv@AAAv1uUaZF	
QqDqz1a 1qz9!Q?@@4Q:;;q!Q 	A1u*1a0	 	'*+AAvQAq!t$)1q5!_ q5&q!,Hr4   c                $    t               t              c dk  rt        d       z   t               dk7  rt        d      dk  r dz
  k(  S dz  r}ndz  rdz  }nyt        |      r"|dz
  t	        |dz
        j                         }ndt        |d      }|sy|\  }}t        |      sy||dz
  z  |dz
  z  t        t	        |dz
        j                               }|j                  |       t         fd|D              S )	a;   Returns True if ``a`` is a primitive root of ``p``.

    Explanation
    ===========

    ``a`` is said to be the primitive root of ``p`` if `\gcd(a, p) = 1` and
    `\phi(p)` is the smallest positive number s.t.

        `a^{\phi(p)} \equiv 1 \pmod{p}`.

    where `\phi(p)` is Euler's totient function.

    The primitive root of ``p`` exist only for
    `p = 2, 4, q^e, 2q^e` (``q`` is an odd prime).
    Hence, if it is not such a ``p``, it returns False.
    To determine the primitive root, we need to know
    the prime factorization of ``q-1``.
    The hardness of the determination depends on this complexity.

    Parameters
    ==========

    a : integer
    p : integer, ``p`` > 1. ``a`` and ``p`` should be relatively prime

    Returns
    =======

    bool : If True, ``a`` is the primitive root of ``p``.

    Raises
    ======

    ValueError
        If `p \le 1` or `\gcd(a, p) \neq 1`.
        If ``a`` or ``p`` is not an integer.

    Examples
    ========

    >>> from sympy.functions.combinatorial.numbers import totient
    >>> from sympy.ntheory import is_primitive_root, n_order
    >>> is_primitive_root(3, 10)
    True
    >>> is_primitive_root(9, 10)
    False
    >>> n_order(3, 10) == totient(10)
    True
    >>> n_order(9, 10) == totient(10)
    False

    See Also
    ========

    primitive_root

    r   rX   r!   rY   r7   Fr6   c              3  D   K   | ]  }t        |z        d k7    ywr>   r?   )r@   primer&   group_orderr)   s     r2   rC   z$is_primitive_root.<locals>.<genexpr>  s$     Is1kU*A.!3Is    )
r   r"   r   r   r   rD   r   setaddrF   )r&   r)   r^   r-   rP   r*   rc   s   ``    @r2   r[   r[   O  s   t !9fQiDAqAv@AA	AA
1ayA~EFF 	AvAEz1u	
QqDqz!eAE"'')1a 1qz!a%j!a%(iA&++-.AIIIIr4   c                   t        |dz
        }||z	  }|dz  dk(  rd}n+|dz  dv rd}n!	 t        d|dz
        }t        ||      dk(  rn t        | ||      }t        |||      }d}t	        |      D ]?  }|t        |||      z  |z  }	t        |	d	|dz
  |z
  z  |      }	|	|z  |dz
  k(  s8|d	|z  z  }A t        | |dz   d	z  |      t        ||d	z  |      z  |z  }
|
S )
a  
    Returns the square root in the case of ``p`` prime with ``p == 1 (mod 8)``

    Assume that the root exists.

    Parameters
    ==========

    a : int
    p : int
        prime number. should be ``p % 8 == 1``

    Returns
    =======

    int : Generally, there are two roots, but only one is returned.
          Which one is returned is random.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _sqrt_mod_tonelli_shanks
    >>> _sqrt_mod_tonelli_shanks(2, 17) in [6, 11]
    True

    References
    ==========

    .. [1] Carl Pomerance, Richard Crandall, Prime Numbers: A Computational Perspective,
           2nd Edition (2005), page 101, ISBN:978-0387252827

    r      r<   r6   )r7   r6      r   r7   )r	   r   r   r$   rE   )r&   r)   srS   dADrP   rH   admr1   s              r2   _sqrt_mod_tonelli_shanksro     s   B 	!a%A	QA2v{	
Q&1q5!Aa|r! 
 	Aq!AAq!A	A1X Aq!nq #q1q519~q)7a!eAIA	 	AAz1c!QT1o-1AHr4   c                    |rt        t        | |            S t        t        |            }|dz  }d}t        | |      D ]  }||k  r|c S ||kD  r||z
  c S |} |S )a  
    Find a root of ``x**2 = a mod p``.

    Parameters
    ==========

    a : integer
    p : positive integer
    all_roots : if True the list of roots is returned or None

    Notes
    =====

    If there is no root it is returned None; else the returned root
    is less or equal to ``p // 2``; in general is not the smallest one.
    It is returned ``p // 2`` only if it is the only root.

    Use ``all_roots`` only when it is expected that all the roots fit
    in memory; otherwise use ``sqrt_mod_iter``.

    Examples
    ========

    >>> from sympy.ntheory import sqrt_mod
    >>> sqrt_mod(11, 43)
    21
    >>> sqrt_mod(17, 32, True)
    [7, 9, 23, 25]
    r7   N)sortedsqrt_mod_iterabsr   )r&   r)   	all_rootshalfpr1   rs         r2   sqrt_modrw     sr    < mAq)**F1IAFEA1a  u9HYq5LA Hr4   c              #    K   t        |       t        t        |            }} g }g }t        }t        |      j	                         D ]T  \  }}| |z  rt        | ||      }nt        | ||      }t        }|s y|j                  |       |j                  ||z         V t        |      dk(  rt        ||d         E d{    yt        |t              \  }	}
} || D ]  } |t        |||	|
|t                       y7 @w)a  
    Iterate over solutions to ``x**2 = a mod p``.

    Parameters
    ==========

    a : integer
    p : positive integer
    domain : integer domain, ``int``, ``ZZ`` or ``Integer``

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import sqrt_mod_iter
    >>> list(sqrt_mod_iter(11, 43))
    [21, 22]

    See Also
    ========

    sqrt_mod : Same functionality, but you want a sorted list or only one solution.

    Nr   r   )r   rs   r   r   r#   _sqrt_mod_prime_power
_sqrt_mod1r   appendlenmapr   r   r   )r&   r)   domainrI   pv_productr/   r0   rxmmr*   rj   vxs                r2   rr   rr     s     0 !9c&)nqA
A	BHA,$$& Br6&q"b1B
 Ar2&BH	
		"b& 1v{vqt$$$2r?AqA, 	8BRQ2677	8 	%s   B:C?<C==AC?c                   ||z  }| |z  } |dk(  rx| dz  dk7  ry|dk  rt        t        d|d            S d}t        d|      D ]  }|dz  | z
  |z	  dz  s|d|dz
  z  z  } d|dz
  z  }t        |||z
  ||z   |z  ||z    |z  g      S t        | |      dk7  ry|dz  dk(  rt	        | |dz   dz  |      }nT|dz  dk(  r@t	        | |dz   dz  |      }t	        |d|      | |z  k7  r&|t	        d|dz
  dz  |      z  |z  }nt        | |      }|dkD  rp|}t        |j                         dz
        D ]'  }	|dz  }t        d|z  |      }
||dz  | z
  |
z  z
  |z  }) ||dz
  z  r t        d|z  |      }
||dz  | z
  |
z  z
  |z  }t        |||z
  g      S )aS  
    Find the solutions to ``x**2 = a mod p**k`` when ``a % p != 0``.
    If no solution exists, return ``None``.
    Solutions are returned in an ascending list.

    Parameters
    ==========

    a : integer
    p : prime number
    k : positive integer

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _sqrt_mod_prime_power
    >>> _sqrt_mod_prime_power(11, 43, 1)
    [21, 22]

    References
    ==========

    .. [1] P. Hackman "Elementary Number Theory" (2009), page 160
    .. [2] http://www.numbertheory.org/php/squareroot.html
    .. [3] [Gathen99]_
    r7   r8   r   Nr6   rY   r<   )listrE   rq   r   r$   ro   
bit_lengthr   )r&   r)   rJ   pkrv   nxhresr/   _frinvs              r2   ry   ry   F  s   6 
AB	BAAvq5A:6aQ((
 1+ 	#BAb A%Q26]"	#
 !a%Lq"q&1q5B,!a%2>?? a|q1uz!a!e\1%	
Q!!a!e\1%sAq>QU"AA!|Q//!3C&q!,1u q||~)* 	2AQB1S5"%E#q&1*e++r1C	2 A;1S5"%E#q&1*e++r1C3S/""r4   c                    z  | z  } | dk(  rt        ddz   dz  z        S t        |       \  } }|dz  dk(  ryt        | |z
        }|y|dz  fd|D        S )a<  
    Find solution to ``x**2 == a mod p**n`` when ``a % p == 0``.
    If no solution exists, return ``None``.

    Parameters
    ==========

    a : integer
    p : prime number, p must divide a
    n : positive integer

    References
    ==========

    .. [1] http://www.numbertheory.org/php/squareroot.html
    r   r   r7   Nc              3  ^   K   | ]$  }t        |z  z  z
  z        D ]  }|  & y wrN   rE   )r@   r   r1   rP   r'   r)   pns      r2   rC   z_sqrt_mod1.<locals>.<genexpr>  s6     D"U2ad7BAE
%CDADADs   *-)rE   r
   ry   )r&   r)   r'   rv   r   rP   r   s    ``  @@r2   rz   rz     s    " 
AB	BAAvQAQ1-..!Q<DAq1uz
1a!e
,C
{	QADDDr4   c                   t        |       t        |      }} |dk  rt        d      | |z  } | dk  s|dk  ryt        |      }|r8| d|z  z  }|rt        |      }|dz  s||z	  dz  ry||z  }| |z  } | dk  s|dk  ryt        | |      }|dk(  st	        |      r|dk(  S t        |      j                         D ]O  \  }}| |z  rt        | |      dk7  s y| ||z  z  }|d	k(  r+t        ||      \  }}|dz  st        ||      dk7  sO y y)
a  
    Returns True if ``a`` (mod ``p``) is in the set of squares mod ``p``,
    i.e a % p in set([i**2 % p for i in range(p)]).

    Parameters
    ==========

    a : integer
    p : positive integer

    Returns
    =======

    bool : If True, ``x**2 == a (mod p)`` has solution.

    Raises
    ======

    ValueError
        If ``a``, ``p`` is not integer.
        If ``p`` is not positive.

    Examples
    ========

    >>> from sympy.ntheory import is_quad_residue
    >>> is_quad_residue(21, 100)
    True

    Indeed, ``pow(39, 2, 100)`` would be 21.

    >>> is_quad_residue(21, 120)
    False

    That is, for any integer ``x``, ``pow(x, 2, 120)`` is not 21.

    If ``p`` is an odd
    prime, an iterative method is used to make the determination:

    >>> from sympy.ntheory import is_quad_residue
    >>> sorted(set([i**2 % 7 for i in range(7)]))
    [0, 1, 2, 4]
    >>> [j for j in range(7) if is_quad_residue(j, 7)]
    [0, 1, 2, 4]

    See Also
    ========

    legendre_symbol, jacobi_symbol, sqrt_mod
    r   zp must be > 0r7   r6   Trh   Fri   r   )r   r"   r	   r   r   r   r#   r
   )r&   r)   rS   a_rv   jr/   r0   s           r2   is_quad_residuer     s;   f !9fQiqA1u))FA1uA 	!A !q&\"A1uqA	a	Qq5AEq!ABw'!*AvA,$$& 
Br6a}!RVBQw2rNEB1ur2!+
 r4   c                F     |z   t               t              t        |      c }|dk  rt        d      dk  rt        d      dk(  r|dk(  ry dk(  S  dk(  rydk(  rydk(  rt         |      S t         fdt	        |      j                         D              S )	z
    Returns True if ``x**n == a (mod m)`` has solutions.

    References
    ==========

    .. [1] P. Hackman "Elementary Number Theory" (2009), page 76

    r   zm must be > 0zn must be >= 0r   FTr7   c              3  @   K   | ]  \  }}t        ||        y wrN   )#_is_nthpow_residue_bign_prime_power)r@   r)   r*   r&   r'   s      r2   rC   z$is_nthpow_residue.<locals>.<genexpr>'  s(      11a 31aA> 1s   )r   r"   r   rF   r   r#   )r&   r'   rP   s   `` r2   is_nthpow_residuer     s     	
AAQiF1IGAq!Av))1u)**Av6AvAvAvAvq!$$ 1$Q<--/1 1 1r4   c                P   | |z  dk(  r5| t        ||      z  } | syt        | |      \  } }||z  ry||z  }| |z  dk(  r5|dk7  r5||dz
  z  |dz
  z  }t        | |t        ||      z  t        ||            dk(  S |dz  ryt        t	        |      dz   |      }| t        d|      z  dk(  S )z
    Returns True if `x^n = a \pmod{p^k}` has solutions for `n > 2`.

    Parameters
    ==========

    a : positive integer
    n : integer, n > 2
    p : prime number
    k : positive integer

    r   TFr7   r   )r$   r
   r   minr	   )r&   r'   r)   rJ   mufcs          r2   r   r   +  s     a%1*	SAYq!26	R a%1* 	AvAJA1a3q!9nc!Qi0A551uIaL1a As1ay=Ar4   c           
     n   t        t        |            }| }t        |      j                         D ]  \  }}|dz
  ||z  z  }||z  dk(  r||z  }||z  dk(  r|t	        | |      z  }	d|	z   |z  }
t        |t        |||      t        |||z  |            }t        |      D ]/  }t        ||
|      t        ||	 |z  |dz
  z  |      z  |z  }||z  }1  |g}t        ||dz
  |z  |      }|}t        |dz
        D ]  }||z  |z  }|j                  |        |r|j                          |S t        |      S )aE  
    Root of ``x**q = s mod p``, ``p`` prime and ``q`` divides ``p - 1``.
    Assume that the root exists.

    Parameters
    ==========

    s : integer
    q : integer, n > 2. ``q`` divides ``p - 1``.
    p : prime number
    all_roots : if False returns the smallest root, else the list of roots

    Returns
    =======

    list[int] | int :
        Root of ``x**q = s mod p``. If ``all_roots == True``,
        returned ascending list. otherwise, returned an int.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _nthroot_mod1
    >>> _nthroot_mod1(5, 3, 13, False)
    7
    >>> _nthroot_mod1(13, 4, 17, True)
    [3, 5, 12, 14]

    References
    ==========

    .. [1] A. M. Johnston, A Generalized qth Root Algorithm,
           ACM-SIAM Symposium on Discrete Algorithms (1999), pp. 929-930

    r   r   )rZ   rK   r   r#   r   discrete_logr$   rE   r{   sortr   )rj   r^   r)   rt   rB   rv   qxr0   r   zr1   rS   r   r   r   hxs                   r2   _nthroot_mod1r   I  sg   H 	'*+A	AA,$$& 
BUr2v"fk"HA "fkfaRnUrMC1aL#a2q/:r 	AAq!SQBqDAENA66:A"HA	
 #CAA!|QA	
B1q5\ daZ

2 

s8Or4   c                n   t        | |||      sg S | |z  }|dk(  rdg}n|dz
  |z  dk(  rt        |||d      }nu|}|dz
  }d}||k  r||||f\  }}}}|r.t        ||      \  }	}
t        ||	 |      |z  |z  }||
}}||}}|r.|dk(  r|g}n#|dk(  rt	        ||d      }nt        |||d      }|dk(  r|S | ||z  z  } t               }|D ]  }t        ||dz
  |      |z  |z  }|}|dk7  rSt        ||      }t        |dz
        D ]$  }||z  }t        |||      | z
  }||z  }||z
  |z  }& |j                  |       s|h}t        |dz
        D ]T  }||z  }t               }|D ]<  }t        |||      | |z  k7  r||vs|j                  |       |||z  z   |z  }||vr!> |}V ||z  } t        |      S )a,   Root of ``x**n = a mod p**k``.

    Parameters
    ==========

    a : integer
    n : integer, n > 2
    p : prime number
    k : positive integer

    Returns
    =======

    list[int] :
        Ascending list of roots of ``x**n = a mod p**k``.
        If no solution exists, return ``[]``.

    r   r   T)rt   r7   )
r   r   divmodr$   rw   rd   r   rE   re   rq   )r&   r'   r)   rJ   a_mod_p
base_rootspapbbr^   pcr   	tot_rootsrootdiffnew_basem_invr   tmproots_in_base	new_rootsk_s                         r2   _nthroot_mod_prime_powerr     s[   & /q!Q:	!eG!|S

a%1	"7AqDA
 U7!"B!3GRB 2rNEArAr1'!+ABAQG	 
 7!J1W!'1=J&wAFJAvAIAI 24Q"1$q(194OE1q5\ /A$8,q0us
h.	/
 MM$!FM1q5\ 	*AE	' ?B2q(+q8|; I-!b) HM2h> I-? !*	* "M1I/20 )r4   c                l   | |z  } t        |       t        |      t        |      }}} |dk  rt        d      |dk  rt        d      |dk(  r|r| gS | S |dk(  rt        | ||      S g }g }t        |      j	                         D ]M  \  }}t        | |||      }|s
|rg c S dc S |j                  ||z         |j                  t        |             O t        |t              \  }	}
}t        t        t        t        | D ch c]  }t        |||	|
|t               c}            }|r|S |r|d   S yc c}w )a  
    Find the solutions to ``x**n = a mod p``.

    Parameters
    ==========

    a : integer
    n : positive integer
    p : positive integer
    all_roots : if False returns the smallest root, else the list of roots

    Returns
    =======

        list[int] | int | None :
            solutions to ``x**n = a mod p``.
            The table of the output type is:

            ========== ========== ==========
            all_roots  has roots  Returns
            ========== ========== ==========
            True       Yes        list[int]
            True       No         []
            False      Yes        int
            False      No         None
            ========== ========== ==========

    Raises
    ======

        ValueError
            If ``a``, ``n`` or ``p`` is not integer.
            If ``n`` or ``p`` is not positive.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import nthroot_mod
    >>> nthroot_mod(11, 4, 19)
    8
    >>> nthroot_mod(11, 4, 19, True)
    [8, 11]
    >>> nthroot_mod(68, 3, 109)
    23

    References
    ==========

    .. [1] P. Hackman "Elementary Number Theory" (2009), page 76

    r   zn should be positivezp should be positiver7   Nr   )r   r"   rw   r   r#   r   r{   rq   r   r   r}   r%   r   r   )r&   r'   r)   rt   baseprime_powerr^   r*   r   PESr   rets                 r2   nthroot_modr     sT   h 	
AAQiF1I!qA1u/001u/00Avs&Q&Av1i((DK!""$ '1,Q1a8	"2,,1a4 F9%&' k2&GAq!
S$+TN4  #1k1aB? 4 5 6C

1v 	4s   ?D1c                    t        |       } t        | dz  dz         D ch c]  }t        |d|        }}t        |      S c c}w )z
    Returns the list of quadratic residues.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import quadratic_residues
    >>> quadratic_residues(7)
    [0, 1, 2, 4]
    r7   r   )r   rE   r$   rq   )r)   rH   rv   s      r2   quadratic_residuesr   %  sD     	q	A$Q!VaZ01!Q11A1!9 	2s   A z~The `sympy.ntheory.residue_ntheory.legendre_symbol` has been moved to `sympy.functions.combinatorial.numbers.legendre_symbol`.z1.13z%deprecated-ntheory-symbolic-functions)deprecated_since_versionactive_deprecations_targetc                     ddl m}  || |      S )a2  
    Returns the Legendre symbol `(a / p)`.

    .. deprecated:: 1.13

        The ``legendre_symbol`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.legendre_symbol`
        instead. See its documentation for more information. See
        :ref:`deprecated-ntheory-symbolic-functions` for details.

    For an integer ``a`` and an odd prime ``p``, the Legendre symbol is
    defined as

    .. math ::
        \genfrac(){}{}{a}{p} = \begin{cases}
             0 & \text{if } p \text{ divides } a\\
             1 & \text{if } a \text{ is a quadratic residue modulo } p\\
            -1 & \text{if } a \text{ is a quadratic nonresidue modulo } p
        \end{cases}

    Parameters
    ==========

    a : integer
    p : odd prime

    Examples
    ========

    >>> from sympy.functions.combinatorial.numbers import legendre_symbol
    >>> [legendre_symbol(i, 7) for i in range(7)]
    [0, 1, 1, -1, 1, -1, -1]
    >>> sorted(set([i**2 % 7 for i in range(7)]))
    [0, 1, 2, 4]

    See Also
    ========

    is_quad_residue, jacobi_symbol

    r   )legendre_symbol)%sympy.functions.combinatorial.numbersr   )r&   r)   _legendre_symbols      r2   r   r   5  s    Z ZAq!!r4   zzThe `sympy.ntheory.residue_ntheory.jacobi_symbol` has been moved to `sympy.functions.combinatorial.numbers.jacobi_symbol`.c                     ddl m}  || |      S )a  
    Returns the Jacobi symbol `(m / n)`.

    .. deprecated:: 1.13

        The ``jacobi_symbol`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.jacobi_symbol`
        instead. See its documentation for more information. See
        :ref:`deprecated-ntheory-symbolic-functions` for details.

    For any integer ``m`` and any positive odd integer ``n`` the Jacobi symbol
    is defined as the product of the Legendre symbols corresponding to the
    prime factors of ``n``:

    .. math ::
        \genfrac(){}{}{m}{n} =
            \genfrac(){}{}{m}{p^{1}}^{\alpha_1}
            \genfrac(){}{}{m}{p^{2}}^{\alpha_2}
            ...
            \genfrac(){}{}{m}{p^{k}}^{\alpha_k}
            \text{ where } n =
                p_1^{\alpha_1}
                p_2^{\alpha_2}
                ...
                p_k^{\alpha_k}

    Like the Legendre symbol, if the Jacobi symbol `\genfrac(){}{}{m}{n} = -1`
    then ``m`` is a quadratic nonresidue modulo ``n``.

    But, unlike the Legendre symbol, if the Jacobi symbol
    `\genfrac(){}{}{m}{n} = 1` then ``m`` may or may not be a quadratic residue
    modulo ``n``.

    Parameters
    ==========

    m : integer
    n : odd positive integer

    Examples
    ========

    >>> from sympy.functions.combinatorial.numbers import jacobi_symbol, legendre_symbol
    >>> from sympy import S
    >>> jacobi_symbol(45, 77)
    -1
    >>> jacobi_symbol(60, 121)
    1

    The relationship between the ``jacobi_symbol`` and ``legendre_symbol`` can
    be demonstrated as follows:

    >>> L = legendre_symbol
    >>> S(45).factors()
    {3: 2, 5: 1}
    >>> jacobi_symbol(7, 45) == L(7, 3)**2 * L(7, 5)**1
    True

    See Also
    ========

    is_quad_residue, legendre_symbol
    r   )jacobi_symbol)r   r   )rP   r'   _jacobi_symbols      r2   r   r   f  s    F V!Qr4   zlThe `sympy.ntheory.residue_ntheory.mobius` has been moved to `sympy.functions.combinatorial.numbers.mobius`.c                    ddl m}  ||       S )a  
    Mobius function maps natural number to {-1, 0, 1}

    .. deprecated:: 1.13

        The ``mobius`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.mobius`
        instead. See its documentation for more information. See
        :ref:`deprecated-ntheory-symbolic-functions` for details.

    It is defined as follows:
        1) `1` if `n = 1`.
        2) `0` if `n` has a squared prime factor.
        3) `(-1)^k` if `n` is a square-free positive integer with `k`
           number of prime factors.

    It is an important multiplicative function in number theory
    and combinatorics.  It has applications in mathematical series,
    algebraic number theory and also physics (Fermion operator has very
    concrete realization with Mobius Function model).

    Parameters
    ==========

    n : positive integer

    Examples
    ========

    >>> from sympy.functions.combinatorial.numbers import mobius
    >>> mobius(13*7)
    1
    >>> mobius(1)
    1
    >>> mobius(13*7*5)
    -1
    >>> mobius(13**2)
    0

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/M%C3%B6bius_function
    .. [2] Thomas Koshy "Elementary Number Theory with Applications"

    r   )mobius)r   r   )r'   _mobiuss     r2   r   r     s    d H1:r4   Nc                z    || z  }|| z  }|| }d}t        |      D ]  }||k(  r|c S ||z  | z  } t        d      )a  
    Trial multiplication algorithm for computing the discrete logarithm of
    ``a`` to the base ``b`` modulo ``n``.

    The algorithm finds the discrete logarithm using exhaustive search. This
    naive method is used as fallback algorithm of ``discrete_log`` when the
    group order is very small.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_trial_mul
    >>> _discrete_log_trial_mul(41, 15, 7)
    3

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    r   Log does not exist)rE   r"   )r'   r&   r   r.   r1   rH   s         r2   _discrete_log_trial_mulr     s_    6 FAFA}	A5\ 6HEAI )
**r4   c                   || z  }|| z  }|t        ||       }t        |      dz   }i }d}t        |      D ]  }|||<   ||z  | z  } t        || |       }|}t        |      D ]  }||v r||z  ||   z   c S ||z  | z  } t	        d      )ae  
    Baby-step giant-step algorithm for computing the discrete logarithm of
    ``a`` to the base ``b`` modulo ``n``.

    The algorithm is a time-memory trade-off of the method of exhaustive
    search. It uses `O(sqrt(m))` memory, where `m` is the group order.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_shanks_steps
    >>> _discrete_log_shanks_steps(41, 15, 7)
    3

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    r   r   )r3   r   rE   r$   r"   )	r'   r&   r   r.   rP   Tr1   rH   r   s	            r2   _discrete_log_shanks_stepsr   
  s    4 FAFA}1UaA
A	A1X !EAI 	Ar1A	A1X 6q51Q4<EAI )
**r4   c                   || z  }|| z  }|t        ||       }t        |      }t        |      D ]  } |d|dz
        } |d|dz
        }	t        |||       t        ||	|       z  | z  }
|
dz  }|dk(  r||
z  | z  }|}|	dz   |z  }n0|dk(  r|
|
z  | z  }||z   |z  }|	|	z   |z  }n||
z  | z  }|dz   |z  }|	}t        |      D ]   }|
dz  }|dk(  r||
z  | z  }
|	dz   |z  }	n.|dk(  r|
|
z  | z  }
||z   |z  }|	|	z   |z  }	n||
z  | z  }
|dz   |z  }|dz  }|dk(  r||z  | z  }|dz   |z  }n.|dk(  r||z  | z  }||z   |z  }||z   |z  }n||z  | z  }|dz   |z  }|dz  }|dk(  r||z  | z  }|dz   |z  }n.|dk(  r||z  | z  }||z   |z  }||z   |z  }n||z  | z  }|dz   |z  }|
|k(  s|	|z
  |z  }	 t	        ||      ||z
  z  |z  }t        |||       |z
  | z  dk(  r|c c S 	    t        d      # t
        $ r Y w xY w)ag  
    Pollard's Rho algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    It is a randomized algorithm with the same expected running time as
    ``_discrete_log_shanks_steps``, but requires a negligible amount of memory.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pollard_rho
    >>> _discrete_log_pollard_rho(227, 3**7, 3)
    7

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    r   r6   r   z&Pollard's Rho failed to find logarithm)r3   r   rE   r$   r   ZeroDivisionErrorr"   )r'   r&   r   r.   retriesrseedr   rH   aabaxar   xbabbbr   rv   r*   s                     r2   _discrete_log_pollard_rhor   7  s   4 FAFA}1uoG7^ @Q	"Q	"B]SB]*Q.F6R!BBq&E!B!Vb1Br'U"Br'U"BR!Bq&E!BBu -	AQAAvVaZ1f%a"Wq[2g&2g&VaZ1f%QAAvVaZ1f%a"Wq[2g&2g&VaZ1f%QAAvVaZ1f%a"Wq[2g&2g&VaZ1f%Rx"W%q%(BG4u<AAq!q(A-2  3 [-	'@B =
>> ) s   /,G33	G?>G?c                    dgt        |      z  }t        |      D ])  \  }}| |z  dk(  s||xx   dz  cc<   | |z  } | |z  dk(  r+ | dk7  ry|S )zTry to factor n with respect to a given factorbase.
    Upon success a list of exponents with repect to the factorbase is returned.
    Otherwise None.r   r   N)r|   	enumerate)r'   
factorbaser-   rH   r)   s        r2   _discrete_log_is_smoothr     sk     c#j/!G*% 1!eqjAJ!OJQA !eqj 	AvNr4   c                   t        |      }ddlm}m}m} || z  }|| z  }t         |d | ||        | ||             z        z  dd | ||             z  z   z              }	d|	z  |	z  }
t        t        |	            }t        |      }|dz
  }|}t        |      D ]@  }|dk(  r
||z
  |z  c S t        ||      }|r|D cg c]  }||z  	 c}|gz   } n||z  | z  }B t        d      dg|z  }d}d}|d|z  k  ro||
k  ri |d|      }t        t        |||       |      }||dz  }7|dz  }d}||gz  }|}t        |      D ]U  }||   |z  }|dkD  r0||   +t        |dz         D ]  }||   |||   |   z  z
  |z  ||<    n|||<   ||   dkD  sN||k(  sT|}W ||k(  s||   t        ||   d	|      }t        ||dz         D ]  }|||   z  |z  ||<    |||<   t        |      D ]H  }||   dkD  r4||   /||   }t        |dz         D ]  }||   |||   |   z  z
  |z  ||<    ||   dkD  sH n) |||   z
  |z  }t        |||       |k(  r|S t        d      |d|z  k  r||
k  rit        d      c c}w )
a  
    Index Calculus algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    The group order must be given and prime. It is not suitable for small orders
    and the algorithm might fail to find a solution in such situations.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_index_calculus
    >>> _discrete_log_index_calculus(24570203447, 23859756228, 2, 12285101723)
    4519867240

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    r   )r   explogg      ?r   r<   zIndex Calculus failedNr6   ri   )r   mathr   r   r   r%   r   r   r|   rE   r   r"   r$   )r'   r&   r   r.   r   r   r   r   r   Bmaxr   lfordermoabxr1   	relationarv   	relationsrJ   kkrelationindexrH   rir   rinvrbis                               r2   _discrete_log_index_calculusr     sN   4 uoG##FAFA
 	CdCFSQ[022Q3s1v;5FHIJA
a%!)Cjm$J	ZBAgG
C5\ 
2!8AI&&+C<	,56qU6!<IAgk
2 011I	A	
B
a"f*cAg*3q1:zB!GB	QaEr 	A!u$B1u11r!t MA#+A;IaLO1C#Cu"LHQKM !{Q5B;	 B;)E*68E?2e,uRT" 	5A!,u4HQK	5#	%r 	6A|aIaL$<lr!t PA$-aL3y|A3F$F%#OIaLP|a	6 	"%.A1QqzQ455M a"f*cN ,
--c 7s   I8c           
        ddl m} || z  }|| z  }|t        ||       }|t        |      }dgt	        |      z  }t        |j                               D ]r  \  }\  }}	t        |	      D ]\  }
t        |t        |||    |       z  |||
dz   z  z  |       }t        |||z  |       }t        | |||d      }||xx   |||
z  z  z  cc<   ^ t  ||j                         D 	cg c]
  \  }}	||	z   c}	}|      \  }}|S c c}	}w )a  
    Pohlig-Hellman algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    In order to compute the discrete logarithm, the algorithm takes advantage
    of the factorization of the group order. It is more efficient when the
    group order factors into many small primes.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pohlig_hellman
    >>> _discrete_log_pohlig_hellman(251, 210, 71)
    197

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    r   r   r   T)
modularr   r3   r   r|   r   r#   rE   r$   r   )r'   r&   r   r.   order_factorsr   lrH   pir   r   ajbjcjrk   r   s                   r2   _discrete_log_pohlig_hellmanr     s#   6 FAFA}1!%(	
c-  A !4!4!67 8Br 	AQQ1q))5BQK+?CBQQ'BaRT2BaDBQJD		 ]%8%8%:;62rB;Q?DAqH <s   C;
c           	     f   ddl m}m} t        |       t        |      t        |      }}} |i }t	        |       j                         D ]b  \  }}	|	dkD  r||v r||xx   |	dz
  z  cc<   n|	dz
  ||<   t	        |dz
        j                         D ]  \  }
}|
|v r||
xx   |z  cc<   |||
<    d d}|j                         D ]  \  }}	|||	z  z  } i }|j                         D ]D  \  }}d}t        |      D ]!  }t        |||z  |       dk(  r||z  }|dz  }! n ||k  s=||z
  ||<   F |t        |      }|dk  rt        | |||      S |r[d | ||        | ||             z        z   ||      dz
  k  rt        | |||      S |dk  rt        | |||      S t        | |||      S t        | |||      S )a0  
    Compute the discrete logarithm of ``a`` to the base ``b`` modulo ``n``.

    This is a recursive function to reduce the discrete logarithm problem in
    cyclic groups of composite order to the problem in cyclic groups of prime
    order.

    It employs different algorithms depending on the problem (subgroup order
    size, prime order or not):

        * Trial multiplication
        * Baby-step giant-step
        * Pollard's Rho
        * Index Calculus
        * Pohlig-Hellman

    Examples
    ========

    >>> from sympy.ntheory import discrete_log
    >>> discrete_log(41, 15, 7)
    3

    References
    ==========

    .. [1] https://mathworld.wolfram.com/DiscreteLogarithm.html
    .. [2] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).

    r   )r   r   r   i  rY   
   l    J))r   r   r   r   r   r#   rE   r$   r   r   r   r   r   r   )r'   r&   r   r.   prime_orderr   r   r-   r/   kxpykyr   r)   r*   rH   r   s                    r2   r   r   ;  s
   @ QiF1I!qA} l((* 
	%FBAv=BK26)K"$q&GBK#BF+113 %B=BK2%K"$GBK	%
	% mmo 	FBRVOE	 MMO 		)DAqA1X q%1*a(A-Q;561 1u#$q5a 		) ent|&q!Q66	 T#a&SV$%%E
R7/1a??]"-aAu==(Aq%88'1aFFr4   c           
        t        |       } t              t        |      }t              dk  rt        d      | z  } z  |z  }| dk(  rt        |       S dk(  r3g }|dk(  r|j                  d       |z   dz  r|j                  d       |S t	        d| z        dk(  rJt        |       }|z  ||z  }dz  rz  dz  t        fdt        dz  |z
        D              S t               }t        dz  d| z  |z  z
  d| z  z        D ]3  }|j                  fdt        d| z  |z
  d| z  z        D               5 t        |      S )ah  
    Find the solutions to `a x^2 + b x + c \equiv 0 \pmod{n}`.

    Parameters
    ==========

    a : int
    b : int
    c : int
    n : int
        A positive integer.

    Returns
    =======

    list[int] :
        A sorted list of solutions. If no solution exists, ``[]``.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import quadratic_congruence
    >>> quadratic_congruence(2, 5, 3, 7) # 2x^2 + 5x + 3 = 0 (mod 7)
    [2, 6]
    >>> quadratic_congruence(8, 6, 4, 15) # No solution
    []

    See Also
    ========

    polynomial_congruence : Solve the polynomial congruence

    r   r    r   r7   c              3  .   K   | ]  }|z
  z    y wrN   rO   )r@   rH   r   r'   s     r2   rC   z'quadratic_congruence.<locals>.<genexpr>  s     Faq1ukFrQ   rY   c              3  (   K   | ]	  }|z    y wrN   rO   )r@   r   r'   s     r2   rC   z'quadratic_congruence.<locals>.<genexpr>  s     GQ1q5Gs   )
r   r"   r   r{   r   r   rq   rr   rd   update)r&   r   r   r'   rootsinv_ar   rH   s    ` `    r2   quadratic_congruencer	    s~   D 	q	Aq	Aq	Aq	AAv@AAFAFAFAAv QB**Av6LLOEQ;LLO
1Q3{aq!	U
	U
q5FA	aF=A1+EFFF
%C1a4!A#a%<1Q/ H

G"3AaCQ!A"FGGH#;r4   c                    | j                         st        d      t        |       }|j                  st        d      |j                  t
        k(  st        d      |j                         S )z}
    return coefficients of expr if it is a univariate polynomial
    with integer coefficients else raise a ValueError.
    z%The expression should be a polynomialz#The expression should be univariatez6The expression should should have integer coefficients)is_polynomialr"   r   is_univariater~   r   
all_coeffs)expr
polynomials     r2   _valid_exprr    sc     @AAdJ##>??"QRR  ""r4   c                    t        |       }|D cg c]  }||z  	 }}t        |      }|dk(  rt        g || S |dk(  rt        dg|| S |d   dk(  r)d|d   z   t        |      k(  rt	        |d    |dz
  |d      S t        ||      S c c}w )a  
    Find the solutions to a polynomial congruence equation modulo m.

    Parameters
    ==========

    expr : integer coefficient polynomial
    m : positive integer

    Examples
    ========

    >>> from sympy.ntheory import polynomial_congruence
    >>> from sympy.abc import x
    >>> expr = x**6 - 2*x**5 -35
    >>> polynomial_congruence(expr, 6125)
    [3257]

    See Also
    ========

    sympy.polys.galoistools.gf_csolve : low level solving routine used by this routine

    r6   r7   r   r   ri   T)r  r|   r	  sumr   r   )r  rP   coefficientsnumranks        r2   polynomial_congruencer    s    2 t$L'34C!G4L4|Dqy#5\5155qy#A88a88A!L$4 4L8I IL,,dQh4@@\1%% 5s   Bc           
     6   |dk  rt        d      | dk  s
|dk  s|| kD  ryt        |      }|j                         D cg c]  \  }}t        | |||       }}}t	        |j                         D cg c]
  \  }}||z   c}}|d      d   S c c}}w c c}}w )ay  Compute ``binomial(n, m) % k``.

    Explanation
    ===========

    Returns ``binomial(n, m) % k`` using a generalization of Lucas'
    Theorem for prime powers given by Granville [1]_, in conjunction with
    the Chinese Remainder Theorem.  The residue for each prime power
    is calculated in time O(log^2(n) + q^4*log(n)log(p) + q^4*p*log^3(p)).

    Parameters
    ==========

    n : an integer
    m : an integer
    k : a positive integer

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import binomial_mod
    >>> binomial_mod(10, 2, 6)  # binomial(10, 2) = 45
    3
    >>> binomial_mod(17, 9, 10)  # binomial(17, 9) = 24310
    0

    References
    ==========

    .. [1] Binomial coefficients modulo prime powers, Andrew Granville,
        Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
    r   zk is required to be positiver   F)check)r"   r   r#   _binomial_mod_prime_powerr   )r'   rP   rJ   factorisationr)   r*   residuesrA   s           r2   binomial_modr  	  s    B 	1uJ=>>
 	1uAQqaLMBOBUBUBWX$!Q)!Q15XHX=#6#6#89%!R2985QRSTT Y9s   B2B
c                   t              fdd fdt        dg      fd       fd}d}| || |z
  }}}dx}	x}
x}}|r ||z        } ||z         ||z        z  z  }|z  t        |      t        |      c}\  }}\  }}||z   |
z   z  }
|	|
z  }	|dz
  k\  r||
z  }||t        |      z  z  }|z  }|dz  }|rt        dk(  rd	k\  rdnd
|      }t        |	      |z  |z  z  S )a  Compute ``binomial(n, m) % p**q`` for a prime ``p``.

    Parameters
    ==========

    n : positive integer
    m : a nonnegative integer
    p : a prime
    q : a positive integer (the prime exponent)

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _binomial_mod_prime_power
    >>> _binomial_mod_prime_power(10, 2, 3, 2)  # binomial(10, 2) = 45
    0
    >>> _binomial_mod_prime_power(17, 9, 2, 4)  # binomial(17, 9) = 24310
    6

    References
    ==========

    .. [1] Binomial coefficients modulo prime powers, Andrew Granville,
        Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
    c                >   dz  }dx}}|dk(  rdk(  sd|z  dz   z  fv r/dz  dk(  r|dz  }t        d|z        t        d|z  z
        }}n't        d|z  dz         t        d|z  dz   z
        }}t        d|dz         D ]H  }t        |dz
  z  dz   |z        D ]  }||z  }||z  }  
| ||      }|t        |||      z  }||z  }J dk(  r9| dz  }	t        d|dz         D ]  }|	|dz   
| ||      z  z  }	 |	dz  dk(  r|dz  }|||z  z  }||z  S )zCompute (u*p)!_p modulo p^q.r7   r   ri   )r$   rE   )urv   facprodmodulodivr   mulbj_smr   r)   r^   s             r2   up_factorialz/_binomial_mod_prime_power.<locals>.up_factorialU  s   Fd6a1f!aAqs8 31uz161a1+s1acAgCFa1q/3q1Q37a-+@CFq!a% 	Aa!eQY]AaC0 s
v Q1+CCS&))DFND	 6aB1a!e_>bAqD2aA;,>&>b>Av{DBJDf}r4   c                    | }t        d|dz         D ]  }||k7  s	|| | z  ||z  z
  z  } t        d|dz         D ]  }||k7  s	|||z  ||z  z
  z  } ||z  S )z@Compute the exponent of (j*p)!_p in the calculation of (u*p)!_p.r   r   )r  r   rv   r!  rH   s        r2   r   z%_binomial_mod_prime_power.<locals>.bjl  s{    q!a% 	)AAvtqsQqSy(t	)q!a% 	*AAvt!ac	)t	*qyr4   c                ^   d}t         	|      
      }t        d      D ]  }|}t        |z  dz   |z  |z   dz         D ]  }||z  }|
z  } | }t        d      D ]  }||k7  s	|| |z
  z  } t        d      D ]  }||k7  s	|||z
  z  } ||z  }|t        ||
      z  }|
z  } |S )z*Compute binomial(u*p + v, v)_p modulo p^q.r   )r   rE   r$   )r  rI   r!  r#  r   r   v_r   rH   	factorialr"  r)   r^   s            r2   up_plus_v_binomz2_binomial_mod_prime_power.<locals>.up_plus_v_binomu  s    Yq\6*q! 	AAAaC!GQqS1Wq[1 RV B1a[ '62Q;2'1a[ (62!a%<2(1HBC2v&&DFND	 r4   r   c                    | |d   z  z  S )zCompute v! modulo p^q.ri   rO   )rI   prevr"  s     r2   r+  z,_binomial_mod_prime_power.<locals>.factorial  s     bzF""r4   c                ^    t        |       \  }} |       |      z   ||      z  z  S )zCompute n!_p modulo p^q.)r   )r'   r  rI   r+  r"  r)   r'  r,  s      r2   factorial_pz._binomial_mod_prime_power.<locals>.factorial_p  s6    a|1!|A.A1FF&PPr4   r   r7   r6   ri   )r$   r   r   r   )r'   rP   r)   r^   r0  r!  NjMjRje0carryeq_1r   	numeratordenominatormjrjr$  r   r+  r"  r'  r,  s     ``              @@@@@r2   r  r  5  sc   < AYF.& aS# #Q Q
 DAq1uBBB
V,	!"v+.R&[1IIFR!#Qr1vb!}HRhr2b5Q&
eA:tu}t	F;777	Q  16a1fa"dF
;C2v$t+v55r4   )T)F)returnz	list[int]rN   )Nr   N)r'   r%   r   r   )NN)K
__future__r   sympy.external.gmpyr   r   r   r   r   r	   r
   sympy.polysr   sympy.polys.domainsr   sympy.polys.galoistoolsr   r   r   r   	primetestr   generater   factor_r   r   r   r   sympy.utilities.decoratorr   sympy.utilities.memoizationr   sympy.utilities.miscr   sympy.utilities.iterablesr   sympy.core.randomr   r   	itertoolsr   r3   rK   rT   rV   r_   r[   ro   rw   r%   rr   ry   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	  r  r  r  r  rO   r4   r2   <module>rJ     s   "4 4 4  " R R    .  0 7 ' . / CL=@*GZ!H`FXJv:z*Z  # /8dH#VEBXv1<<;|K\M`   BBD*"	D*"Z  ~BD@ 	D@ F  pBD/	D/d$+N*+Zb?J^.B-`QGjAH# "&J)UXm6r4   