



'''simple docstring'''

from typing import Any

import numpy as np



class 		lowerCamelCase__   :




					'''simple docstring'''



					def __init__(	self					:						Tuple  ,	UpperCamelCase_					:						int  ,	UpperCamelCase_					:						Dict       )	->							Tuple:



						'''simple docstring'''





						if np.any(tableau[:, -1]  ,	where=tableau[:, -1] < 0       ):
							raise ValueError('RHS must be > 0'       )

						_lowercase       :							str  	=		tableau
						_lowercase	,     _lowercase       :							Dict  	=		tableau.shape

						# Number of decision variables x1, x2, x3...
						_lowercase       :							List[Any]  	=		n_vars

						# Number of artificial variables to be minimised
						_lowercase       :							Optional[Any]  	=		len(np.where(tableau[self.n_vars : -1] == -1       )[0]       )

						# 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
						_lowercase       :							Union[str, Any]  	=		(self.n_art_vars > 0) + 1

						# Number of slack variables added to make inequalities into equalities
						_lowercase       :							List[Any]  	=		self.n_rows - self.n_stages

						# Objectives for each stage
						_lowercase       :							Union[str, Any]  	=		['max']

						# In two stage simplex, first minimise then maximise
						if self.n_art_vars:
							self.objectives.append('min'       )

						_lowercase       :							Dict  	=		['']

						# Index of current pivot row and column
						_lowercase       :							Dict  	=		None
						_lowercase       :							Optional[Any]  	=		None

						# Does objective row only contain (non)-negative values?
						_lowercase       :							Union[str, Any]  	=		False




					@staticmethod
					def     __UpperCAmelCase  (	*UpperCamelCase_					:						int       )	->							Optional[Any]:



						'''simple docstring'''





						if len(a_       ) != 3:
							raise ValueError('Must provide n_vars, n_slack, and n_art_vars'       )

						if not all(x >= 0 and isinstance(a_  ,	a_       ) for x in args       ):
							raise ValueError('All arguments must be non-negative integers'       )

						# decision | slack | artificial
						_lowercase       :							str  	=		['x', 's', 'a']
						_lowercase       :							List[Any]  	=		[]
						for i in range(3       ):
							for j in range(args[i]       ):
								titles.append(string_starts[i] + str(j + 1       )       )
						titles.append('RHS'       )
						return titles




					def     __UpperCAmelCase  (	self					:						Optional[Any]  ,	UpperCamelCase_					:						int       )	->							Union[str, Any]:



						'''simple docstring'''





						_lowercase       :							Tuple  	=		self.objectives[-1]

						# Find entries of highest magnitude in objective rows
						_lowercase       :							Dict  	=		(objective == 'min') - (objective == 'max')
						_lowercase       :							List[str]  	=		np.argmax(sign * tableau[0, : self.n_vars]       )

						# Choice is only valid if below 0 for maximise, and above for minimise
						if sign * self.tableau[0, col_idx] <= 0:
							_lowercase       :							int  	=		True
							return 0, 0

						# Pivot row is chosen as having the lowest quotient when elements of
						# the pivot column divide the right-hand side

						# Slice excluding the objective rows
						_lowercase       :							str  	=		slice(self.n_stages  ,	self.n_rows       )

						# RHS
						_lowercase       :							Any  	=		tableau[s, -1]

						# Elements of pivot column within slice
						_lowercase       :							List[Any]  	=		tableau[s, col_idx]

						# Array filled with nans
						_lowercase       :							Tuple  	=		np.full(self.n_rows - self.n_stages  ,	np.nan       )

						# If element in pivot column is greater than zeron_stages, return
						# quotient or nan otherwise
						_lowercase       :							Dict  	=		np.divide(a_  ,	a_  ,	out=a_  ,	where=divisor > 0       )

						# Arg of minimum quotient excluding the nan values. n_stages is added
						# to compensate for earlier exclusion of objective columns
						_lowercase       :							Tuple  	=		np.nanargmin(a_       ) + self.n_stages
						return row_idx, col_idx




					def     __UpperCAmelCase  (	self					:						str  ,	UpperCamelCase_					:						Any  ,	UpperCamelCase_					:						Optional[int]  ,	UpperCamelCase_					:						Tuple       )	->							str:



						'''simple docstring'''





						_lowercase       :							List[str]  	=		tableau[row_idx].copy()

						_lowercase       :							Optional[int]  	=		piv_row[col_idx]

						# Entry becomes 1
						piv_row *= 1 / piv_val

						# Variable in pivot column becomes basic, ie the only non-zero entry
						for idx, coeff in enumerate(tableau[:, col_idx]       ):
							tableau[idx] += -coeff * piv_row
						_lowercase       :							Optional[int]  	=		piv_row
						return tableau




					def     __UpperCAmelCase  (	self					:						List[Any]  ,	UpperCamelCase_					:						List[str]       )	->							Dict:



						'''simple docstring'''





						self.objectives.pop()

						if not self.objectives:
							return tableau

						# Slice containing ids for artificial columns
						_lowercase       :							Optional[int]  	=		slice(-self.n_art_vars - 1  ,	-1       )

						# Delete the artificial variable columns
						_lowercase       :							Optional[int]  	=		np.delete(a_  ,	a_  ,	axis=1       )

						# Delete the objective row of the first stage
						_lowercase       :							Optional[Any]  	=		np.delete(a_  ,	0  ,	axis=0       )

						_lowercase       :							str  	=		1
						self.n_rows -= 1
						_lowercase       :							int  	=		0
						_lowercase       :							List[str]  	=		False
						return tableau




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



						'''simple docstring'''





						for _ in range(100       ):
							# Completion of each stage removes an objective. If both stages
							# are complete, then no objectives are left
							if not self.objectives:
								_lowercase       :							Optional[Any]  	=		self.generate_col_titles(
								    self.n_vars  ,	self.n_slack  ,	self.n_art_vars       )

								# Find the values of each variable at optimal solution
								return self.interpret_tableau(self.tableau  ,	self.col_titles       )

							_lowercase	,     _lowercase       :							Union[str, Any]  	=		self.find_pivot(self.tableau       )

							# If there are no more negative values in objective row
							if self.stop_iter:
								# Delete artificial variable columns and rows. Update attributes
								_lowercase       :							Dict  	=		self.change_stage(self.tableau       )
							else:
								_lowercase       :							int  	=		self.pivot(self.tableau  ,	a_  ,	a_       )
						return {}




					def     __UpperCAmelCase  (	self					:						int  ,	UpperCamelCase_					:						Union[str, Any]  ,	UpperCamelCase_					:						List[str]       )	->							Dict:



						'''simple docstring'''





						_lowercase       :							Optional[Any]  	=		{'P': abs(tableau[0, -1]       )}

						for i in range(self.n_vars       ):
							# Gives ids of nonzero entries in the ith column
							_lowercase       :							Any  	=		np.nonzero(tableau[:, i]       )
							_lowercase       :							Union[str, Any]  	=		len(nonzero[0]       )

							# First entry in the nonzero ids
							_lowercase       :							str  	=		nonzero[0][0]
							_lowercase       :							Optional[Any]  	=		tableau[nonzero_rowidx, i]

							# If there is only one nonzero value in column, which is one
							if n_nonzero == nonzero_val == 1:
								_lowercase       :							Tuple  	=		tableau[nonzero_rowidx, -1]
								_lowercase       :							Union[str, Any]  	=		rhs_val

        # Check for basic variables
						for title in col_titles:
							# Don't add RHS or slack variables to output dict
							if title[0] not in "R-s-a":
								output_dict.setdefault(a_  ,	0       )
						return output_dict


