
    #iR                        d Z ddlZddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ g dZ ddZ!ddZ"ddZ# G d	 d
      Z$ddZ%ddZ&ddZ'ddZ(d Z)ddZ*ddZ+d Z,ddZ-d Z.y)z.
Useful utilities for working with bitarrays.
    N)bitarray
bits2bytes)zerosonescount_nparity_ssqixor_indices	count_andcount_or	count_xorany_andsubsetcorrespond_allbyteswap	serializedeserializeba2hexhex2baba2basebase2ba	sc_encode	sc_decode	vl_encode	vl_decodecanonical_decode)#r   r   urandomrandom_krandom_p
gen_primespprintstripr   r   sum_indicesr
   r   r   r   r   r   r   r   	intervalsr   r   r   r   ba2intint2bar   r   r   r   r   r   huffman_codecanonical_huffmanr   c                 `    t        t        j                  t        |             |      }|| d= |S )zdurandom(n, /, endian=None) -> bitarray

Return random bitarray of length `n` (uses `os.urandom()`).
N)r   osr   r   )__lengthendianas      >/var/www/br/venv/lib/python3.12/site-packages/bitarray/util.pyr   r   +   s,    
 	Jx016:A	()H    c                     t        | |      }t        |t              s!t        dt	        |      j
                  z        |j                  |      S )aX  random_k(n, /, k, endian=None) -> bitarray

Return (pseudo-) random bitarray of length `n` with `k` elements
set to one.  Mathematically equivalent to setting (in a bitarray of
length `n`) all bits at indices `random.sample(range(n), k)` to one.
The random bitarrays are reproducible when giving Python's `random.seed()`
a specific seed value.
int expected, got '%s')_Random
isinstanceint	TypeErrortype__name__r   )__nkr,   rs       r.   r   r   5   sC     	VAa0473C3CCDD::a=r/   c                 ~    t         j                  dd dk  rt        d      t        | |      }|j	                  |      S )aD  random_p(n, /, p=0.5, endian=None) -> bitarray

Return (pseudo-) random bitarray of length `n`, where each bit has
probability `p` of being one (independent of any other bits).  Mathematically
equivalent to `bitarray((random() < p for _ in range(n)), endian)`, but much
faster for large `n`.  The random bitarrays are reproducible when giving
Python's `random.seed()` with a specific seed value.

This function requires Python 3.12 or higher, as it depends on the standard
library function `random.binomialvariate()`.  Raises `NotImplementedError`
when Python version is too low.
N   )      z7bitarray.util.random_p() requires Python 3.12 or higher)sysversion_infoNotImplementedErrorr2   r   )r8   pr,   r:   s       r.   r   r   E   sE     g%! #: ; 	;VA::a=r/   c                   D    e Zd ZdZdez  ZdZddZd Zd Zd Z	d	 Z
d
 Zy)r2         g{Gz?Nc                 @    || _         t        |      | _        || _        y N)nr   nbytesr,   )selfrH   r,   s      r.   __init__z_Random.__init__j   s     mr/   c                     | j                   }t        j                  d|z        j                  |d      }t	        || j
                        }|| j                  d= |S )zV
        Return bitarray with each bit having probability p = 1/2 of being 1.
        rD   littleN)rI   randomgetrandbitsto_bytesr   r,   rH   )rJ   rI   br-   s       r.   random_halfz_Random.random_halfo   sP     q6z*33FHEQ$dffgJr/   c                     d|cxk  r| j                   k  sn t        d| j                   |fz        t        |j                  dd      d      }||j	                  d      dz   | j
                   S )z
        Return bitarray containing operator sequence.
        Each item represents a bitwise operation:   0: AND   1: OR
        After applying the sequence (see .combine_half()), we
        obtain a bitarray with probability  q = i / K
        r   z0 < i < %d, got i = %dr<   rM   	byteorderrE   )K
ValueErrorr   rP   indexM)rJ   ir-   s      r.   op_seqz_Random.op_seqz   sd     1~tvv~5CDD QZZXZ6Aa$&&))r/   c                     | j                         }|D ]+  }|r|| j                         z  }|| j                         z  }- |S )zm
        Combine random bitarrays with probability 1/2
        according to given operator sequence.
        )rR   )rJ   seqr-   r9   s       r.   combine_halfz_Random.combine_half   sQ    
  	(AT%%''T%%''		(
 r/   c                 p   | j                   }|dk  s||k\  rD|dk(  rt        || j                        S ||k(  rt        || j                        S t	        d|z        ||dz  kD  r&| j                  ||z
        }|j                          |S |dk  s|| j                  z  d|z  k  rd}nA||z  }|dd|z  z
  t        j                  |      z  z  }t        || j                  dz   z        }|dk  rt        || j                        }| }n3| j                  | j                  |            }|j                         |z
  }t        j                  }|dk  r3t!        |       D ]"  } ||      }||   r ||      }||   rd||<   $ |S |dkD  r0t!        |      D ]"  } ||      }||   s ||      }||   sd||<   $ |S )	Nr   z&k must be in range 0 <= k <= n, got %sr<      r=   g?g?rE   )rH   r   r,   r   rW   r   invertrV   mathsqrtr4   r^   r[   countrN   	randrangerange)	rJ   r9   rH   r-   rZ   rB   diffre   _s	            r.   r   z_Random.random_k   s   FF6Q!VAvQ,,AvAt{{++EIJJ qAv:a!e$AHHJH r6QZ!a%'AAA#a-499Q<//AA!$%A q5a%A2D!!$++a.1A779q=D$$	!8D5\ aLd!!A d!	  AX4[ aLA$!!A A$!	 r/   c                 ~   dk  s
dk(  sdk\  rmdk(  r t        | j                  | j                        S dk(  r| j                         S dk(  r t	        | j                  | j                        S t        dz        | j                  dk  r2t        fdt        | j                        D        | j                        S dkD  r&| j                  dz
        }|j                          |S | j                  k  r/| j                  t        j                  | j                              S t        | j                  z        }| j                  dz   z  |dz   kD  r|dz  }| j!                  |      }|| j                  z  }| j                  dk  r\| j"                  t%        |      d	t'        |k7        z  z   k  r2t        fd
t        | j                        D        | j                        S | j)                  |      }|k  r!|z
  d|z
  z  }|| j                  |      z  }|S |kD  r|z  }|| j                  |      z  }|S )Ng              ?      ?z*p must be in range 0.0 <= p <= 1.0, got %sr`   c              3   L   K   | ]  }t        j                          k    y wrG   rN   .0rh   rB   s     r.   	<genexpr>z#_Random.random_p.<locals>.<genexpr>        HQV]]_q0H   !$rE   d   r=   c              3   L   K   | ]  }t        j                          k    y wrG   rm   rn   s     r.   rp   z#_Random.random_p.<locals>.<genexpr>   rq   rr   )r   rH   r,   rR   r   rW   r   rf   r   ra   SMALL_Pr   rN   binomialvariater4   rV   r[   rI   lenboolr^   )rJ   rB   r-   rZ   r]   qxs    `     r.   r   z_Random.random_p   s   8qCx18CxTVVT[[11Cx''))CxDFFDKK00IAMNN 66B;H%-H KK) ) s7cAg&AHHJH t||==!7!7!BCC DFF
