o
    8Va                      @   sh   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 G dd deZ
d	d
 Zdd Zdd ZdS )z
The Schur number S(k) is the largest integer n for which the interval [1,n]
can be partitioned into k sum-free sets.(http://mathworld.wolfram.com/SchurNumber.html)
    N)S)Basic)Function)Integerc                   @   s$   e Zd ZdZedd Zdd ZdS )SchurNumberaX  
    This function creates a SchurNumber object
    which is evaluated for k <= 4 otherwise only
    the lower bound information can be retrieved.

    Examples
    ========

    >>> from sympy.combinatorics.schur_number import SchurNumber

    Since S(3) = 13, hence the output is a number
    >>> SchurNumber(3)
    13

    We don't know the schur number for values greater than 4, hence
    only the object is returned
    >>> SchurNumber(6)
    SchurNumber(6)

    Now, the lower bound information can be retrieved using lower_bound()
    method
    >>> SchurNumber(6).lower_bound()
    364

    c                 C   s^   |j r+|tju rtjS |jrdS |jr|jrtdddddd}|dkr-t|| S d S d S )Nr   zk should be a positive integer         ,   )r         r   )	is_Numberr   InfinityZis_zero
is_integerZis_negative
ValueErrorr   )clskZfirst_known_schur_numbers r   B/usr/lib/python3/dist-packages/sympy/combinatorics/schur_number.pyeval'   s   
zSchurNumber.evalc                 C   s   | j d }d| d d S )Nr   r   r   r   )args)selfZf_r   r   r   lower_bound4   s   
zSchurNumber.lower_boundN)__name__
__module____qualname____doc__classmethodr   r   r   r   r   r   r      s
    
r   c                 C   sX   | t ju r	td| dkrtd| dkrd}t|S ttd|  d d}t|S )NzInput must be finiter   z&n must be a non-zero positive integer.r   r   r   )r   r   r   mathZceillogr   )nZmin_kr   r   r   _schur_subsets_number9   s   
r!   c                 C   s   t | tr| jstdt| }| dkrdgg}n| dkr#ddgg}n| dkr-g dg}nddgddgg}t||k r`t|| }dd tt|| d d d D }|d	  |7  < t||k s;|S )
a  

    This function returns the partition in the minimum number of sum-free subsets
    according to the lower bound given by the Schur Number.

    Parameters
    ==========

    n: a number
        n is the upper limit of the range [1, n] for which we need to find and
        return the minimum number of free subsets according to the lower bound
        of schur number

    Returns
    =======

    List of lists
        List of the minimum number of sum-free subsets

    Notes
    =====

    It is possible for some n to make the partition into less
    subsets since the only known Schur numbers are:
    S(1) = 1, S(2) = 4 , S(3) = 13, S(4) = 44.
    e.g for n = 44 the lower bound from the function above is 5 subsets but it has been proven
    that can be done with 4 subsets.

    Examples
    ========

    For n = 1, 2, 3 the answer is the set itself

    >>> from sympy.combinatorics.schur_number import schur_partition
    >>> schur_partition(2)
    [[1, 2]]

    For n > 3, the answer is the minimum number of sum-free subsets:

    >>> schur_partition(5)
    [[3, 2], [5], [1, 4]]

    >>> schur_partition(8)
    [[3, 2], [6, 5, 8], [1, 4, 7]]
    zInput value must be a numberr   r   r   )r   r   r   r   c                 S   s   g | ]}d | d qS r   r   r   .0r   r   r   r   
<listcomp>   s    z#schur_partition.<locals>.<listcomp>)
isinstancer   r   r   r!   len_generate_next_listrange)r    Znumber_of_subsetsZsum_free_subsetsZmissed_elementsr   r   r   schur_partitionG   s    /

$r+   c                    sv   g }| D ]} fdd|D } fdd|D }|| }| | q fddtdt| d D }| | |} | S )Nc                    s    g | ]}|d   kr|d  qS )r   r   r$   Znumberr    r   r   r%      s     z'_generate_next_list.<locals>.<listcomp>c                    s(   g | ]}|d  d  kr|d  d qS r"   r   r,   r-   r   r   r%         ( c                    s(   g | ]}d | d  krd | d qS r"   r   r#   r-   r   r   r%      r.   r   r   )appendr*   r(   )Zcurrent_listr    Znew_listitemZtemp_1Ztemp_2Znew_itemZ	last_listr   r-   r   r)      s    
r)   )r   r   Z
sympy.corer   Zsympy.core.basicr   Zsympy.core.functionr   Zsympy.core.numbersr   r   r!   r+   r)   r   r   r   r   <module>   s    -D