

'''simple docstring'''






from __future__ import annotations

import time

import numpy as np

lowerCAmelCase__											=	[8, 5, 9, 7]
lowerCAmelCase__											=	[
    [2, 0, 1, 1],
    [0, 1, 2, 1],
    [4, 0, 0, 3],
    [0, 2, 1, 0],
    [1, 0, 3, 0],
]
lowerCAmelCase__											=	[
    [3, 2, 1, 4],
    [0, 2, 5, 2],
    [5, 1, 0, 5],
    [1, 5, 3, 0],
    [3, 0, 3, 3],
]






class 			lowercase_	:




  """simple docstring"""




  def __init__(      self   :     Optional[Any]					,lowercase__   :     list[int]					,lowercase__   :     list[list[int]]					,lowercase__   :     list[list[int]]					,):
   __lowercase							  = claim_vector
   __lowercase							  = allocated_resources_table
   __lowercase							  = maximum_claim_table






  def 					SCREAMING_SNAKE_CASE      (      self   :     Tuple			):
   return [
       sum(p_item[i] for p_item in self.__allocated_resources_table			)
       for i in range(len(self.__allocated_resources_table[0]			)			)
   ]






  def 					SCREAMING_SNAKE_CASE      (      self   :     str			):
   return np.array(self.__claim_vector			) - np.array(
       self.__processes_resource_summation()			)






  def 					SCREAMING_SNAKE_CASE      (      self   :     Union[str, Any]			):
   return [
       list(np.array(self.__maximum_claim_table[i]			) - np.array(lowercase__			)			)
       for i, allocated_resource in enumerate(self.__allocated_resources_table			)
   ]






  def 					SCREAMING_SNAKE_CASE      (      self   :     Any			):
   return {self.__need().index(lowercase__			): i for i in self.__need()}






  def 					SCREAMING_SNAKE_CASE      (      self   :     List[str]					,**lowercase__   :     List[Any]			):
   __lowercase							  = self.__need()
   __lowercase							  = self.__allocated_resources_table
   __lowercase							  = self.__available_resources()
   __lowercase							  = self.__need_index_manager()
   for kw, val in kwargs.items():
    if kw and val is True:
     self.__pretty_data()
   print('''_''' * 5_0 + '''\n'''			)
   while need_list:
    __lowercase							  = False
    for each_need in need_list:
     __lowercase							  = True
     for index, need in enumerate(lowercase__			):
      if need > available_resources[index]:
       __lowercase							  = False
       break
     if execution:
      __lowercase							  = True
      # get the original index of the process from ind_ctrl db
      for original_need_index, need_clone in need_index_manager.items():
       if each_need == need_clone:
        __lowercase							  = original_need_index
      print(F"Process {process_number + 1} is executing."			)
      # remove the process run from stack
      need_list.remove(lowercase__			)
      # update available/freed resources stack
      __lowercase							  = np.array(lowercase__			) + np.array(
          alloc_resources_table[process_number]			)
      print(
          '''Updated available resource stack for processes: '''
          + ''' '''.join([str(lowercase__			) for x in available_resources]			)			)
      break
    if safe:
     print('''The process is in a safe state.\n'''			)
    else:
     print('''System in unsafe state. Aborting...\n'''			)
     break






  def 					SCREAMING_SNAKE_CASE      (      self   :     Optional[int]			):
   print(''' ''' * 9 + '''Allocated Resource Table'''			)
   for item in self.__allocated_resources_table:
    print(
        F"P{self.__allocated_resources_table.index(lowercase__			) + 1}"
        + ''' '''.join(F"{it:>8}" for it in item			)
        + '''\n'''			)
   print(''' ''' * 9 + '''System Resource Table'''			)
   for item in self.__maximum_claim_table:
    print(
        F"P{self.__maximum_claim_table.index(lowercase__			) + 1}"
        + ''' '''.join(F"{it:>8}" for it in item			)
        + '''\n'''			)
   print(
       '''Current Usage by Active Processes: '''
       + ''' '''.join(str(lowercase__			) for x in self.__claim_vector			)			)
   print(
       '''Initial Available Resources:       '''
       + ''' '''.join(str(lowercase__			) for x in self.__available_resources()			)			)
   time.sleep(1			)


if __name__ == "__main__":
 import doctest

 doctest.testmod()







