from __future__ import annotations

import time

import numpy as np

__snake_case      :      Union[str, Any]             =       [8, 5, 9, 7]
__snake_case      :      int             =       [
    [2, 0, 1, 1],
    [0, 1, 2, 1],
    [4, 0, 0, 3],
    [0, 2, 1, 0],
    [1, 0, 3, 0],
]
__snake_case      :      List[Any]             =       [
    [3, 2, 1, 4],
    [0, 2, 5, 2],
    [5, 1, 0, 5],
    [1, 5, 3, 0],
    [3, 0, 3, 3],
]


class       __SCREAMING_SNAKE_CASE   :






						def __init__(		self       ,  _UpperCamelCase       ,  _UpperCamelCase       ,  _UpperCamelCase       ,  ):






												"""simple docstring"""
												lowerCAmelCase__        =  claim_vector
												lowerCAmelCase__        =  allocated_resources_table
												lowerCAmelCase__        =  maximum_claim_table






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												return [
												    sum(p_item[i] for p_item in self.__allocated_resources_table				)
												    for i in range(len(self.__allocated_resources_table[0]				)				)
												]






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												return np.array(self.__claim_vector				) - np.array(
												    self.__processes_resource_summation()				)






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												return [
												    list(np.array(self.__maximum_claim_table[i]				) - np.array(_UpperCamelCase				)				)
												    for i, allocated_resource in enumerate(self.__allocated_resources_table				)
												]






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												return {self.__need().index(_UpperCamelCase				): i for i in self.__need()}






						def  UpperCamelCase__ (		self       ,  **_UpperCamelCase				):






												"""simple docstring"""
												lowerCAmelCase__        =  self.__need()
												lowerCAmelCase__        =  self.__allocated_resources_table
												lowerCAmelCase__        =  self.__available_resources()
												lowerCAmelCase__        =  self.__need_index_manager()
												for kw, val in kwargs.items():
																		if kw and val is True:
																								self.__pretty_data()
												print('_' * 50 + '\n'				)
												while need_list:
																		lowerCAmelCase__        =  False
																		for each_need in need_list:
																								lowerCAmelCase__        =  True
																								for index, need in enumerate(_UpperCamelCase				):
																														if need > available_resources[index]:
																																				lowerCAmelCase__        =  False
																																				break
																								if execution:
																														lowerCAmelCase__        =  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:
																																										lowerCAmelCase__        =  original_need_index
																														print(F"Process {process_number + 1} is executing."				)
																														# remove the process run from stack
																														need_list.remove(_UpperCamelCase				)
																														# update available/freed resources stack
																														lowerCAmelCase__        =  np.array(_UpperCamelCase				) + np.array(
																														    alloc_resources_table[process_number]				)
																														print(
																														    'Updated available resource stack for processes: '
																														    + ' '.join([str(_UpperCamelCase				) 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  UpperCamelCase__ (		self				):






												"""simple docstring"""
												print(' ' * 9 + 'Allocated Resource Table'				)
												for item in self.__allocated_resources_table:
																		print(
																		    F"P{self.__allocated_resources_table.index(_UpperCamelCase				) + 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(_UpperCamelCase				) + 1}"
																		    + ' '.join(F"{it:>8}" for it in item				)
																		    + '\n'				)
												print(
												    'Current Usage by Active Processes: '
												    + ' '.join(str(_UpperCamelCase				) for x in self.__claim_vector				)				)
												print(
												    'Initial Available Resources:       '
												    + ' '.join(str(_UpperCamelCase				) for x in self.__available_resources()				)				)
												time.sleep(1				)


if __name__ == "__main__":
					import doctest

					doctest.testmod()













from collections.abc import Iterator, MutableMapping
from dataclasses import dataclass
from typing import Generic, TypeVar

__snake_case      :      Optional[Any]             =       TypeVar("""KEY""")
__snake_case      :      str             =       TypeVar("""VAL""")


@dataclass(frozen=__lowercase						,   slots=__lowercase)
class       __SCREAMING_SNAKE_CASE   (				Generic[KEY, VAL]):
						_SCREAMING_SNAKE_CASE		:    KEY
						_SCREAMING_SNAKE_CASE		:    VAL




class       __SCREAMING_SNAKE_CASE   (				_Item):






						def __init__(		self				):






												"""simple docstring"""
												super().__init__(_UpperCamelCase       ,  _UpperCamelCase				)







						def __bool__(		self				):






												"""simple docstring"""
												return False




__snake_case      :      int             =       _DeletedItem()


class       __SCREAMING_SNAKE_CASE   (				MutableMapping[KEY, VAL]):






						def __init__(		self       ,  _UpperCamelCase = 8       ,  _UpperCamelCase = 0.75				):






												"""simple docstring"""
												lowerCAmelCase__        =  initial_block_size
												lowerCAmelCase__        =  [None] * initial_block_size
												assert 0.0 < capacity_factor < 1.0
												lowerCAmelCase__        =  capacity_factor
												lowerCAmelCase__        =  0






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												return hash(_UpperCamelCase				) % len(self._buckets				)






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												return (ind + 1) % len(self._buckets				)






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase       ,  _UpperCamelCase       ,  _UpperCamelCase				):






												"""simple docstring"""
												lowerCAmelCase__        =  self._buckets[ind]
												if not stored:
																		lowerCAmelCase__        =  _Item(_UpperCamelCase       ,  _UpperCamelCase				)
																		self._len += 1
																		return True
												elif stored.key == key:
																		lowerCAmelCase__        =  _Item(_UpperCamelCase       ,  _UpperCamelCase				)
																		return True
												else:
																		return False






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												lowerCAmelCase__        =  len(self._buckets				) * self._capacity_factor
												return len(self				) >= int(_UpperCamelCase				)






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												if len(self._buckets				) <= self._initial_block_size:
																		return False
												lowerCAmelCase__        =  len(self._buckets				) * self._capacity_factor / 2
												return len(self				) < limit






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												lowerCAmelCase__        =  self._buckets
												lowerCAmelCase__        =  [None] * new_size
												lowerCAmelCase__        =  0
												for item in old_buckets:
																		if item:
																								self._add_item(item.key       ,  item.val				)






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												self._resize(len(self._buckets				) * 2				)






						def  UpperCamelCase__ (		self				):






												"""simple docstring"""
												self._resize(len(self._buckets				) // 2				)






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												lowerCAmelCase__        =  self._get_bucket_index(_UpperCamelCase				)
												for _ in range(len(self._buckets				)				):
																		yield ind
																		lowerCAmelCase__        =  self._get_next_ind(_UpperCamelCase				)






						def  UpperCamelCase__ (		self       ,  _UpperCamelCase       ,  _UpperCamelCase				):






												"""simple docstring"""
												for ind in self._iterate_buckets(_UpperCamelCase				):
																		if self._try_set(_UpperCamelCase       ,  _UpperCamelCase       ,  _UpperCamelCase				):
																								break






						def __setitem__(		self       ,  _UpperCamelCase       ,  _UpperCamelCase				):






												"""simple docstring"""
												if self._is_full():
																		self._size_up()

												self._add_item(_UpperCamelCase       ,  _UpperCamelCase				)






						def __delitem__(		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												for ind in self._iterate_buckets(_UpperCamelCase				):
																		lowerCAmelCase__        =  self._buckets[ind]
																		if item is None:
																								raise KeyError(_UpperCamelCase				)
																		if item is _deleted:
																								continue
																		if item.key == key:
																								lowerCAmelCase__        =  _deleted
																								self._len -= 1
																								break
												if self._is_sparse():
																		self._size_down()






						def __getitem__(		self       ,  _UpperCamelCase				):






												"""simple docstring"""
												for ind in self._iterate_buckets(_UpperCamelCase				):
																		lowerCAmelCase__        =  self._buckets[ind]
																		if item is None:
																								break
																		if item is _deleted:
																								continue
																		if item.key == key:
																								return item.val
												raise KeyError(_UpperCamelCase				)






						def __len__(		self				):






												"""simple docstring"""
												return self._len






						def __iter__(		self				):






												"""simple docstring"""
												yield from (item.key for item in self._buckets if item)







						def __repr__(		self				):






												"""simple docstring"""
												lowerCAmelCase__        =  ' ,'.join(
												    F"{item.key}: {item.val}" for item in self._buckets if item				)
												return F"HashMap({val_string})"





