




"""simple docstring"""

from __future__ import annotations

import random

from matplotlib import animation
from matplotlib import pyplot as plt

# Frame rate of the animation
_lowerCamelCase	:      Tuple   =							20

# Time between time steps in seconds
_lowerCamelCase	:      List[str]   =							INTERVAL / 1000

class 							lowercase   :







				def __init__(				self :       Optional[int]   ,  _lowerCamelCase :       Optional[int]   ,  _lowerCamelCase :       Any   ,  _lowerCamelCase :       Union[str, Any]   ,  _lowerCamelCase :       List[Any]   ,  _lowerCamelCase :       int = 1.0   ,  _lowerCamelCase :       Optional[Any] = 1.0   ,  _lowerCamelCase :       str = "blue"   ,  ):



					"""simple docstring"""

					A_	:					int						 =		position_x
					A_	:					Optional[Any]						 =		position_y
					A_	:					Optional[Any]						 =		velocity_x
					A_	:					List[str]						 =		velocity_y
					A_	:					Optional[Any]						 =		mass
					A_	:					int						 =		size
					A_	:					int						 =		color







				@property
				def        a_	(				self :       Union[str, Any]							):



					"""simple docstring"""

					return self.position_x, self.position_y







				@property
				def        a_	(				self :       int							):



					"""simple docstring"""

					return self.velocity_x, self.velocity_y







				def        a_	(				self :       Dict   ,  _lowerCamelCase :       int   ,  _lowerCamelCase :       List[str]   ,  _lowerCamelCase :       Optional[Any]							):



					"""simple docstring"""

					self.velocity_x += force_x * delta_time
					self.velocity_y += force_y * delta_time







				def        a_	(				self :       int   ,  _lowerCamelCase :       Any							):



					"""simple docstring"""

					self.position_x += self.velocity_x * delta_time
					self.position_y += self.velocity_y * delta_time

class 							lowercase   :







				def __init__(				self :       str   ,  _lowerCamelCase :       Optional[Any]   ,  _lowerCamelCase :       List[Any] = 1.0   ,  _lowerCamelCase :       int = 1.0   ,  _lowerCamelCase :       Optional[int] = 0.0   ,  ):



					"""simple docstring"""

					A_	:					List[Any]						 =		bodies
					A_	:					Optional[int]						 =		gravitation_constant
					A_	:					List[Any]						 =		time_factor
					A_	:					Dict						 =		softening_factor







				def __len__(				self :       List[str]							):



					"""simple docstring"""

					return len(self.bodies							)







				def        a_	(				self :       Optional[int]   ,  _lowerCamelCase :       Optional[int]							):



					"""simple docstring"""

					for bodya in self.bodies:
						A_	:					str						 =		0.0
						A_	:					Dict						 =		0.0
						for bodya in self.bodies:
							if bodya != bodya:
								A_	:					Dict						 =		bodya.position_x - bodya.position_x
								A_	:					int						 =		bodya.position_y - bodya.position_y

								# Calculation of the distance using Pythagoras's theorem
								# Extra factor due to the softening technique
								A_	:					str						 =		(dif_x**2 + dif_y**2 + self.softening_factor) ** (
								    1 / 2
								)

								# Newton's law of universal gravitation.
								force_x += (
								    self.gravitation_constant * bodya.mass * dif_x / distance**3
								)
								force_y += (
								    self.gravitation_constant * bodya.mass * dif_y / distance**3
								)

            # Update the body's velocity once all the force components have been added
						bodya.update_velocity(_UpperCAmelCase   ,  _UpperCAmelCase   ,  delta_time * self.time_factor							)

					# Update the positions only after all the velocities have been updated
					for body in self.bodies:
						body.update_position(delta_time * self.time_factor							)

def 		lowercase_   (		_UpperCAmelCase	,   _UpperCAmelCase	,   _UpperCAmelCase						):




	"""simple docstring"""






	body_system.update_system(snake_case__						)

	# Update the positions of the patches
	for patch, body in zip(snake_case__	,   body_system.bodies						):
		A_	:					Tuple						 =		(body.position_x, body.position_y)

