





from __future__ import annotations







def       lowerCAmelCase__(	lowercase       :    list[int]				) ->    list[int]:
  if not list_of_ints:
    return []

  if min(lowercase				) < 0:
    raise ValueError("All numbers must be positive"				)

  __snake_case   :				List[str]        =       max(len(bin(lowercase				)[2:]				) for x in list_of_ints				)
  return _msd_radix_sort(lowercase   ,     lowercase				)







def       lowerCAmelCase__(	lowercase       :    list[int]   ,     lowercase       :    int				) ->    list[int]:
  if bit_position == 0 or len(lowercase				) in [0, 1]:
    return list_of_ints

  __snake_case   :				List[str]        =       []
  __snake_case   :				Optional[int]        =       []
  # Split numbers based on bit at bit_position from the right
  for number in list_of_ints:
    if (number >> (bit_position - 1)) & 1:
      # number has a one at bit bit_position
      ones.append(lowercase				)
    else:
      # number has a zero at bit bit_position
      zeros.append(lowercase				)

    # recursively split both lists further
  __snake_case   :				Tuple        =       _msd_radix_sort(lowercase   ,     bit_position - 1				)
  __snake_case   :				Dict        =       _msd_radix_sort(lowercase   ,     bit_position - 1				)

  # recombine lists
  __snake_case   :				Dict        =       zeros
  res.extend(lowercase				)

  return res







def       lowerCAmelCase__(	lowercase       :    list[int]				) ->    int:
  __snake_case   :				Tuple        =       len(lowercase				)
  if not list_of_ints or length == 1:
    return

  if min(lowercase				) < 0:
    raise ValueError("All numbers must be positive"				)

  __snake_case   :				List[str]        =       max(len(bin(lowercase				)[2:]				) for x in list_of_ints				)
  _msd_radix_sort_inplace(lowercase   ,     lowercase   ,     0   ,     lowercase				)







def       lowerCAmelCase__(	lowercase       :    list[int]   ,     lowercase       :    int   ,     lowercase       :    int   ,     lowercase       :    int				) ->    Union[str, Any]:
  if bit_position == 0 or end_index - begin_index <= 1:
    return

  bit_position -= 1

  __snake_case   :				int        =       begin_index
  __snake_case   :				Any        =       end_index - 1
  while i <= j:
    __snake_case   :				Tuple        =       False
    if not (list_of_ints[i] >> bit_position) & 1:
      # found zero at the beginning
      i += 1
      __snake_case   :				Any        =       True
    if (list_of_ints[j] >> bit_position) & 1:
      # found one at the end
      j -= 1
      __snake_case   :				Tuple        =       True

    if changed:
      continue

    __snake_case    ,   __snake_case   :				int        =       list_of_ints[j], list_of_ints[i]
    j -= 1
    if j != i:
      i += 1

  _msd_radix_sort_inplace(lowercase   ,     lowercase   ,     lowercase   ,     lowercase				)
  _msd_radix_sort_inplace(lowercase   ,     lowercase   ,     lowercase   ,     lowercase				)


if __name__ == "__main__":
     import doctest

     doctest.testmod()








from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

_UpperCamelCase       = TypeVar('''T''')
_UpperCamelCase       = TypeVar('''U''')




class 				_lowerCamelCase (    Generic[T, U]    ):



      """simple docstring"""






      def __init__( self				,						UpperCAmelCase				,						UpperCAmelCase   )       ->   Dict:






        '''simple docstring'''






        __snake_case   :				Any        =       key
        __snake_case   :				Tuple        =       val
        __snake_case   :				int        =       0
        __snake_case   :				DoubleLinkedListNode[T, U] | None        =       None
        __snake_case   :				DoubleLinkedListNode[T, U] | None        =       None







      def __repr__( self   )       ->   str:






        '''simple docstring'''






        return "Node: key: {}, val: {}, freq: {}, has next: {}, has prev: {}".format(
            self.key				,						self.val				,						self.freq				,						self.next is not None				,						self.prev is not None   )




