



'''simple docstring'''






from __future__ import annotations

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

class     SCREAMING_SNAKE_CASE(							A__      ):







 """simple docstring"""






 lowerCamelCase__      			=	1
 lowerCamelCase__      			=	2
 lowerCamelCase__      			=	3







 def __repr__(						self      :					Union[str, Any]		)      ->		Any:
        return F"""{self.__class__.__name__}.{self.name}"""


def 			snake_case_					( _lowerCAmelCase  :						tuple[int, int]       ,				_lowerCAmelCase  :						int       ,				_lowerCAmelCase  :						int  )				->       float:
       UpperCAmelCase			:	Optional[int]										=		point
       return degrees(atana(y - miny       ,				x - minx  )  )


def 			snake_case_					( _lowerCAmelCase  :						tuple[int, int]       ,				_lowerCAmelCase  :						tuple[int, int]       ,				_lowerCAmelCase  :						tuple[int, int]  )				->       Direction:
       UpperCAmelCase			:	Any										=		starting
       UpperCAmelCase			:	Any										=		via
       UpperCAmelCase			:	int										=		target
       UpperCAmelCase			:	Optional[Any]										=		degrees(atana(ya - ya       ,				xa - xa  )  )
       via_angle %= 360
       UpperCAmelCase			:	Dict										=		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 			snake_case_					( _lowerCAmelCase  :						list[tuple[int, int]]  )				->       list[tuple[int, int]]:

       if len(_lowerCAmelCase  ) <= 2:
              # There is no convex hull
              raise ValueError('''graham_scan: argument must contain more than 3 points.'''  )
       if len(_lowerCAmelCase  ) == 3:
              return points
       # find the lowest and the most left point
       UpperCAmelCase			:	List[Any]										=		0
       UpperCAmelCase			:	Any										=		maxsize, maxsize
       for i, point in enumerate(_lowerCAmelCase  ):
              UpperCAmelCase			:	int										=		point[0]
              UpperCAmelCase			:	Union[str, Any]										=		point[1]
              if y < miny:
                     UpperCAmelCase			:	Optional[Any]										=		y
                     UpperCAmelCase			:	Any										=		x
                     UpperCAmelCase			:	List[Any]										=		i
              if y == miny and x < minx:
                     UpperCAmelCase			:	List[str]										=		x
                     UpperCAmelCase			:	Union[str, Any]										=		i

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

       UpperCAmelCase			:	List[Any]										=		sorted(_lowerCAmelCase       ,				key=lambda _lowerCAmelCase  : angle_comparer(_lowerCAmelCase       ,				_lowerCAmelCase       ,				_lowerCAmelCase  )  )
       # 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[tuple[int, int]]										=		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			:	Any										=		Direction.left

       for i in range(3       ,				len(_lowerCAmelCase  )  ):
              while True:
                     UpperCAmelCase			:	Union[str, Any]										=		stack[-2]
                     UpperCAmelCase			:	Dict										=		stack[-1]
                     UpperCAmelCase			:	int										=		sorted_points[i]
                     UpperCAmelCase			:	List[str]										=		check_direction(_lowerCAmelCase       ,				_lowerCAmelCase       ,				_lowerCAmelCase  )

                     if next_direction == Direction.left:
                            UpperCAmelCase			:	Any										=		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(_lowerCAmelCase  )










'''simple docstring'''






import importlib.metadata
import subprocess
import sys


def 			snake_case_					( _lowerCAmelCase  :						bool = False  )				->       str:
							UpperCAmelCase			:	List[str]										=		False
							if "IPython" in sys.modules:
														UpperCAmelCase			:	Optional[Any]										=		'''google.colab''' in str(sys.modules['''IPython'''].get_ipython()  )

							if in_colab:
														if upgrade:
																					UpperCAmelCase			:	List[Any]										=		['''pip''', '''install''', '''-U''', '''torch''']
																					subprocess.run(_lowerCAmelCase       ,				check=_lowerCAmelCase  )
														# get the current version of torch
														UpperCAmelCase			:	Dict										=		importlib.metadata.version('''torch'''  )
														UpperCAmelCase			:	int										=		torch_version[: torch_version.rindex('''.'''  )]
														UpperCAmelCase			:	Any										=		f"""https://storage.googleapis.com/tpu-pytorch/wheels/colab/torch_xla-{torch_version_trunc}-cp37-cp37m-linux_x86_64.whl"""
														UpperCAmelCase			:	List[str]										=		['''pip''', '''install''', xla_wheel]
														subprocess.run(_lowerCAmelCase       ,				check=_lowerCAmelCase  )
							else:
														raise RuntimeError('''`install_xla` utility works only on google colab.'''  )