O
a!e#FAkk!nJ 66C<DKK3s8a$qAv,6F+FFH%-H KK) ) c"q5Q37#Aq!!A
 	 UAAq!!Ar/   )r   N)r7   
__module____qualname__rY   rV   ru   rK   rR   r[   r^   r   r    r/   r.   r2   r2   Y   s:     	
A 	
QA G
	*.`/r/   r2   c           
      b   t        |       }|dk  rt        d      |r't        d|      }d|ddd<   d|ddd<   d|ddd	<   d
}nt        d|      }dD ]
  }d|dd|<    d}||t        |      z   dz
  t        |      z  z  }t	        ||      |dd ||d= |rR|j                  ddt        t        j                  |dz        dz               D ]  }d|z  dz   }d|||z  dz  d|<    |S |j                  ddt        t        j                  |      dz               D ]  }d|||z  dd|z  <    |S )a_  gen_primes(n, /, endian=None, odd=False) -> bitarray

Generate a bitarray of length `n` in which active indices are prime numbers.
By default (`odd=False`), active indices correspond to prime numbers directly.
When `odd=True`, only odd prime numbers are represented in the resulting
bitarray `a`, and `a[i]` corresponds to `2*i+1` being prime or not.
r   zbitarray length must be >= 0i   rE   Nr=   r<         01110110   )r<   r=   r   r   00110101rD   rk      )r4   rW   r   rw   r   searchrb   rc   )r8   r,   oddrH   r-   frZ   js           r.   r    r       s{    	CA1u788
f!$Q$!$Q$!$Q$f 	AAccF	 !c!f*q.SV	##AQAbqE	!"
!QDIIa1f$5$; <= 	%AA	A#$Aq1ula 	% H !RTYYq\C%7!89 	"A !Aa!enq1un	"Hr/   c                 r   |dvrt        d|z        d}t        |       |k  rt        | |      S |dz  }||dz
  z  dz  }|d|z  dz
  z  dz  }t        |       |z   dz
  |z  }| j                  }d}t	        |      D ]  }	t        |       |	|z  |	dz   |z   }
t        d	| j                  |

      }|r%|	|dz
  k(  r|j                  rt        |      }d|| d	 |j                         }|sl||	z  }||k(  r|n
t        |      }|dk(  r|||z  |z   z  }||k(  r|nt        |d      }|||z  d|z  z   |z  |z   z  } |S )zsum_indices(a, /, mode=1) -> int

Return sum of indices of all active bits in bitarray `a`.
Equivalent to `sum(i for i, v in enumerate(a) if v)`.
`mode=2` sums square of indices.
)rE   r<   zunexpected mode %ri   rD   rE   r<   r=   r   N)buffer)
rW   rw   r	   padbitsrf   
memoryviewr   r,   readonlyrd   )__amoderH   mo1o2nblocksr   smrZ   vblockr9   yz1z2s                   r.   r#   r#      s}    6-455 	A
3x1}S$ 	
QA	
a!e	B	q1uqy	Q	B3x!|aA%GkkG	
B7^ 0sOAEQUaK0szz!4qGaK'~~  E7()KKMAAAv5<Bqya!ebj 6RuUAq1uq2v~*R//#0& Ir/   c                 p   |t         j                  }t        | t              sddl}|j	                  | |||       yt        |      }|dk  rt        d      t        |      }|dk  rt        d      t        |      }||k  rt        d|z        ||z
  |dz   z  }||z  }|dk(  r||z
  dz
  }t        |       j                  }t        |      d	z   t        |       z   t        |       |z  z   |k\  }	|	rd
}
n| rd}
nd}
|j                  |d|
       t        |       D ]a  \  }}|	r||z  dk(  r|j                  d|dz  z         ||z  dk(  r||z  dk7  r|j                  d       |j                  t        |             c |	r|j                  d       |j                  d|
z         |j                          y)a  pprint(bitarray, /, stream=None, group=8, indent=4, width=80)

Pretty-print bitarray object to `stream`, defaults is `sys.stdout`.
By default, bits are grouped in bytes (8 bits), and 64 bits per line.
Non-bitarray objects are printed using `pprint.pprint()`.
Nr   )streamindentwidthrE   zgroup must be >= 1zindent must be >= 0zwidth must be > %d (indent)r<      z'''' (z
%s 
z%s)
)r?   stdoutr3   r   r!   r4   rW   r6   r7   rw   write	enumeratestrflush)r   r   groupr   r   _pprintgplepl	type_name	multilinequotesrZ   rQ   s                r.   r!   r!   M  s    ~c8$ s6&FJEqy-..[Fz.//JE6?@@6>uqy
)C
#+C
axfnq S	""II"SX-CE0AAUJI	
LLIv./# 1SALL6C<01u9>a#glLLSV T
LL6!"
LLNr/   c                    t        |t              s!t        dt        |       j                  z        |dvrt        d|z        |dk(  rdn| j                  d      }|dk(  r| dd S |d	k(  rdn| j                  dd
      dz   }| || S )zstrip(bitarray, /, mode='right') -> bitarray

Return a new bitarray with zeros stripped from left, right or both ends.
Allowed values for mode are the strings: `left`, `right`, `both`
zstr expected for mode, got '%s')leftrightbothz.mode must be 'left', 'right' or 'both', got %rr   NrE   r   r   r   )r3   r   r5   r6   r7   rW   find)r   r   startstops       r.   r"   r"     s     dC 9S	**+ , 	,,,I  	 GOD!E{2Aw6>4sxxx';a'?DuT?r/   c              #      K   	 | d   }t        |       }d}||k  r0|}	 | j                  | |      }t	        |      ||f | }||k  r/yy# t         $ r Y yw xY w# t        $ r |}Y 7w xY ww)zintervals(bitarray, /) -> iterator

Compute all uninterrupted intervals of 1s and 0s, and return an
iterator over tuples `(value, start, stop)`.  The intervals are guaranteed
to be in order, and their size is always non-zero (`stop - start > 0`).
r   N)
IndexErrorrw   rX   rW   r4   )r   valuerH   r   r   s        r.   r$   r$     s     A 	CAD
(	99Y.D %j%%%	 (    	D	sO   A,A A,A A,
A,	AA,AA,A)&A,(A))A,c                    t        | t              s!t        dt        |       j                  z        t        |       }|dk(  rt        d      | j                  r9t        | j                  | j                        }| j                  dk(  r| |z   n|| z   } t        j                  | j                         | j                        }|r||dz
  z	  r|d|z  z  }|S )zba2int(bitarray, /, signed=False) -> int

Convert the given bitarray to an integer.
The bit-endianness of the bitarray is respected.
`signed` indicates whether two's complement is used to represent the integer.
zbitarray expected, got '%s'r   znon-empty bitarray expectedrM   rT   rE   )r3   r   r5   r6   r7   rw   rW   r   r   r,   r4   
from_bytestobytes)r   signedlengthpadress        r.   r%   r%     s     c8$5S	8J8JJKKXF{677
{{CKK,::1cCisSy
..#**.
=C#!#qF{Jr/   c                 (   t        | t              s!t        dt        |       j                  z        |+t        |t              st        d      |dk  rt        d      |rC|t        d      d|dz
  z  }| | cxk  r|k  sn t        d| || fz        | dk  r#| d|z  z  } n|r| |z	  rt        d	d|z  | fz        t        d|      }| j                  t        | j                               |j                  
      }|j                  |       |j                  dk(  }||rt        ||rd      S d      S |dz   S t        |      |kD  r|r|d| S || d S t        |      |k(  r|S t        |t        |      z
  |j                        }|r||z   S ||z   S )a  int2ba(int, /, length=None, endian=None, signed=False) -> bitarray

Convert the given integer to a bitarray (with given bit-endianness,
and no leading (big-endian) / trailing (little-endian) zeros), unless
the `length` of the bitarray is provided.  An `OverflowError` is raised
if the integer is not representable with the given number of bits.
`signed` determines whether two's complement is used to represent the integer,
and requires `length` to be provided.
r1   Nz"int expected for argument 'length'r   zlength must be > 0z!signed requires argument 'length'rE   z+signed integer not in range(%d, %d), got %dz,unsigned integer not in range(0, %d), got %drT   rM   r   r   0)r3   r4   r5   r6   r7   rW   OverflowErrorr   rP   r   
bit_lengthr,   	frombytesr"   rw   r   )	__ir   r,   r   r   r-   rQ   ler   s	            r.   r&   r&     s    c30493E3EEFF&#&@AAQ;122>?@@!OcA !)-.B3<!8 9 971;CcVm !),-K+=!> ? ? 	FAZ 01QXXFAKKN	
X	B~67uQ22D62DQWD
1vq&z0Qwx[0
1v
Q
*C1s7%cAg%r/   c                    ddl m}m}  G d dt              }g }| j	                         D ]#  \  }} |       }||_        ||_         |||       % t        |      dkD  rl |       } ||       ||      f|_        |j                  d   j                  |j                  d   j                  z   |_         |||       t        |      dkD  rl|d   S )z_huffman_tree(dict, /) -> Node

Given a dict mapping symbols to their frequency, construct a Huffman tree
and return its root node.
r   )heappushheappopc                       e Zd ZdZd Zy)_huffman_tree.<locals>.Nodez
        There are to tyes of Node instances (both have 'freq' attribute):
          * leaf node: has 'symbol' attribute
          * parent node: has 'child' attribute (tuple with both children)
        c                 4    | j                   |j                   k  S rG   )freq)rJ   others     r.   __lt__z"_huffman_tree.<locals>.Node.__lt__  s    99uzz))r/   N)r7   r{   r|   __doc__r   r}   r/   r.   Noder     s    	
	*r/   r   rE   )	heapqr   r   objectitemssymbolr   rw   child)	
__freq_mapr   r   r   minheapsymr   leafparents	            r.   _huffman_treer     s     (*v * G""$  Qv	$	  g,
 w')99ll1o**V\\!_-A-AA&! g,
 1:r/   c                 <   t        | t              s!t        dt        |       j                  z        t        |       dk  r5t        |       dk(  rt        d      t        |       d   }|t        d|      iS i t        d|      ffd	 t        |              S )a:  huffman_code(dict, /, endian=None) -> dict

Given a frequency map, a dictionary mapping symbols to their frequency,
calculate the Huffman code, i.e. a dict mapping those symbols to
bitarrays (with given bit-endianness).  Note that the symbols are not limited
to being strings.  Symbols may be any hashable object.
dict expected, got '%s'r<   r   *cannot create Huffman code with no symbolsr   c                     	 || j                   <   y # t        $ r5  | j                  d   |dz           | j                  d   |dz          Y y w xY w)Nr   r   rE   1r   AttributeErrorr   )ndprefixresulttraverses     r.   r   zhuffman_code.<locals>.traverse9  sQ    	0 &F299 	0RXXa[&3,/RXXa[&3,/	0    ;AA)
r3   dictr5   r6   r7   rw   rW   listr   r   )r   r,   r   r   r   s      @@r.   r'   r'      s     j$'1D4D4M4MMNN
:z?aIJJ :q!Xc6*++F$Q/ 0 ]:&'Mr/   c                 |  
 t        | t              s!t        dt        |       j                  z        t        |       dk  r;t        |       dk(  rt        d      t        |       d   }|t        dd      iddg|gfS i 
d
fd	 t        |              t        
j                         d	 
      }|d   d   }i }|dz   dgz  }d}t        |      D ]M  \  }\  }}t        ||d      ||<   ||xx   dz  cc<   |dz   t        |      k  s8|dz  }|||dz      d   |z
  z  }O |||D 	cg c]  }	|	d   	 c}	fS c c}	w )a  canonical_huffman(dict, /) -> tuple

Given a frequency map, a dictionary mapping symbols to their frequency,
calculate the canonical Huffman code.  Returns a tuple containing:

0. the canonical Huffman code as a dict mapping symbols to bitarrays
1. a list containing the number of symbols of each code length
2. a list of symbols in canonical order

Note: the two lists may be used as input for `canonical_decode()`.
r   r<   r   r   r   bigrE   c                     	 || j                   <   y # t        $ r5  | j                  d   |dz           | j                  d   |dz          Y y w xY w)Nr   rE   r   )r   r   code_lengthr   s     r.   r   z#canonical_huffman.<locals>.traverse\  sQ    	.%+K		" 	.RXXa[&1*-RXXa[&1*-	.r   c                     | d   S )NrE   r}   )items    r.   <lambda>z#canonical_huffman.<locals>.<lambda>j  s
    a r/   )keyr   )r   )r3   r   r5   r6   r7   rw   rW   r   r   r   sortedr   r   r&   )r   r   tablemaxbitscodedictrd   coderZ   r   r   r   r   s             @@r.   r(   r(   D  sg    j$'1D4D4M4MMNN
:z?aIJJ:q!Xc5)*QFSE99K. ]:&'
 ;$$&,@AEBilGHq[QCED%e, .=CtVU3fq53u:AIDU1q5\!_v--D. U7T!W7777s   )D9rG   )rj   N)NF)rE   )NrD   r   P   r   )F)NNF)/r   r*   r?   rb   rN   r   r   bitarray._utilr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __all__r   r   r   r2   r    r#   r!   r"   r$   r%   r&   r   r'   r(   r}   r/   r.   <module>r      s   
 
 
   )
 
 
 
 
 
 
  ([ [|&R*Z3l(20-&b$N!H48r/   