
    wg!                     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
mZmZ d dlmZ d ZddZd	 Zdd
Zd Zy)    )prodgcdgcdextisprime)ZZ)gf_crtgf_crt1gf_crt2)as_intc                      | |dz  k  r| S | |z
  S )zReturn the residual mod m such that it is within half of the modulus.

    >>> from sympy.ntheory.modular import symmetric_residue
    >>> symmetric_residue(1, 6)
    1
    >>> symmetric_residue(4, 6)
    -2
        )ams     Z/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/ntheory/modular.pysymmetric_residuer   
   s     	AF{q5L    c                    |r2t        t        t        |             } t        t        t        |            }t        || t              t        |       }|rFt        fdt        ||       D              s(t        t        t        ||             d|dS \  }|r t        t        |            t        |      fS t              t        |      fS )ak  Chinese Remainder Theorem.

    The moduli in m are assumed to be pairwise coprime.  The output
    is then an integer f, such that f = v_i mod m_i for each pair out
    of v and m. If ``symmetric`` is False a positive integer will be
    returned, else \|f\| will be less than or equal to the LCM of the
    moduli, and thus f may be negative.

    If the moduli are not co-prime the correct result will be returned
    if/when the test of the result is found to be incorrect. This result
    will be None if there is no solution.

    The keyword ``check`` can be set to False if it is known that the moduli
    are coprime.

    Examples
    ========

    As an example consider a set of residues ``U = [49, 76, 65]``
    and a set of moduli ``M = [99, 97, 95]``. Then we have::

       >>> from sympy.ntheory.modular import crt

       >>> crt([99, 97, 95], [49, 76, 65])
       (639985, 912285)

    This is the correct result because::

       >>> [639985 % m for m in [99, 97, 95]]
       [49, 76, 65]

    If the moduli are not co-prime, you may receive an incorrect result
    if you use ``check=False``:

       >>> crt([12, 6, 17], [3, 4, 2], check=False)
       (954, 1224)
       >>> [954 % m for m in [12, 6, 17]]
       [6, 0, 2]
       >>> crt([12, 6, 17], [3, 4, 2]) is None
       True
       >>> crt([3, 6], [2, 5])
       (5, 6)

    Note: the order of gf_crt's arguments is reversed relative to crt,
    and that solve_congruence takes residue, modulus pairs.

    Programmer's note: rather than checking that all pairs of moduli share
    no GCD (an O(n**2) test) and rather than factoring all moduli and seeing
    that there is no factor in common, a check that the result gives the
    indicated residuals is performed -- an O(n) operation.

    See Also
    ========

    solve_congruence
    sympy.polys.galoistools.gf_crt : low level crt routine used by this routine
    c              3   :   K   | ]  \  }}||z  |z  k(    y wNr   ).0vr   results      r   	<genexpr>zcrt.<locals>.<genexpr>Z   s"     =41a1q5FQJ&=s   F)check	symmetric)listmapr   r
   r	   r   allzipsolve_congruenceintr   )r   r   r   r   mmr   s        @r   crtr&      s    t VQ VQ Aq"F	aB=3q!9==%tC1I96F~JFB$VR013r7::v;Br   c                 "    t        | t              S )aC  First part of Chinese Remainder Theorem, for multiple application.

    Examples
    ========

    >>> from sympy.ntheory.modular import crt, crt1, crt2
    >>> m = [99, 97, 95]
    >>> v = [49, 76, 65]

    The following two codes have the same result.

    >>> crt(m, v)
    (639985, 912285)

    >>> mm, e, s = crt1(m)
    >>> crt2(m, v, mm, e, s)
    (639985, 912285)

    However, it is faster when we want to fix ``m`` and
    compute for multiple ``v``, i.e. the following cases:

    >>> mm, e, s = crt1(m)
    >>> vs = [[52, 21, 37], [19, 46, 76]]
    >>> for v in vs:
    ...     print(crt2(m, v, mm, e, s))
    (397042, 912285)
    (803206, 912285)

    See Also
    ========

    sympy.polys.galoistools.gf_crt1 : low level crt routine used by this routine
    sympy.ntheory.modular.crt
    sympy.ntheory.modular.crt2

    )r   r	   )r   s    r   crt1r(   f   s    L 1b>r   c                     t        || |||t              }|r t        t        ||            t        |      fS t        |      t        |      fS )a  Second part of Chinese Remainder Theorem, for multiple application.

    See ``crt1`` for usage.

    Examples
    ========

    >>> from sympy.ntheory.modular import crt1, crt2
    >>> mm, e, s = crt1([18, 42, 6])
    >>> crt2([18, 42, 6], [0, 0, 0], mm, e, s)
    (0, 4536)

    See Also
    ========

    sympy.polys.galoistools.gf_crt2 : low level crt routine used by this routine
    sympy.ntheory.modular.crt
    sympy.ntheory.modular.crt1

    )r   r	   r$   r   )r   r   r%   esr   r   s          r   crt2r,      sJ    , Q2q!R(F$VR013r7::v;Br   c                  "   d }| }|j                  dd      }|j                  dd      r|D cg c]  \  }}t        |      t        |      f }}}i }|D ]  \  }}||z  }||v r|||   k7  r y|||<     |j                         D cg c]	  \  }}||f }}}~t        d |D              r#t	        t        |       \  }}t        |||d      S d	}|D ]  }	 |||	      }| y|\  }
}|
|z  }
 |rt        
      |fS 
