

from __future__ import annotations

from collections.abc import Iterable






class 				A_					:


     def __init__(				self     :						int     ,    UpperCAmelCase     :						Tuple     ,    UpperCAmelCase     :						Optional[Any]   )				->      Any:
      __lowerCAmelCase      ,				__lowerCAmelCase:  str        = float(_lowercase   ), float(_lowercase   )


     def __eq__(				self     :						int     ,    UpperCAmelCase     :						int   )				->      List[str]:
      return self.x == other.x and self.y == other.y


     def __ne__(				self     :						Any     ,    UpperCAmelCase     :						Tuple   )				->      Dict:
      return not self == other


     def __gt__(				self     :						Optional[Any]     ,    UpperCAmelCase     :						List[str]   )				->      Dict:
      if self.x > other.x:
       return True
      elif self.x == other.x:
       return self.y > other.y
      return False


     def __lt__(				self     :						List[str]     ,    UpperCAmelCase     :						Dict   )				->      Tuple:
      return not self > other


     def __ge__(				self     :						Tuple     ,    UpperCAmelCase     :						Optional[Any]   )				->      Union[str, Any]:
      if self.x > other.x:
       return True
      elif self.x == other.x:
       return self.y >= other.y
      return False


     def __le__(				self     :						List[Any]     ,    UpperCAmelCase     :						List[str]   )				->      Tuple:
      if self.x < other.x:
       return True
      elif self.x == other.x:
       return self.y <= other.y
      return False


     def __repr__(				self     :						int   )				->      Optional[int]:
      return F'''({self.x}, {self.y})'''


     def __hash__(				self     :						List[str]   )				->      List[Any]:
      return hash(self.x   )







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point] | list[list[float]] | Iterable[list[float]]       ,   )       ->       list[Point]:

 """simple docstring"""






 __lowerCAmelCase:  str        = []
 if list_of_tuples:
  for p in list_of_tuples:
   if isinstance(UpperCAmelCase__       ,   UpperCAmelCase__						):
    points.append(UpperCAmelCase__						)
   else:
    try:
     points.append(Point(p[0]       ,   p[1]						)						)
    except (IndexError, TypeError):
     print(
         f'''Ignoring deformed point {p}. All points'''
         ' must have at least 2 coordinates.'						)
 return points







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point] | list[list[float]]						)       ->       list[Point]:

 """simple docstring"""






 if not hasattr(UpperCAmelCase__       ,   '__iter__'						):
  __lowerCAmelCase:  Union[str, Any]        = f'''Expecting an iterable object but got an non-iterable type {points}'''
  raise ValueError(UpperCAmelCase__						)

 if not points:
  __lowerCAmelCase:  Optional[int]        = f'''Expecting a list of points but got {points}'''
  raise ValueError(UpperCAmelCase__						)

 return _construct_points(UpperCAmelCase__						)







def _a					(			SCREAMING_SNAKE_CASE						:     Point       ,   SCREAMING_SNAKE_CASE						:     Point       ,   SCREAMING_SNAKE_CASE						:     Point						)       ->       float:

 """simple docstring"""






 __lowerCAmelCase:  int        = (a.x * b.y + b.x * c.y + c.x * a.y) - (a.y * b.x + b.y * c.x + c.y * a.x)
 return det







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point]						)       ->       list[Point]:

 """simple docstring"""






 __lowerCAmelCase:  Tuple        = sorted(_validate_input(UpperCAmelCase__						)						)
 __lowerCAmelCase:  Any        = len(UpperCAmelCase__						)
 __lowerCAmelCase:  Optional[int]        = set()

 for i in range(n - 1						):
  for j in range(i + 1       ,   UpperCAmelCase__						):
   __lowerCAmelCase:  Tuple        = False
   __lowerCAmelCase:  Any        = True
   for k in range(UpperCAmelCase__						):
    if k != i and k != j:
     __lowerCAmelCase:  Tuple        = _det(points[i]       ,   points[j]       ,   points[k]						)

     if det_k > 0:
      __lowerCAmelCase:  int        = True
     elif det_k < 0:
      __lowerCAmelCase:  Tuple        = True
     else:
      # point[i], point[j], point[k] all lie on a straight line
      # if point[k] is to the left of point[i] or it's to the
      # right of point[j], then point[i], point[j] cannot be
      # part of the convex hull of A
      if points[k] < points[i] or points[k] > points[j]:
       __lowerCAmelCase:  Union[str, Any]        = False
       break

    if points_left_of_ij and points_right_of_ij:
     __lowerCAmelCase:  List[Any]        = False
     break

   if ij_part_of_convex_hull:
    convex_set.update([points[i], points[j]]						)

 return sorted(UpperCAmelCase__						)







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point]						)       ->       list[Point]:

 """simple docstring"""






 __lowerCAmelCase:  Optional[Any]        = sorted(_validate_input(UpperCAmelCase__						)						)
 __lowerCAmelCase:  str        = len(UpperCAmelCase__						)

 # divide all the points into an upper hull and a lower hull
 # the left most point and the right most point are definitely
 # members of the convex hull by definition.
 # use these two anchors to divide all the points into two hulls,
 # an upper hull and a lower hull.

 # all points to the left (above) the line joining the extreme points belong to the
 # upper hull
 # all points to the right (below) the line joining the extreme points below to the
 # lower hull
 # ignore all points on the line joining the extreme points since they cannot be
 # part of the convex hull

 __lowerCAmelCase:  Tuple        = points[0]
 __lowerCAmelCase:  str        = points[n - 1]

 __lowerCAmelCase:  str        = {left_most_point, right_most_point}
 __lowerCAmelCase:  int        = []
 __lowerCAmelCase:  Optional[int]        = []

 for i in range(1       ,   n - 1						):
  __lowerCAmelCase:  List[str]        = _det(UpperCAmelCase__       ,   UpperCAmelCase__       ,   points[i]						)

  if det > 0:
   upper_hull.append(points[i]						)
  elif det < 0:
   lower_hull.append(points[i]						)

 _construct_hull(UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__						)
 _construct_hull(UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__						)

 return sorted(UpperCAmelCase__						)







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point]       ,   SCREAMING_SNAKE_CASE						:     Point       ,   SCREAMING_SNAKE_CASE						:     Point       ,   SCREAMING_SNAKE_CASE						:     set[Point]						)       ->       None:

 """simple docstring"""






 if points:
  __lowerCAmelCase:  int        = None
  __lowerCAmelCase:  Union[str, Any]        = float('-inf'						)
  __lowerCAmelCase:  List[str]        = []

  for p in points:
   __lowerCAmelCase:  List[str]        = _det(UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__						)

   if det > 0:
    candidate_points.append(UpperCAmelCase__						)

    if det > extreme_point_distance:
     __lowerCAmelCase:  Optional[Any]        = det
     __lowerCAmelCase:  List[Any]        = p

  if extreme_point:
   _construct_hull(UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__						)
   convex_set.add(UpperCAmelCase__						)
   _construct_hull(UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__       ,   UpperCAmelCase__						)







