




from __future__ import annotations

from collections import deque
from enum import Enum
from math import atana, degrees
from sys import maxsize






class    __lowerCAmelCase			(	UpperCAmelCase__			):
			snake_case_				:			List[Any]								=					1
			snake_case_				:			int								=					2
			snake_case_				:			Any								=					3







			def __repr__(	self   :      Union[str, Any]				):




									"""simple docstring"""


									return F"""{self.__class__.__name__}.{self.name}"""




def 							__SCREAMING_SNAKE_CASE  (      snake_case_     ,   snake_case_     ,   snake_case_						):

						'''simple docstring'''


						_UpperCAmelCase							,			_UpperCAmelCase													=					point
						return degrees(atana(y - miny     ,   x - minx						)						)


def 							__SCREAMING_SNAKE_CASE  (      snake_case_     ,   snake_case_     ,   snake_case_						):

						'''simple docstring'''


						_UpperCAmelCase							,			_UpperCAmelCase													=					starting
						_UpperCAmelCase							,			_UpperCAmelCase													=					via
						_UpperCAmelCase							,			_UpperCAmelCase													=					target
						_UpperCAmelCase													=					degrees(atana(ya - ya     ,   xa - xa						)						)
						via_angle %= 360
						_UpperCAmelCase													=					degrees(atana(ya - ya     ,   xa - xa						)						)
						target_angle %= 360
						# t-
						#  \ \
						#   \ v
						#    \|
						#     s
						# via_angle is always lower than target_angle, if direction is left.
						# If they are same, it means they are on a same line of convex hull.
						if target_angle > via_angle:
												return Direction.left
						elif target_angle == via_angle:
												return Direction.straight
						else:
												return Direction.right





def 							__SCREAMING_SNAKE_CASE  (      snake_case_						):

						'''simple docstring'''


						if len(snake_case_						) <= 2:
												# There is no convex hull
												raise ValueError("graham_scan: argument must contain more than 3 points."						)
						if len(snake_case_						) == 3:
												return points
						# find the lowest and the most left point
						_UpperCAmelCase													=					0
						_UpperCAmelCase							,			_UpperCAmelCase													=					maxsize, maxsize
						for i, point in enumerate(snake_case_						):
												_UpperCAmelCase													=					point[0]
												_UpperCAmelCase													=					point[1]
												if y < miny:
																		_UpperCAmelCase													=					y
																		_UpperCAmelCase													=					x
																		_UpperCAmelCase													=					i
												if y == miny and x < minx:
																		_UpperCAmelCase													=					x
																		_UpperCAmelCase													=					i

    # remove the lowest and the most left point from points for preparing for sort
						points.pop(snake_case_						)

						_UpperCAmelCase													=					sorted(snake_case_     ,   key=lambda snake_case_						: angle_comparer(snake_case_     ,   snake_case_     ,   snake_case_						)						)
						# This insert actually costs complexity,
						# and you should instead add (minx, miny) into stack later.
						# I'm using insert just for easy understanding.
						sorted_points.insert(0     ,   (minx, miny)						)

						_UpperCAmelCase													=					deque()
						stack.append(sorted_points[0]						)
						stack.append(sorted_points[1]						)
						stack.append(sorted_points[2]						)
						# In any ways, the first 3 points line are towards left.
						# Because we sort them the angle from minx, miny.
						_UpperCAmelCase													=					Direction.left

						for i in range(3     ,   len(snake_case_						)						):
												while True:
																		_UpperCAmelCase													=					stack[-2]
																		_UpperCAmelCase													=					stack[-1]
																		_UpperCAmelCase													=					sorted_points[i]
																		_UpperCAmelCase													=					check_direction(snake_case_     ,   snake_case_     ,   snake_case_						)

																		if next_direction == Direction.left:
																								_UpperCAmelCase													=					Direction.left
																								break
																		if next_direction == Direction.straight:
																								if current_direction == Direction.left:
																														# We keep current_direction as left.
																														# Because if the straight line keeps as straight,
																														# we want to know if this straight line is towards left.
																														break
																								elif current_direction == Direction.right:
																														# If the straight line is towards right,
																														# every previous points on those straigh line is not convex hull.
																														stack.pop()
																		if next_direction == Direction.right:
																								stack.pop()
												stack.append(sorted_points[i]						)
						return list(snake_case_						)










from __future__ import annotations

from collections.abc import Generator


def 							__SCREAMING_SNAKE_CASE  (      snake_case_						):

						'''simple docstring'''


						if not isinstance(snake_case_     ,   snake_case_						) or n < 1:
												raise Exception("Sequence only defined for positive integers"						)

						yield n
						while n != 1:
												if n % 2 == 0:
																		n //= 2
												else:
																		_UpperCAmelCase													=					3 * n + 1
												yield n


def 							__SCREAMING_SNAKE_CASE  (      ):

						'''simple docstring'''


						_UpperCAmelCase													=					43
						_UpperCAmelCase													=					tuple(collatz_sequence(snake_case_						)						)
						print(snake_case_						)
						print(f"""Collatz sequence from {n} took {len(snake_case_						)} steps."""						)


if __name__ == "__main__":
				main()




