
from collections.abc import Sequence
from queue import Queue




class   __lowercase						:






	def __init__(self				: Union[str, Any]      ,	snake_case				: int      ,	snake_case				: List[Any]      ,	snake_case				: Any      ,	snake_case				: Any=None      ,	snake_case				: Dict=None    ) ->			List[str]:
							_lowercase       :	Optional[Any]           =   start
							_lowercase       :	Optional[int]           =   end
							_lowercase       :	Tuple           =   val
							_lowercase       :	int           =   (start + end) // 2
							_lowercase       :	Dict           =   left
							_lowercase       :	Dict           =   right






	def __repr__(self				: Tuple    ) ->			Optional[int]:
							return F"""SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})"""




class   __lowercase						:






	def __init__(self				: Dict      ,	snake_case				: Sequence      ,	snake_case				: Optional[Any]    ) ->			int:
							_lowercase       :	int           =   collection
							_lowercase       :	Tuple           =   function
							if self.collection:
													_lowercase       :	int           =   self._build_tree(0      ,	len(snake_case    ) - 1    )






	def       _a(self				: Union[str, Any]      ,	snake_case				: Union[str, Any]      ,	snake_case				: Union[str, Any]    ) ->			Union[str, Any]:
							self._update_tree(self.root      ,	snake_case      ,	snake_case    )






	def       _a(self				: int      ,	snake_case				: str      ,	snake_case				: Tuple    ) ->			Optional[int]:
							return self._query_range(self.root      ,	snake_case      ,	snake_case    )






	def       _a(self				: Optional[Any]      ,	snake_case				: str      ,	snake_case				: Any    ) ->			Optional[Any]:
							if start == end:
													return SegmentTreeNode(snake_case      ,	snake_case      ,	self.collection[start]    )
							_lowercase       :	List[str]           =   (start + end) // 2
							_lowercase       :	List[Any]           =   self._build_tree(snake_case      ,	snake_case    )
							_lowercase       :	int           =   self._build_tree(mid + 1      ,	snake_case    )
							return SegmentTreeNode(snake_case      ,	snake_case      ,	self.fn(left.val      ,	right.val    )      ,	snake_case      ,	snake_case    )






	def       _a(self				: Dict      ,	snake_case				: Optional[Any]      ,	snake_case				: Any      ,	snake_case				: str    ) ->			List[Any]:
							if node.start == i and node.end == i:
													_lowercase       :	str           =   val
													return
							if i <= node.mid:
													self._update_tree(node.left      ,	snake_case      ,	snake_case    )
							else:
													self._update_tree(node.right      ,	snake_case      ,	snake_case    )
							_lowercase       :	Tuple           =   self.fn(node.left.val      ,	node.right.val    )






	def       _a(self				: Optional[int]      ,	snake_case				: Tuple      ,	snake_case				: List[str]      ,	snake_case				: Union[str, Any]    ) ->			Dict:
							if node.start == i and node.end == j:
													return node.val

							if i <= node.mid:
													if j <= node.mid:
																			# range in left child tree
																			return self._query_range(node.left      ,	snake_case      ,	snake_case    )
													else:
																			# range in left child tree and right child tree
																			return self.fn(
																			    self._query_range(node.left      ,	snake_case      ,	node.mid    )      ,	self._query_range(node.right      ,	node.mid + 1      ,	snake_case    )      ,	)
							else:
													# range in right child tree
													return self._query_range(node.right      ,	snake_case      ,	snake_case    )






	def       _a(self				: Any    ) ->			Optional[Any]:
							if self.root is not None:
													_lowercase       :	str           =   Queue()
													queue.put(self.root    )
													while not queue.empty():
																			_lowercase       :	int           =   queue.get()
																			yield node

																			if node.left is not None:
																									queue.put(node.left    )

																			if node.right is not None:
																									queue.put(node.right    )


if __name__ == "__main__":
							import operator

							for fn in [operator.add, max, min]:
														print("""*""" * 50)
														UpperCamelCase_						:     Tuple	       =							SegmentTree([2, 1, 5, 3, 4], fn)
														for node in arr.traverse():
																					print(node)
														print()

														arr.update(1, 5)
														for node in arr.traverse():
																					print(node)
														print()

														print(arr.query_range(3, 4))  # 7
														print(arr.query_range(2, 2))  # 5
														print(arr.query_range(1, 3))  # 13
														print()






import math




class   __lowercase						:






	def       _a(self				: Dict      ,	snake_case				: list[list[float]]      ,	snake_case				: list[int]    ) ->			int:
							_lowercase       :	List[Any]           =   0.0
							_lowercase       :	Any           =   0.0
							for i in range(len(snake_case    )    ):
													da += math.pow((sample[i] - weights[0][i])      ,	2    )
													da += math.pow((sample[i] - weights[1][i])      ,	2    )
													return 0 if da > da else 1
							return 0






	def       _a(self				: Dict      ,	snake_case				: list[list[int | float]]      ,	snake_case				: list[int]      ,	snake_case				: int      ,	snake_case				: float    ) ->			list[list[int | float]]:
							for i in range(len(snake_case    )    ):
													weights[j][i] += alpha * (sample[i] - weights[j][i])
							return weights



def 		UpperCamelCase     (       )   ->			None:






						'''simple docstring'''

						_lowercase       :	Union[str, Any]           =   [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 0, 1, 1]]

						# weight initialization ( n, C )
						_lowercase       :	Tuple           =   [[0.2, 0.6, 0.5, 0.9], [0.8, 0.4, 0.7, 0.3]]

						# training
						_lowercase       :	List[Any]           =   SelfOrganizingMap()
						_lowercase       :	Any           =   3
						_lowercase       :	Optional[Any]           =   0.5

						for _ in range(_UpperCAmelCase  ):
												for j in range(len(_UpperCAmelCase  )  ):
																		# training sample
																		_lowercase       :	Optional[int]           =   training_samples[j]

																		# Compute the winning vector
																		_lowercase       :	Tuple           =   self_organizing_map.get_winner(_UpperCAmelCase ,			_UpperCAmelCase  )

																		# Update the winning vector
																		_lowercase       :	str           =   self_organizing_map.update(_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )

    # classify test sample
						_lowercase       :	Any           =   [0, 0, 0, 1]
						_lowercase       :	Dict           =   self_organizing_map.get_winner(_UpperCAmelCase ,			_UpperCAmelCase  )

						# results
						print(f"""Clusters that the test sample belongs to : {winner}"""  )
						print(f"""Weights that have been trained : {weights}"""  )


# running the main() function
if __name__ == "__main__":
							main()




