




"""simple docstring"""
import string

import numpy





def 						UpperCAmelCase				(			A__:    int							,				A__:    int     )  ->     int:
			return b if a == 0 else greatest_common_divisor(b % a							,				A__     )

class __lowercase:




					'''simple docstring'''


					__a						:						Tuple     		= string.ascii_uppercase + string.digits
					# This cipher takes alphanumerics into account
					# i.e. a total of 36 characters

					# take x and return x % len(key_string)
					__a						:						Any     		= numpy.vectorize(lambda lowercase__				: x % 36				)

					__a						:						Optional[Any]     		= numpy.vectorize(lowercase__				)
					def __init__(    self						,	__a     ):
								__lowerCamelCase					:	Tuple	       =				self.modulus(__a     )  # mod36 calc's on the encrypt key
								self.check_determinant()  # validate the determinant of the encryption key
								__lowerCamelCase					:	Optional[Any]	       =				encrypt_key.shape[0]
					def     snake_case_				(    self						,	__a     ):
								return self.key_string.index(__a     )
					def     snake_case_				(    self						,	__a     ):
								return self.key_string[round(__a     )]
					def     snake_case_				(    self     ):
								__lowerCamelCase					:	Optional[int]	       =				round(numpy.linalg.det(self.encrypt_key     )     )

								if det < 0:
											__lowerCamelCase					:	Union[str, Any]	       =				det % len(self.key_string     )

								__lowerCamelCase					:	Optional[Any]	       =				len(self.key_string     )
								if greatest_common_divisor(__a						,	len(self.key_string     )     ) != 1:
											__lowerCamelCase					:	Optional[Any]	       =				(
											    f'''determinant modular {req_l} of encryption key({det}) '''
											    f'''is not co prime w.r.t {req_l}.\nTry another key.'''
											)
											raise ValueError(__a     )
					def     snake_case_				(    self						,	__a     ):
								__lowerCamelCase					:	Union[str, Any]	       =				[char for char in text.upper() if char in self.key_string]

								__lowerCamelCase					:	Tuple	       =				chars[-1]
								while len(__a     ) % self.break_key != 0:
											chars.append(__a     )

								return "".join(__a     )
					def     snake_case_				(    self						,	__a     ):
								__lowerCamelCase					:	Union[str, Any]	       =				self.process_text(text.upper()     )
								__lowerCamelCase					:	Optional[Any]	       =				''

								for i in range(0						,	len(__a     ) - self.break_key + 1						,	self.break_key     ):
											__lowerCamelCase					:	int	       =				text[i : i + self.break_key]
											__lowerCamelCase					:	Union[str, Any]	       =				[self.replace_letters(__a     ) for char in batch]
											__lowerCamelCase					:	Union[str, Any]	       =				numpy.array([vec]     ).T
											__lowerCamelCase					:	Dict	       =				self.modulus(self.encrypt_key.dot(__a     )     ).T.tolist()[
											    0
											]
											__lowerCamelCase					:	Any	       =				''.join(
											    self.replace_digits(__a     ) for num in batch_encrypted     )
											encrypted += encrypted_batch

								return encrypted
					def     snake_case_				(    self     ):
								__lowerCamelCase					:	Union[str, Any]	       =				round(numpy.linalg.det(self.encrypt_key     )     )

								if det < 0:
											__lowerCamelCase					:	Optional[int]	       =				det % len(self.key_string     )
								__lowerCamelCase					:	List[Any]	       =				None
								for i in range(len(self.key_string     )     ):
											if (det * i) % len(self.key_string     ) == 1:
														__lowerCamelCase					:	Tuple	       =				i
														break

								__lowerCamelCase					:	List[str]	       =				(
								    det_inv
								    * numpy.linalg.det(self.encrypt_key     )
								    * numpy.linalg.inv(self.encrypt_key     )
								)

								return self.to_int(self.modulus(__a     )     )





					def     snake_case_				(    self						,	__a     ):
								__lowerCamelCase					:	List[str]	       =				self.make_decrypt_key()
								__lowerCamelCase					:	List[str]	       =				self.process_text(text.upper()     )
								__lowerCamelCase					:	int	       =				''

								for i in range(0						,	len(__a     ) - self.break_key + 1						,	self.break_key     ):
											__lowerCamelCase					:	Any	       =				text[i : i + self.break_key]
											__lowerCamelCase					:	List[str]	       =				[self.replace_letters(__a     ) for char in batch]
											__lowerCamelCase					:	Any	       =				numpy.array([vec]     ).T
											__lowerCamelCase					:	int	       =				self.modulus(decrypt_key.dot(__a     )     ).T.tolist()[0]
											__lowerCamelCase					:	List[Any]	       =				''.join(
											    self.replace_digits(__a     ) for num in batch_decrypted     )
											decrypted += decrypted_batch

								return decrypted