def _a					(			SCREAMING_SNAKE_CASE						:     list[Point]						)       ->       list[Point]:

 """simple docstring"""






 __lowerCAmelCase:  Any        = sorted(_validate_input(UpperCAmelCase__						)						)
 __lowerCAmelCase:  str        = len(UpperCAmelCase__						)

 __lowerCAmelCase:  int        = points[:2]
 for i in range(2       ,   UpperCAmelCase__						):
  __lowerCAmelCase:  int        = _det(convex_hull[1]       ,   convex_hull[0]       ,   points[i]						)
  if det > 0:
   convex_hull.insert(0       ,   points[i]						)
   break
  elif det < 0:
   convex_hull.append(points[i]						)
   break
  else:
   __lowerCAmelCase:  Any        = points[i]
 i += 1

 for j in range(UpperCAmelCase__       ,   UpperCAmelCase__						):
  if (
      _det(convex_hull[0]       ,   convex_hull[-1]       ,   points[j]						) > 0
      and _det(convex_hull[-1]       ,   convex_hull[0]       ,   points[1]						) < 0
  ):
   # The point lies within the convex hull
   continue

  convex_hull.insert(0       ,   points[j]						)
  convex_hull.append(points[j]						)
  while _det(convex_hull[0]       ,   convex_hull[1]       ,   convex_hull[2]						) >= 0:
   del convex_hull[1]
  while _det(convex_hull[-1]       ,   convex_hull[-2]       ,   convex_hull[-3]						) <= 0:
   del convex_hull[-2]

    # `convex_hull` is contains the convex hull in circular order
 return sorted(convex_hull[1:] if len(UpperCAmelCase__						) > 3 else convex_hull						)







def _a					(			)       ->       List[str]:

 """simple docstring"""






 __lowerCAmelCase:  Optional[Any]        = [
     (0, 3),
     (2, 2),
     (1, 1),
     (2, 1),
     (3, 0),
     (0, 0),
     (3, 3),
     (2, -1),
     (2, -4),
     (1, -3),
 ]
 # the convex set of points is
 # [(0, 0), (0, 3), (1, -3), (2, -4), (3, 0), (3, 3)]
 __lowerCAmelCase:  Union[str, Any]        = convex_hull_bf(UpperCAmelCase__						)

 __lowerCAmelCase:  Optional[int]        = convex_hull_recursive(UpperCAmelCase__						)
 assert results_bf == results_recursive

 __lowerCAmelCase:  Tuple        = convex_hull_melkman(UpperCAmelCase__						)
 assert results_bf == results_melkman

 print(UpperCAmelCase__						)


if __name__ == "__main__":
  main()






"""simple docstring"""







def 	a__   (		UpperCAmelCase__							:      list[int]      )->						int:
						UpperCAmelCase__       						=		len(UpperCAmelCase__      )
						if n in (0, 1):
												return 0
						return sum(query * (n - i - 1) for i, query in enumerate(sorted(UpperCAmelCase__      )      )      )


if __name__ == "__main__":
						import doctest

						doctest.testmod()