def 		lowercase_   (		_UpperCAmelCase	,   _UpperCAmelCase	,   _UpperCAmelCase = -1	,   _UpperCAmelCase = 1	,   _UpperCAmelCase = -1	,   _UpperCAmelCase = 1	,   ):




	"""simple docstring"""






	A_	:					List[Any]						 =		plt.figure()
	fig.canvas.set_window_title(snake_case__						)
	A_	:					int						 =		plt.axes(
	    xlim=(x_start, x_end)	,   ylim=(y_start, y_end)						)  # Set section to be plotted
	plt.gca().set_aspect('''equal'''						)  # Fix aspect ratio

	# Each body is drawn as a patch by the plt-function
	A_	:					Optional[Any]						 =		[
	    plt.Circle((body.position_x, body.position_y)	,   body.size	,   fc=body.color						)
	    for body in body_system.bodies
	]

	for patch in patches:
		ax.add_patch(snake_case__						)

	# Function called at each step of the animation
	def update(_UpperCAmelCase						) -> list[plt.Circle]:
		update_step(snake_case__	,   snake_case__	,   snake_case__						)
		return patches

	A_	:					Any						 =		animation.FuncAnimation(  # noqa: F841
	    snake_case__	,   snake_case__	,   interval=snake_case__	,   blit=snake_case__						)

	plt.show()

def 		lowercase_   (		):




	"""simple docstring"""






	A_	:					int						 =		0.970_0436
	A_	:					Dict						 =		-0.2430_8753
	A_	:					Union[str, Any]						 =		0.4_6620_3685
	A_	:					Union[str, Any]						 =		0.4323_6573

	A_	:					List[Any]						 =		[
	    Body(snake_case__	,   snake_case__	,   snake_case__	,   snake_case__	,   size=0.2	,   color='''red'''						),
	    Body(-position_x	,   -position_y	,   snake_case__	,   snake_case__	,   size=0.2	,   color='''green'''						),
	    Body(0	,   0	,   -2 * velocity_x	,   -2 * velocity_y	,   size=0.2	,   color='''blue'''						),
	]
	return BodySystem(snake_case__	,   time_factor=3						)

def 		lowercase_   (		):




	"""simple docstring"""






	A_	:					List[Any]						 =		7.3476E22
	A_	:					Optional[Any]						 =		5.972E24
	A_	:					Any						 =		1022
	A_	:					Tuple						 =		3_8439_9000
	A_	:					List[str]						 =		6.674E-11

	# Calculation of the respective velocities so that total impulse is zero,
	# i.e. the two bodies together don't move
	A_	:					Any						 =		earth_mass * velocity_dif / (earth_mass + moon_mass)
	A_	:					int						 =		moon_velocity - velocity_dif

	A_	:					str						 =		Body(-earth_moon_distance	,   0	,   0	,   snake_case__	,   snake_case__	,   1000_0000	,   '''grey'''						)
	A_	:					Optional[int]						 =		Body(0	,   0	,   0	,   snake_case__	,   snake_case__	,   5000_0000	,   '''blue'''						)
	return BodySystem([earth, moon]	,   snake_case__	,   time_factor=100_0000						)

def 		lowercase_   (		):




	"""simple docstring"""






	A_	:					Any						 =		[]
	for _ in range(10						):
		A_	:					int						 =		random.uniform(-0.5	,   0.5						)
		A_	:					int						 =		random.uniform(-0.5	,   0.5						)

		# Bodies are created pairwise with opposite velocities so that the
		# total impulse remains zero
		bodies.append(
		    Body(
		        random.uniform(-0.5	,   0.5						)	,   random.uniform(-0.5	,   0.5						)	,   snake_case__	,   snake_case__	,   size=0.05	,   )						)
		bodies.append(
		    Body(
		        random.uniform(-0.5	,   0.5						)	,   random.uniform(-0.5	,   0.5						)	,   -velocity_x	,   -velocity_y	,   size=0.05	,   )						)
	return BodySystem(snake_case__	,   0.01	,   10	,   0.1						)


if __name__ == "__main__":
		plot('Figure-8 solution to the 3-body-problem', example_a(), -2, 2, -2, 2)
		plot(
		    'Moon\'s orbit around the earth',
		    example_a(),
		    -430000000,
		    430000000,
		    -430000000,
		    430000000,
		)
		plot('Random system with many bodies', example_a(), -1.5, 1.5, -1.5, 1.5)











'''simple docstring'''






def      __lowerCAmelCase   (       snake_case__		):

			for insert_index, insert_value in enumerate(collection[1:]		):
						__UpperCamelCase :     Union[str, Any]										=  insert_index
						while insert_index >= 0 and insert_value < collection[insert_index]:
									__UpperCamelCase :     int										=  collection[insert_index]
									insert_index -= 1
						if insert_index != temp_index:
									__UpperCamelCase :     Tuple										=  insert_value
			return collection


if __name__ == "__main__":
				from doctest import testmod

				testmod()

				_lowerCAmelCase       =   input('''Enter numbers separated by a comma:\n''').strip()
				_lowerCAmelCase       =   [int(item) for item in user_input.split(''',''')]
				print(f'{insertion_sort(unsorted) = }')



