






from __future__ import annotations

from collections import deque
from enum import Enum
from math import atana, degrees
from sys import maxsize
class 	a_(		lowercase__	):



     """simple docstring"""



     __snake_case		:				str  					=1
     __snake_case		:				Union[str, Any]  					=2
     __snake_case		:				Tuple  					=3





     def __repr__(		self					:	str)							->	Optional[int]:

      """simple docstring"""
      return f'''{self.__class__.__name__}.{self.name}'''





def 						A_					(						lowercase_	,  lowercase_	,  lowercase_			)				->float:







 """simple docstring"""

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





def 						A_					(						lowercase_	,  lowercase_	,  lowercase_			)				->Direction:







 """simple docstring"""

 SCREAMING_SNAKE_CASE    ,   SCREAMING_SNAKE_CASE				    =		starting
 SCREAMING_SNAKE_CASE    ,   SCREAMING_SNAKE_CASE				    =		via
 SCREAMING_SNAKE_CASE    ,   SCREAMING_SNAKE_CASE				    =		target
 SCREAMING_SNAKE_CASE				    =		degrees(atana(ya - ya	,  xa - xa			)			)
 via_angle %= 3_6_0
 SCREAMING_SNAKE_CASE				    =		degrees(atana(ya - ya	,  xa - xa			)			)
 target_angle %= 3_6_0
 # 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 						A_					(						lowercase_			)				->list[tuple[int, int]]:







 """simple docstring"""

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

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

 SCREAMING_SNAKE_CASE				    =		sorted(lowercase_	,  key=lambda lowercase_			: angle_comparer(lowercase_	,  lowercase_	,  lowercase_			)			)
 # 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)			)

 SCREAMING_SNAKE_CASE				    =		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.
 SCREAMING_SNAKE_CASE				    =		Direction.left

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

   if next_direction == Direction.left:
    SCREAMING_SNAKE_CASE				    =		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(lowercase_			)












"""simple docstring"""





from __future__ import annotations

from PIL import Image

# Define the first generation of cells
# fmt: off
A__       :			str=						[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE       )       ->						list[int]:
    """simple docstring"""

    return [int(SCREAMING_SNAKE_CASE       ) for c in F'{ruleset:08}'[:8]]







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE			,						SCREAMING_SNAKE_CASE			,						SCREAMING_SNAKE_CASE       )       ->						list[int]:
    """simple docstring"""

    UpperCamelCase__								=     len(cells[0]       )  # 31
    UpperCamelCase__								=     []
    for i in range(SCREAMING_SNAKE_CASE       ):
        # Get the neighbors of each cell
        # Handle neighbours outside bounds by using 0 as their value
        UpperCamelCase__								=     0 if i == 0 else cells[time][i - 1]
        UpperCamelCase__								=     0 if i == population - 1 else cells[time][i + 1]
        # Define a new cell and add it to the new generation
        UpperCamelCase__								=     7 - int(F'{left_neighbor}{cells[time][i]}{right_neighbor}'			,						2       )
        next_generation.append(rule[situation]       )
    return next_generation







def 	lowerCAmelCase_(			SCREAMING_SNAKE_CASE       )       ->						Image.Image:
    """simple docstring"""

    UpperCamelCase__								=     Image.new('RGB'			,						(len(cells[0]       ), len(SCREAMING_SNAKE_CASE       ))       )
    UpperCamelCase__								=     img.load()
    # Generates image
    for w in range(img.width       ):
        for h in range(img.height       ):
            UpperCamelCase__								=     2_55 - int(2_55 * cells[h][w]       )
            UpperCamelCase__								=     (color, color, color)
    return img


if __name__ == "__main__":
  A__       :			Optional[int]=						bin(int(input("""Rule:\n""").strip()))[2:]
  A__       :			str=						format_ruleset(int(rule_num))
  for time in range(16):
    CELLS.append(new_generation(CELLS, rule, time))
  A__       :			Tuple=						generate_image(CELLS)
  # Uncomment to save the image
  # img.save(f"rule_{rule_num}.png")
  img.show()