fS c c}}w c c}}w )
a  Compute the integer ``n`` that has the residual ``ai`` when it is
    divided by ``mi`` where the ``ai`` and ``mi`` are given as pairs to
    this function: ((a1, m1), (a2, m2), ...). If there is no solution,
    return None. Otherwise return ``n`` and its modulus.

    The ``mi`` values need not be co-prime. If it is known that the moduli are
    not co-prime then the hint ``check`` can be set to False (default=True) and
    the check for a quicker solution via crt() (valid when the moduli are
    co-prime) will be skipped.

    If the hint ``symmetric`` is True (default is False), the value of ``n``
    will be within 1/2 of the modulus, possibly negative.

    Examples
    ========

    >>> from sympy.ntheory.modular import solve_congruence

    What number is 2 mod 3, 3 mod 5 and 2 mod 7?

    >>> solve_congruence((2, 3), (3, 5), (2, 7))
    (23, 105)
    >>> [23 % m for m in [3, 5, 7]]
    [2, 3, 2]

    If you prefer to work with all remainder in one list and
    all moduli in another, send the arguments like this:

    >>> solve_congruence(*zip((2, 3, 2), (3, 5, 7)))
    (23, 105)

    The moduli need not be co-prime; in this case there may or
    may not be a solution:

    >>> solve_congruence((2, 3), (4, 6)) is None
    True

    >>> solve_congruence((2, 3), (5, 6))
    (5, 6)

    The symmetric flag will make the result be within 1/2 of the modulus:

    >>> solve_congruence((2, 3), (5, 6), symmetric=True)
    (-1, 6)

    See Also
    ========

    crt : high level routine implementing the Chinese Remainder Theorem

    c                     | \  }}|\  }}|||z
  |}}}t        |||      }	|||fD 
cg c]  }
|
|	z  	 c}
\  }}}|dk7  rt        ||      \  }	}}|	dk7  ry||z  }|||z  z   ||z  }}||fS c c}
w )zReturn the tuple (a, m) which satisfies the requirement
        that n = a + i*m satisfy n = a1 + j*m1 and n = a2 = k*m2.

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Method_of_successive_substitution
           Nr   )c1c2a1m1a2m2r   bcgiinv_a_r   s                 r   combinez!solve_congruence.<locals>.combine   s     BBb2gra11aL"#Q+A1a4+1a6 A,KAuaAvJABqDy"Q$1!t ,s   A,r   Fr   TNc              3   8   K   | ]  \  }}t        |        y wr   r   )r   rr   s      r   r   z#solve_congruence.<locals>.<genexpr>  s     )dawqz)s   )r   r   )r   r/   )getr   itemsr!   r   r"   r&   r   )remainder_modulus_pairshintr<   rmr   r>   r   uniqrvrmins              r   r#   r#      sR   h, 
!Be,Ixx134Avay&)$44  	DAqFADyQ<DG	 "&.Aq!f..
 )b))R>DAqq!y>>	B 	R:1E	 $Q*A--!tS 5* /s    D
DN)FT)F)mathr   sympy.external.gmpyr   r   sympy.ntheory.primetestr   sympy.polys.domainsr	   sympy.polys.galoistoolsr
   r   r   sympy.utilities.miscr   r   r&   r(   r,   r#   r   r   r   <module>rN      s7     + + " < < 'K \&R :wr   