
class 				_UpperCamelCase :






			'''simple docstring'''

			def __init__(				self       :				int  ,		snake_case_       :				List[Any]					):
							UpperCamelCase_:							int		=  data
							UpperCamelCase_:							Optional[Any]		=  None
							UpperCamelCase_:							Optional[Any]		=  None




			def __str__(				self       :				List[Any]					):
							return f'''{self.data}'''




class 				_UpperCamelCase :






			'''simple docstring'''

			def __init__(				self       :				Optional[Any]					):
							UpperCamelCase_:							List[str]		=  None
							UpperCamelCase_:							Union[str, Any]		=  None

			def __iter__(				self       :				Optional[int]					):
							UpperCamelCase_:							int		=  self.head
							while node:
											yield node.data
											UpperCamelCase_:							Tuple		=  node.next

			def __str__(				self       :				str					):
							return "->".join([str(lowerCamelCase_					) for item in self]					)

			def __len__(				self       :				Dict					):
							return sum(1 for _ in self					)

			def 					lowerCAmelCase__		(				self       :				Union[str, Any]  ,		snake_case_       :				List[str]					):
							self.insert_at_nth(0  ,		lowerCamelCase_					)

			def 					lowerCAmelCase__		(				self       :				str  ,		snake_case_       :				int					):
							self.insert_at_nth(len(self					)  ,		lowerCamelCase_					)

			def 					lowerCAmelCase__		(				self       :				List[Any]  ,		snake_case_       :				int  ,		snake_case_       :				Dict					):
							UpperCamelCase_:							Dict		=  len(self					)

							if not 0 <= index <= length:
											raise IndexError("""list index out of range"""					)
							UpperCamelCase_:							Optional[int]		=  Node(lowerCamelCase_					)
							if self.head is None:
											UpperCamelCase_:							int		=  new_node
							elif index == 0:
											UpperCamelCase_:							Dict		=  new_node
											UpperCamelCase_:							int		=  self.head
											UpperCamelCase_:							Tuple		=  new_node
							elif index == length:
											UpperCamelCase_:							Dict		=  new_node
											UpperCamelCase_:							Optional[Any]		=  self.tail
											UpperCamelCase_:							Dict		=  new_node
							else:
											UpperCamelCase_:							List[Any]		=  self.head
											for _ in range(0  ,		lowerCamelCase_					):
															UpperCamelCase_:							Optional[Any]		=  temp.next
											UpperCamelCase_:							Dict		=  new_node
											UpperCamelCase_:							Union[str, Any]		=  temp.previous
											UpperCamelCase_:							Any		=  temp
											UpperCamelCase_:							List[Any]		=  new_node

			def 					lowerCAmelCase__		(				self       :				Any					):
							return self.delete_at_nth(0					)

			def 					lowerCAmelCase__		(				self       :				List[Any]					):
							return self.delete_at_nth(len(self					) - 1					)

			def 					lowerCAmelCase__		(				self       :				int  ,		snake_case_       :				Tuple					):
							UpperCamelCase_:							Dict		=  len(self					)

							if not 0 <= index <= length - 1:
											raise IndexError("""list index out of range"""					)
							UpperCamelCase_:							List[str]		=  self.head  # default first node
							if length == 1:
											UpperCamelCase_:							List[str]		=  None
							elif index == 0:
											UpperCamelCase_:							Union[str, Any]		=  self.head.next
											UpperCamelCase_:							List[str]		=  None
							elif index == length - 1:
											UpperCamelCase_:							Union[str, Any]		=  self.tail
											UpperCamelCase_:							Optional[int]		=  self.tail.previous
											UpperCamelCase_:							Dict		=  None
							else:
											UpperCamelCase_:							Union[str, Any]		=  self.head
											for _ in range(0  ,		lowerCamelCase_					):
															UpperCamelCase_:							str		=  temp.next
											UpperCamelCase_:							Optional[Any]		=  temp
											UpperCamelCase_:							str		=  temp.previous
											UpperCamelCase_:							Any		=  temp.next
							return delete_node.data

			def 					lowerCAmelCase__		(				self       :				int  ,		snake_case_       :				Tuple					):
							UpperCamelCase_:							List[str]		=  self.head

							while current.data != data:  # Find the position to delete
											if current.next:
															UpperCamelCase_:							Optional[int]		=  current.next
											else:  # We have reached the end an no value matches
															raise ValueError("""No data matching given value"""					)

							if current == self.head:
											self.delete_head()

							elif current == self.tail:
											self.delete_tail()

							else:  # Before: 1 <--> 2(current) <--> 3
											UpperCamelCase_:							Union[str, Any]		=  current.next  # 1 --> 3
											UpperCamelCase_:							int		=  current.previous  # 1 <--> 3
							return data




			def 					lowerCAmelCase__		(				self       :				str					):
							return len(self					) == 0