class     __lowerCAmelCase :

			"""simple docstring"""







			def __init__(      self							)    ->      Any:



							'''simple docstring'''
							__lowerCamelCase		       =    0
							__lowerCamelCase		       =    0
							__lowerCamelCase		       =    {}


			def       lowercase_    (      self			,						lowerCamelCase__							)    ->      Tuple:



							'''simple docstring'''
							if vertex not in self.adjacency:
											__lowerCamelCase		       =    {}
											self.num_vertices += 1


			def       lowercase_    (      self			,						lowerCamelCase__			,						lowerCamelCase__			,						lowerCamelCase__							)    ->      str:



							'''simple docstring'''
							self.add_vertex(lowerCamelCase__							)
							self.add_vertex(lowerCamelCase__							)

							if head == tail:
											return

							__lowerCamelCase		       =    weight
							__lowerCamelCase		       =    weight


			def       lowercase_    (      self							)    ->      List[str]:



							'''simple docstring'''
							__lowerCamelCase		       =    self.get_edges()
							for edge in edges:
											__lowerCamelCase       ,						__lowerCamelCase       ,						__lowerCamelCase		       =    edge
											edges.remove((tail, head, weight)							)
							for i in range(len(lowerCamelCase__							)							):
											__lowerCamelCase		       =    list(edges[i]							)

							edges.sort(key=lambda lowerCamelCase__							: e[2]							)
							for i in range(len(lowerCamelCase__							) - 1							):
											if edges[i][2] >= edges[i + 1][2]:
															__lowerCamelCase		       =    edges[i][2] + 1
							for edge in edges:
											__lowerCamelCase       ,						__lowerCamelCase       ,						__lowerCamelCase		       =    edge
											__lowerCamelCase		       =    weight
											__lowerCamelCase		       =    weight


			def __str__(      self							)    ->      Union[str, Any]:



							'''simple docstring'''
							__lowerCamelCase		       =    ''
							for tail in self.adjacency:
											for head in self.adjacency[tail]:
															__lowerCamelCase		       =    self.adjacency[head][tail]
															string += f"""{head} -> {tail} == {weight}\n"""
							return string.rstrip('\n'							)


			def       lowercase_    (      self							)    ->      Optional[Any]:



							'''simple docstring'''
							__lowerCamelCase		       =    []
							for tail in self.adjacency:
											for head in self.adjacency[tail]:
															output.append((tail, head, self.adjacency[head][tail])							)
							return output


			def       lowercase_    (      self							)    ->      List[Any]:



							'''simple docstring'''
							return self.adjacency.keys()


			@staticmethod
			def       lowercase_    (      lowerCamelCase__=None			,						lowerCamelCase__=None							)    ->      str:



							'''simple docstring'''
							__lowerCamelCase		       =    Graph()
							if vertices is None:
											__lowerCamelCase		       =    []
							if edges is None:
											__lowerCamelCase		       =    []
							for vertex in vertices:
											g.add_vertex(lowerCamelCase__							)
							for edge in edges:
											g.add_edge(*lowerCamelCase__							)
							return g







			class     __lowerCAmelCase :

						"""simple docstring"""







						def __init__(      self							)    ->      Tuple:



										'''simple docstring'''
										__lowerCamelCase		       =    {}
										__lowerCamelCase		       =    {}


						def __len__(      self							)    ->      Tuple:



										'''simple docstring'''
										return len(self.parent							)


						def       lowercase_    (      self			,						lowerCamelCase__							)    ->      List[Any]:



										'''simple docstring'''
										if item in self.parent:
														return self.find(lowerCamelCase__							)

										__lowerCamelCase		       =    item
										__lowerCamelCase		       =    0
										return item


						def       lowercase_    (      self			,						lowerCamelCase__							)    ->      List[str]:



										'''simple docstring'''
										if item not in self.parent:
														return self.make_set(lowerCamelCase__							)
										if item != self.parent[item]:
														__lowerCamelCase		       =    self.find(self.parent[item]							)
										return self.parent[item]






						def       lowercase_    (      self			,						lowerCamelCase__			,						lowerCamelCase__							)    ->      int:



										'''simple docstring'''
										__lowerCamelCase		       =    self.find(lowerCamelCase__							)
										__lowerCamelCase		       =    self.find(lowerCamelCase__							)

										if roota == roota:
														return roota

										if self.rank[roota] > self.rank[roota]:
														__lowerCamelCase		       =    roota
														return roota

										if self.rank[roota] < self.rank[roota]:
														__lowerCamelCase		       =    roota
														return roota

										if self.rank[roota] == self.rank[roota]:
														self.rank[roota] += 1
														__lowerCamelCase		       =    roota
														return roota
										return None




			@staticmethod
			def       lowercase_    (      lowerCamelCase__							)    ->      str:



							'''simple docstring'''
							__lowerCamelCase		       =    graph.num_vertices

							__lowerCamelCase		       =    Graph.UnionFind()
							__lowerCamelCase		       =    []
							while num_components > 1:
											__lowerCamelCase		       =    {}
											for vertex in graph.get_vertices():
															__lowerCamelCase		       =    -1

											__lowerCamelCase		       =    graph.get_edges()
											for edge in edges:
															__lowerCamelCase       ,						__lowerCamelCase       ,						__lowerCamelCase		       =    edge
															edges.remove((tail, head, weight)							)
											for edge in edges:
															__lowerCamelCase       ,						__lowerCamelCase       ,						__lowerCamelCase		       =    edge
															__lowerCamelCase		       =    union_find.find(lowerCamelCase__							)
															__lowerCamelCase		       =    union_find.find(lowerCamelCase__							)
															if seta != seta:
																			if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
																							__lowerCamelCase		       =    [head, tail, weight]

																			if cheap_edge[seta] == -1 or cheap_edge[seta][2] > weight:
																							__lowerCamelCase		       =    [head, tail, weight]
											for vertex in cheap_edge:
															if cheap_edge[vertex] != -1:
																			__lowerCamelCase       ,						__lowerCamelCase       ,						__lowerCamelCase		       =    cheap_edge[vertex]
																			if union_find.find(lowerCamelCase__							) != union_find.find(lowerCamelCase__							):
																							union_find.union(lowerCamelCase__			,						lowerCamelCase__							)
																							mst_edges.append(cheap_edge[vertex]							)
																							__lowerCamelCase		       =    num_components - 1
							__lowerCamelCase		       =    Graph.build(edges=lowerCamelCase__							)
							return mst