def 						UpperCAmelCase				(			)  ->     None:
			__lowerCamelCase					:	Optional[int]	       =				int(input('Enter the order of the encryption key: '     )     )
			__lowerCamelCase					:	int	       =				[]

			print('Enter each row of the encryption key with space separated integers'     )
			for _ in range(A__     ):
						__lowerCamelCase					:	Any	       =				[int(A__     ) for x in input().split()]
						hill_matrix.append(A__     )

			__lowerCamelCase					:	Any	       =				HillCipher(numpy.array(A__     )     )

			print('Would you like to encrypt or decrypt some text? (1 or 2)'     )
			__lowerCamelCase					:	Dict	       =				input('\n1. Encrypt\n2. Decrypt\n'     )
			if option == "1":
						__lowerCamelCase					:	List[Any]	       =				input('What text would you like to encrypt?: '     )
						print('Your encrypted text is:'     )
						print(hc.encrypt(A__     )     )
			elif option == "2":
						__lowerCamelCase					:	int	       =				input('What text would you like to decrypt?: '     )
						print('Your decrypted text is:'     )
						print(hc.decrypt(A__     )     )


if __name__ == "__main__":
					import doctest

					doctest.testmod()

					main()









"""simple docstring"""
from __future__ import annotations

import pandas as pd





def 						UpperCAmelCase				(			A__:    list[int]							,				A__:    list[int]							,				A__:    int     )  ->     list[int]:
			__lowerCamelCase					:	List[Any]	       =				[0] * no_of_processes
			__lowerCamelCase					:	Any	       =				[0] * no_of_processes
			# Copy the burst time into remaining_time[]
			for i in range(A__     ):
						__lowerCamelCase					:	Dict	       =				burst_time[i]

			__lowerCamelCase					:	Any	       =				0
			__lowerCamelCase					:	Tuple	       =				0
			__lowerCamelCase					:	Union[str, Any]	       =				999999999
			__lowerCamelCase					:	str	       =				0
			__lowerCamelCase					:	Optional[int]	       =				False

			# Process until all processes are completed
			while complete != no_of_processes:
						for j in range(A__     ):
									if arrival_time[j] <= increment_time and remaining_time[j] > 0:
												if remaining_time[j] < minm:
															__lowerCamelCase					:	List[Any]	       =				remaining_time[j]
															__lowerCamelCase					:	List[str]	       =				j
															__lowerCamelCase					:	Optional[int]	       =				True

						if not check:
									increment_time += 1
									continue
						remaining_time[short] -= 1

						__lowerCamelCase					:	Optional[Any]	       =				remaining_time[short]
						if minm == 0:
									__lowerCamelCase					:	Optional[int]	       =				999999999

						if remaining_time[short] == 0:
									complete += 1
									__lowerCamelCase					:	List[str]	       =				False

									# Find finish time of current process
									__lowerCamelCase					:	Dict	       =				increment_time + 1

									# Calculate waiting time
									__lowerCamelCase					:	Any	       =				finish_time - arrival_time[short]
									__lowerCamelCase					:	Dict	       =				finar - burst_time[short]

									if waiting_time[short] < 0:
												__lowerCamelCase					:	Optional[Any]	       =				0

        # Increment time
						increment_time += 1
			return waiting_time





def 						UpperCAmelCase				(			A__:    list[int]							,				A__:    int							,				A__:    list[int]     )  ->     list[int]:
			__lowerCamelCase					:	List[Any]	       =				[0] * no_of_processes
			for i in range(A__     ):
						__lowerCamelCase					:	Tuple	       =				burst_time[i] + waiting_time[i]
			return turn_around_time





def 						UpperCAmelCase				(			A__:    list[int]							,				A__:    list[int]							,				A__:    int     )  ->     None:
			__lowerCamelCase					:	int	       =				0
			__lowerCamelCase					:	Dict	       =				0
			for i in range(A__     ):
						__lowerCamelCase					:	str	       =				total_waiting_time + waiting_time[i]
						__lowerCamelCase					:	Union[str, Any]	       =				total_turn_around_time + turn_around_time[i]
			print(f'''Average waiting time = {total_waiting_time / no_of_processes:.5f}'''     )
			print('Average turn around time ='							,				total_turn_around_time / no_of_processes     )


if __name__ == "__main__":
					print('''Enter how many process you want to analyze''')
					a_				:    int										=     int(input())
					a_				:    List[str]										=     [0] * no_of_processes
					a_				:    int										=     [0] * no_of_processes
					a_				:    int										=     list(range(1, no_of_processes + 1))

					for i in range(no_of_processes):
										print('''Enter the arrival time and burst time for process:--''' + str(i + 1))
										a_						,							a_				:    Union[str, Any]										=     map(int, input().split())

					a_				:    Any										=     calculate_waitingtime(arrival_time, burst_time, no_of_processes)

					a_				:    List[str]										=     burst_time
					a_				:    List[Any]										=     no_of_processes
					a_				:    Tuple										=     waiting_time
					a_				:    Optional[Any]										=     calculate_turnaroundtime(bt, n, wt)

					calculate_average_times(waiting_time, turn_around_time, no_of_processes)

					a_				:    List[Any]										=     pd.DataFrame(
					    list(zip(processes, burst_time, arrival_time, waiting_time, turn_around_time)),
					    columns=[
					        '''Process''',
					        '''BurstTime''',
					        '''ArrivalTime''',
					        '''WaitingTime''',
					        '''TurnAroundTime''',
					    ],
					)

					# Printing the dataFrame
					pd.set_option('''display.max_rows''', fcfs.shape[0] + 1)
					print(fcfs)