def 				A__    (  )     ->		None:
				UpperCamelCase_:							Optional[int]		=  DoublyLinkedList()
				assert linked_list.is_empty() is True
				assert str(lowerCamelCase  ) == ""

				try:
								linked_list.delete_head()
								raise AssertionError  # This should not happen.
				except IndexError:
								assert True  # This should happen.

				try:
								linked_list.delete_tail()
								raise AssertionError  # This should not happen.
				except IndexError:
								assert True  # This should happen.

				for i in range(10  ):
								assert len(lowerCamelCase  ) == i
								linked_list.insert_at_nth(lowerCamelCase   ,			i + 1  )
				assert str(lowerCamelCase  ) == "->".join(str(lowerCamelCase  ) for i in range(1   ,			11  )  )

				linked_list.insert_at_head(0  )
				linked_list.insert_at_tail(11  )
				assert str(lowerCamelCase  ) == "->".join(str(lowerCamelCase  ) for i in range(0   ,			12  )  )

				assert linked_list.delete_head() == 0
				assert linked_list.delete_at_nth(9  ) == 10
				assert linked_list.delete_tail() == 11
				assert len(lowerCamelCase  ) == 9
				assert str(lowerCamelCase  ) == "->".join(str(lowerCamelCase  ) for i in range(1   ,			10  )  )


if __name__ == "__main__":
							from doctest import testmod

							testmod()










'''simple docstring'''






from .hash_table import HashTable
from .number_theory.prime_numbers import is_prime, next_prime




class 		a__				(							a__  ):





							'''simple docstring'''






							def __init__(		self					,    *lowerCamelCase_					,    **lowerCamelCase_   )       ->							Optional[int]:
														super().__init__(*lowerCamelCase_					,    **lowerCamelCase_   )







							def   __SCREAMING_SNAKE_CASE							(		self					,    lowerCamelCase_					,    lowerCamelCase_   )       ->							Optional[int]:
														lowerCAmelCase__          =	(
														    next_prime(value % self.size_table   )
														    if not is_prime(value % self.size_table   )
														    else value % self.size_table
														)  # gt = bigger than
														return next_prime_gt - (data % next_prime_gt)







							def   __SCREAMING_SNAKE_CASE							(		self					,    lowerCamelCase_					,    lowerCamelCase_					,    lowerCamelCase_   )       ->							Optional[int]:
														return (increment * self.__hash_function_a(lowerCamelCase_					,    lowerCamelCase_   )) % self.size_table







							def   __SCREAMING_SNAKE_CASE							(		self					,    lowerCamelCase_					,    lowerCamelCase_=None   )       ->							Any:
														lowerCAmelCase__          =	1
														lowerCAmelCase__          =	self.hash_function(lowerCamelCase_   )

														while self.values[new_key] is not None and self.values[new_key] != key:
																					lowerCAmelCase__          =	(
																					    self.__hash_double_function(lowerCamelCase_					,    lowerCamelCase_					,    lowerCamelCase_   )
																					    if self.balanced_factor() >= self.lim_charge
																					    else None
																					)
																					if new_key is None:
																												break
																					else:
																												i += 1

														return new_key