if __name__ == "__main__":
		import doctest

		doctest.testmod()





UpperCAmelCase							=       (1, 153, 370, 371, 1_634, 24_678_051, 115_132_219_018_763_992_565_095_597_973_971_522_401)
UpperCAmelCase							=       (-153, -1, 0, 1.2, 200, "A", [], {}, None)

def       A_   (						__a  :					int		):

				"""simple docstring"""
				if not isinstance(__a			,		__a		) or n < 1:
								return False

				# Initialization of sum and number of digits.
				a__					   =		0
				a__					   =		0
				a__					   =		n
				# Calculation of digits of the number
				while temp > 0:
								number_of_digits += 1
								temp //= 10
				# Dividing number into separate digits and find Armstrong number
				a__					   =		n
				while temp > 0:
								a__					   =		temp % 10
								total += rem**number_of_digits
								temp //= 10
				return n == total

def       A_   (						__a  :					int		):

				"""simple docstring"""
				if not isinstance(__a			,		__a		) or n < 1:
								return False

				# Init a "histogram" of the digits
				a__					   =		[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
				a__					   =		0
				a__					   =		0
				a__					   =		n
				while temp > 0:
								a__   ,      a__					   =		divmod(__a			,		10		)
								digit_histogram[rem] += 1
								digit_total += 1

				for cnt, i in zip(__a			,		range(len(__a		)		)		):
								total += cnt * i**digit_total

				return n == total

def       A_   (						__a  :					int		):

				"""simple docstring"""
				if not isinstance(__a			,		__a		) or n < 1:
								return False
				a__					   =		len(str(__a		)		)  # the power that all digits will be raised to
				# check if sum of each digit multiplied expo times is equal to number
				return n == sum(int(__a		) ** expo for i in str(__a		)		)

def       A_   (						):

				"""simple docstring"""
				a__					   =		int(input("""Enter an integer to see if it is an Armstrong number: """		).strip()		)
				print(F'''{num} is {"" if armstrong_number(__a		) else "not "}an Armstrong number.'''		)
				print(F'''{num} is {"" if narcissistic_number(__a		) else "not "}an Armstrong number.'''		)
				print(F'''{num} is {"" if pluperfect_number(__a		) else "not "}an Armstrong number.'''		)


if __name__ == "__main__":
	import doctest

	doctest.testmod()
	main()