class 				_lowerCamelCase (    Generic[T, U]    ):



      """simple docstring"""






      def __init__( self   )       ->   None:






        '''simple docstring'''






        __snake_case   :				DoubleLinkedListNode[T, U]        =       DoubleLinkedListNode(UpperCAmelCase				,						UpperCAmelCase   )
        __snake_case   :				DoubleLinkedListNode[T, U]        =       DoubleLinkedListNode(UpperCAmelCase				,						UpperCAmelCase   )
        __snake_case    ,   __snake_case   :				Any        =       self.rear, self.head







      def __repr__( self   )       ->   str:






        '''simple docstring'''






        __snake_case   :				Union[str, Any]        =       ["DoubleLinkedList"]
        __snake_case   :				List[Any]        =       self.head
        while node.next is not None:
          rep.append(str(UpperCAmelCase   )   )
          __snake_case   :				List[Any]        =       node.next
        rep.append(str(self.rear   )   )
        return ",\n    ".join(UpperCAmelCase   )







      def 						UpperCAmelCase		( self				,						UpperCAmelCase   )       ->   None:






        '''simple docstring'''






        __snake_case   :				Dict        =       self.rear.prev

        # All nodes other than self.head are guaranteed to have non-None previous
        assert previous is not None

        __snake_case   :				int        =       node
        __snake_case   :				List[str]        =       previous
        __snake_case   :				Optional[int]        =       node
        __snake_case   :				int        =       self.rear
        node.freq += 1
        self._position_node(UpperCAmelCase   )







      def 						UpperCAmelCase		( self				,						UpperCAmelCase   )       ->   None:






        '''simple docstring'''






        while node.prev is not None and node.prev.freq > node.freq:
          # swap node with previous node
          __snake_case   :				List[Any]        =       node.prev

          __snake_case   :				Dict        =       previous_node.prev
          __snake_case   :				Union[str, Any]        =       node.prev
          __snake_case   :				Union[str, Any]        =       previous_node
          __snake_case   :				int        =       node







      def 						UpperCAmelCase		( self				,						UpperCAmelCase   )       ->   DoubleLinkedListNode[T, U] | None:






        '''simple docstring'''






        if node.prev is None or node.next is None:
          return None

        __snake_case   :				Optional[int]        =       node.next
        __snake_case   :				Optional[Any]        =       node.prev
        __snake_case   :				Optional[int]        =       None
        __snake_case   :				Any        =       None
        return node




class 				_lowerCamelCase (    Generic[T, U]    ):



      """simple docstring"""






      UpperCAmelCase_						:      dict[Callable[[T], U], LFUCache[T, U]]       ={}







      def __init__( self				,						UpperCAmelCase   )       ->   Tuple:






        '''simple docstring'''






        __snake_case   :				DoubleLinkedList[T, U]        =       DoubleLinkedList()
        __snake_case   :				str        =       capacity
        __snake_case   :				str        =       0
        __snake_case   :				Optional[int]        =       0
        __snake_case   :				Any        =       0
        __snake_case   :				dict[T, DoubleLinkedListNode[T, U]]        =       {}







      def __repr__( self   )       ->   str:






        '''simple docstring'''






        return (
            F"""CacheInfo(hits={self.hits}, misses={self.miss}, """
            F"""capacity={self.capacity}, current_size={self.num_keys})"""
        )







      def __contains__( self				,						UpperCAmelCase   )       ->   bool:






        '''simple docstring'''






        return key in self.cache







      def 						UpperCAmelCase		( self				,						UpperCAmelCase   )       ->   U | None:






        '''simple docstring'''






        if key in self.cache:
          self.hits += 1
          __snake_case   :				DoubleLinkedListNode[T, U]        =       self.cache[key]
          __snake_case   :				Union[str, Any]        =       self.list.remove(self.cache[key]   )
          assert node == value_node

          # node is guaranteed not None because it is in self.cache
          assert node is not None
          self.list.add(UpperCAmelCase   )
          return node.val
        self.miss += 1
        return None







      def 						UpperCAmelCase		( self				,						UpperCAmelCase				,						UpperCAmelCase   )       ->   None:






        '''simple docstring'''






        if key not in self.cache:
          if self.num_keys >= self.capacity:
            # delete first node when over capacity
            __snake_case   :				Optional[Any]        =       self.list.head.next

            # guaranteed to have a non-None first node when num_keys > 0
            # explain to type checker via assertions
            assert first_node is not None
            assert first_node.key is not None
            assert self.list.remove(UpperCAmelCase   ) is not None
            # first_node guaranteed to be in list

            del self.cache[first_node.key]
            self.num_keys -= 1
          __snake_case   :				Union[str, Any]        =       DoubleLinkedListNode(UpperCAmelCase				,						UpperCAmelCase   )
          self.list.add(self.cache[key]   )
          self.num_keys += 1

        else:
          __snake_case   :				Union[str, Any]        =       self.list.remove(self.cache[key]   )
          assert node is not None  # node guaranteed to be in list
          __snake_case   :				Optional[Any]        =       value
          self.list.add(UpperCAmelCase   )







      @classmethod
      def 						UpperCAmelCase		( cls				,						UpperCAmelCase = 128   )       ->   Callable[[Callable[[T], U]], Callable[..., U]]:






        '''simple docstring'''






        def cache_decorator_inner(UpperCAmelCase   ) -> Callable[..., U]:
          def cache_decorator_wrapper(*UpperCAmelCase   ) -> U:
            if func not in cls.decorator_function_to_instance_map:
              __snake_case   :				str        =       LFUCache(UpperCAmelCase   )

            __snake_case   :				Dict        =       cls.decorator_function_to_instance_map[func].get(args[0]   )
            if result is None:
              __snake_case   :				Optional[int]        =       func(*UpperCAmelCase   )
              cls.decorator_function_to_instance_map[func].put(args[0]				,						UpperCAmelCase   )
            return result

          def cache_info() -> LFUCache[T, U]:
            return cls.decorator_function_to_instance_map[func]

          setattr(UpperCAmelCase				,						"cache_info"				,						UpperCAmelCase   )  # noqa: B010

          return cache_decorator_wrapper

        return cache_decorator_inner


if __name__ == "__main__":
     import doctest

     doctest.testmod()

