
from __future__ import annotations

from collections.abc import Iterable
class 			lowercase__:



	"""simple docstring"""




	def __init__(	self  :      Optional[Any]	,							SCREAMING_SNAKE_CASE_  :      Any	,							SCREAMING_SNAKE_CASE_  :      List[str]	)	->					Tuple:
					lowercase_  ,     lowercase_					  = float(SCREAMING_SNAKE_CASE_	), float(SCREAMING_SNAKE_CASE_	)
	def __eq__(	self  :      str	,							SCREAMING_SNAKE_CASE_  :      Optional[int]	)	->					Dict:
					return self.x == other.x and self.y == other.y
	def __ne__(	self  :      Dict	,							SCREAMING_SNAKE_CASE_  :      List[str]	)	->					Union[str, Any]:
					return not self == other
	def __gt__(	self  :      Optional[Any]	,							SCREAMING_SNAKE_CASE_  :      List[Any]	)	->					Optional[Any]:
					if self.x > other.x:
									return True
					elif self.x == other.x:
									return self.y > other.y
					return False
	def __lt__(	self  :      Dict	,							SCREAMING_SNAKE_CASE_  :      List[Any]	)	->					int:
					return not self > other
	def __ge__(	self  :      Dict	,							SCREAMING_SNAKE_CASE_  :      Optional[int]	)	->					str:
					if self.x > other.x:
									return True
					elif self.x == other.x:
									return self.y >= other.y
					return False
	def __le__(	self  :      Tuple	,							SCREAMING_SNAKE_CASE_  :      List[str]	)	->					List[str]:
					if self.x < other.x:
									return True
					elif self.x == other.x:
									return self.y <= other.y
					return False
	def __repr__(	self  :      Optional[int]	)	->					int:
					return f'''({self.x}, {self.y})'''




	def __hash__(	self  :      str	)	->					Dict:
					return hash(self.x	)




def     a						(							snake_case__: list[Point] | list[list[float]] | Iterable[list[float]]						,       ):


				'''simple docstring'''
				lowercase_					  = []
				if list_of_tuples:
								for p in list_of_tuples:
												if isinstance(snake_case__						,       snake_case__ ):
																points.append(snake_case__ )
												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						(							snake_case__: list[Point] | list[list[float]] ):


				'''simple docstring'''

				if not hasattr(snake_case__						,       '''__iter__''' ):
								lowercase_					  = F'''Expecting an iterable object but got an non-iterable type {points}'''
								raise ValueError(snake_case__ )

				if not points:
								lowercase_					  = F'''Expecting a list of points but got {points}'''
								raise ValueError(snake_case__ )

				return _construct_points(snake_case__ )




def     a						(							snake_case__: Point						,       snake_case__: Point						,       snake_case__: Point ):


				'''simple docstring'''
				lowercase_					  = (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						(							snake_case__: list[Point] ):


				'''simple docstring'''
				lowercase_					  = sorted(_validate_input(snake_case__ ) )
				lowercase_					  = len(snake_case__ )
				lowercase_					  = set()

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

																				if det_k > 0:
																								lowercase_					  = True
																				elif det_k < 0:
																								lowercase_					  = 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]:
																												lowercase_					  = False
																												break

																if points_left_of_ij and points_right_of_ij:
																				lowercase_					  = False
																				break

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

				return sorted(snake_case__ )




def     a						(							snake_case__: list[Point] ):


				'''simple docstring'''
				lowercase_					  = sorted(_validate_input(snake_case__ ) )
				lowercase_					  = len(snake_case__ )

				# 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

				lowercase_					  = points[0]
				lowercase_					  = points[n - 1]

				lowercase_					  = {left_most_point, right_most_point}
				lowercase_					  = []
				lowercase_					  = []

				for i in range(1						,       n - 1 ):
								lowercase_					  = _det(snake_case__						,       snake_case__						,       points[i] )

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

				_construct_hull(snake_case__						,       snake_case__						,       snake_case__						,       snake_case__ )
				_construct_hull(snake_case__						,       snake_case__						,       snake_case__						,       snake_case__ )

				return sorted(snake_case__ )




def     a						(							snake_case__: list[Point]						,       snake_case__: Point						,       snake_case__: Point						,       snake_case__: set[Point] ):


				'''simple docstring'''
				if points:
								lowercase_					  = None
								lowercase_					  = float('''-inf''' )
								lowercase_					  = []

								for p in points:
												lowercase_					  = _det(snake_case__						,       snake_case__						,       snake_case__ )

												if det > 0:
																candidate_points.append(snake_case__ )

																if det > extreme_point_distance:
																				lowercase_					  = det
																				lowercase_					  = p

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




def     a						(							snake_case__: list[Point] ):


				'''simple docstring'''
				lowercase_					  = sorted(_validate_input(snake_case__ ) )
				lowercase_					  = len(snake_case__ )

				lowercase_					  = points[:2]
				for i in range(2						,       snake_case__ ):
								lowercase_					  = _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:
												lowercase_					  = points[i]
				i += 1

				for j in range(snake_case__						,       snake_case__ ):
								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(snake_case__ ) > 3 else convex_hull )




def     a						(							):


				'''simple docstring'''
				lowercase_					  = [
				    (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)]
				lowercase_					  = convex_hull_bf(snake_case__ )

				lowercase_					  = convex_hull_recursive(snake_case__ )
				assert results_bf == results_recursive

				lowercase_					  = convex_hull_melkman(snake_case__ )
				assert results_bf == results_melkman

				print(snake_case__ )


if __name__ == "__main__":
						main()






from __future__ import annotations

__a        = 'Alexander Joslin'




def     a						(							snake_case__: int ):


				'''simple docstring'''

				if number <= 0:
								lowercase_					  = F'''n must be greater than 0. Got n = {number}'''
								raise ValueError(snake_case__ )

				lowercase_					  = [number + 1] * (number + 1)

				# starting position
				lowercase_					  = 0
				for i in range(1						,       snake_case__ ):
								lowercase_					  = min(table[i + 1]						,       table[i] + 1 )
								# check if out of bounds
								if i * 2 <= number:
												lowercase_					  = min(table[i * 2]						,       table[i] + 1 )
								# check if out of bounds
								if i * 3 <= number:
												lowercase_					  = min(table[i * 3]						,       table[i] + 1 )
				return table[number]


if __name__ == "__main__":
						import doctest

						doctest.testmod()




