



"""simple docstring"""




from __future__ import annotations

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

_lowerCAmelCase    : Union[str, Any]							=							TypeVar("T")
_lowerCAmelCase    : Tuple							=							TypeVar("U")






class      UpperCAmelCase_  (    Generic[T, U]						):



      def __init__(					self					:     Tuple					,     A					:     T | None					,     A					:     U | None						):
           _UpperCAmelCase      :     List[Any]        =   key
           _UpperCAmelCase      :     Any        =   val
           _UpperCAmelCase      :     DoubleLinkedListNode[T, U] | None        =   None
           _UpperCAmelCase      :     DoubleLinkedListNode[T, U] | None        =   None



      def __repr__(					self					:     Any						):
           return (
               f'Node: key: {self.key}, val: {self.val}, '
               f'has next: {bool(self.next						)}, has prev: {bool(self.prev						)}'
           )







class      UpperCAmelCase_  (    Generic[T, U]						):



      def __init__(					self					:     Union[str, Any]						):
           _UpperCAmelCase      :     DoubleLinkedListNode[T, U]        =   DoubleLinkedListNode(A					,     A						)
           _UpperCAmelCase      :     DoubleLinkedListNode[T, U]        =   DoubleLinkedListNode(A					,     A						)
           _UpperCAmelCase    ,	_UpperCAmelCase      :     Tuple        =   self.rear, self.head



      def __repr__(					self					:     int						):
           _UpperCAmelCase      :     List[Any]        =   ["DoubleLinkedList"]
           _UpperCAmelCase      :     Optional[Any]        =   self.head
           while node.next is not None:
                rep.append(str(A						)						)
                _UpperCAmelCase      :     Optional[Any]        =   node.next
           rep.append(str(self.rear						)						)
           return ",\n    ".join(A						)



      def 						snake_case_ (					self					:     Optional[int]					,     A					:     DoubleLinkedListNode[T, U]						):
           _UpperCAmelCase      :     Tuple        =   self.rear.prev

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

           _UpperCAmelCase      :     int        =   node
           _UpperCAmelCase      :     int        =   previous
           _UpperCAmelCase      :     Optional[Any]        =   node
           _UpperCAmelCase      :     Any        =   self.rear



      def 						snake_case_ (					self					:     List[Any]					,     A					:     DoubleLinkedListNode[T, U]						):

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

           _UpperCAmelCase      :     Optional[Any]        =   node.next
           _UpperCAmelCase      :     List[str]        =   node.prev
           _UpperCAmelCase      :     List[str]        =   None
           _UpperCAmelCase      :     Union[str, Any]        =   None
           return node







class      UpperCAmelCase_  (    Generic[T, U]						):
      __SCREAMING_SNAKE_CASE						:       dict[Callable[[T], U], LRUCache[T, U]]								=			{}



      def __init__(					self					:     List[str]					,     A					:     int						):
           _UpperCAmelCase      :     DoubleLinkedList[T, U]        =   DoubleLinkedList()
           _UpperCAmelCase      :     Optional[int]        =   capacity
           _UpperCAmelCase      :     Any        =   0
           _UpperCAmelCase      :     Optional[Any]        =   0
           _UpperCAmelCase      :     List[Any]        =   0
           _UpperCAmelCase      :     dict[T, DoubleLinkedListNode[T, U]]        =   {}



      def __repr__(					self					:     Any						):
           return (
               f'CacheInfo(hits={self.hits}, misses={self.miss}, '
               f'capacity={self.capacity}, current size={self.num_keys})'
           )



      def __contains__(					self					:     Union[str, Any]					,     A					:     T						):
           return key in self.cache



      def 						snake_case_ (					self					:     Dict					,     A					:     T						):
           # Note: pythonic interface would throw KeyError rather than return None

           if key in self.cache:
                self.hits += 1
                _UpperCAmelCase      :     DoubleLinkedListNode[T, U]        =   self.cache[key]
                _UpperCAmelCase      :     Dict        =   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(A						)
                return node.val
           self.miss += 1
           return None



      def 						snake_case_ (					self					:     Any					,     A					:     T					,     A					:     U						):

           if key not in self.cache:
                if self.num_keys >= self.capacity:
                     # delete first node (oldest) when over capacity
                     _UpperCAmelCase      :     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(A						) is not None
                     )  # node guaranteed to be in list assert node.key is not None

                     del self.cache[first_node.key]
                     self.num_keys -= 1
                _UpperCAmelCase      :     Any        =   DoubleLinkedListNode(A					,     A						)
                self.list.add(self.cache[key]						)
                self.num_keys += 1

           else:
                # bump node to the end of the list, update value
                _UpperCAmelCase      :     Union[str, Any]        =   self.list.remove(self.cache[key]						)
                assert node is not None  # node guaranteed to be in list
                _UpperCAmelCase      :     List[str]        =   value
                self.list.add(A						)



      @classmethod
      def 						snake_case_ (					cls					:     int					,     A					:     int = 1_2_8						):

           def cache_decorator_inner(A					:     Callable[[T], U]						) -> Callable[..., U]:
                def cache_decorator_wrapper(*A					:     T						) -> U:
                     if func not in cls.decorator_function_to_instance_map:
                          _UpperCAmelCase      :     Optional[int]        =   LRUCache(A						)

                     _UpperCAmelCase      :     List[str]        =   cls.decorator_function_to_instance_map[func].get(args[0]						)
                     if result is None:
                          _UpperCAmelCase      :     Union[str, Any]        =   func(*A						)
                          cls.decorator_function_to_instance_map[func].put(args[0]					,     A						)
                     return result

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

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

                return cache_decorator_wrapper

           return cache_decorator_inner


if __name__ == "__main__":
 import doctest

 doctest.testmod()





"""simple docstring"""




from __future__ import annotations

from typing import Any

def 						__snake_case						(				SCREAMING_SNAKE_CASE__     :						list[Any]    )  ->       None:





     '''simple docstring'''

     create_state_space_tree(SCREAMING_SNAKE_CASE__						,  []						,  0    )

def 						__snake_case						(				SCREAMING_SNAKE_CASE__     :						list[Any]						,  SCREAMING_SNAKE_CASE__     :						list[Any]						,  SCREAMING_SNAKE_CASE__     :						int    )  ->       None:





     '''simple docstring'''

     if index == len(SCREAMING_SNAKE_CASE__    ):
          print(SCREAMING_SNAKE_CASE__    )
          return

     create_state_space_tree(SCREAMING_SNAKE_CASE__						,  SCREAMING_SNAKE_CASE__						,  index + 1    )
     current_subsequence.append(sequence[index]    )
     create_state_space_tree(SCREAMING_SNAKE_CASE__						,  SCREAMING_SNAKE_CASE__						,  index + 1    )
     current_subsequence.pop()


if __name__ == "__main__":
 _lowerCAmelCase    : list[Any]							=							[3, 1, 2, 4]
 generate_all_subsequences(seq)

 seq.clear()
 seq.extend(["A", "B", "C"])
 generate_all_subsequences(seq)
