import numpy as np
import skfuzzy as fuzz

if __name__ == "__main__":
							# Create universe of discourse in Python using linspace ()
							_lowerCamelCase					:   int							=		np.linspace(start=0, stop=75, num=75, endpoint=True, retstep=False)

							# Create two fuzzy sets by defining any membership function
							# (trapmf(), gbellmf(), gaussmf(), etc).
							_lowerCamelCase					:   Any							=		[0, 25, 50]
							_lowerCamelCase					:   List[Any]							=		[25, 50, 75]
							_lowerCamelCase					:   Tuple							=		fuzz.membership.trimf(X, abca)
							_lowerCamelCase					:   Tuple							=		fuzz.membership.trimf(X, abca)

							# Compute the different operations using inbuilt functions.
							_lowerCamelCase					:   Optional[Any]							=		np.ones(75)
							_lowerCamelCase					:   Union[str, Any]							=		np.zeros((75,))
							# 1. Union = max(µA(x), µB(x))
							_lowerCamelCase					:   Any							=		fuzz.fuzzy_or(X, young, X, middle_aged)[1]
							# 2. Intersection = min(µA(x), µB(x))
							_lowerCamelCase					:   int							=		fuzz.fuzzy_and(X, young, X, middle_aged)[1]
							# 3. Complement (A) = (1- min(µA(x))
							_lowerCamelCase					:   List[Any]							=		fuzz.fuzzy_not(young)
							# 4. Difference (A/B) = min(µA(x),(1- µB(x)))
							_lowerCamelCase					:   Union[str, Any]							=		fuzz.fuzzy_and(X, young, X, fuzz.fuzzy_not(middle_aged)[1])[1]
							# 5. Algebraic Sum = [µA(x) + µB(x) – (µA(x) * µB(x))]
							_lowerCamelCase					:   Dict							=		young + middle_aged - (young * middle_aged)
							# 6. Algebraic Product = (µA(x) * µB(x))
							_lowerCamelCase					:   Tuple							=		young * middle_aged
							# 7. Bounded Sum = min[1,(µA(x), µB(x))]
							_lowerCamelCase					:   List[str]							=		fuzz.fuzzy_and(X, one, X, young + middle_aged)[1]
							# 8. Bounded difference = min[0,(µA(x), µB(x))]
							_lowerCamelCase					:   int							=		fuzz.fuzzy_or(X, zero, X, young - middle_aged)[1]

							# max-min composition
							# max-product composition

							# Plot each set A, set B and each operation result using plot() and subplot().
							from matplotlib import pyplot as plt

							plt.figure()

							plt.subplot(4, 3, 1)
							plt.plot(X, young)
							plt.title('''Young''')
							plt.grid(True)

							plt.subplot(4, 3, 2)
							plt.plot(X, middle_aged)
							plt.title('''Middle aged''')
							plt.grid(True)

							plt.subplot(4, 3, 3)
							plt.plot(X, union)
							plt.title('''union''')
							plt.grid(True)

							plt.subplot(4, 3, 4)
							plt.plot(X, intersection)
							plt.title('''intersection''')
							plt.grid(True)

							plt.subplot(4, 3, 5)
							plt.plot(X, complement_a)
							plt.title('''complement_a''')
							plt.grid(True)

							plt.subplot(4, 3, 6)
							plt.plot(X, difference)
							plt.title('''difference a/b''')
							plt.grid(True)

							plt.subplot(4, 3, 7)
							plt.plot(X, alg_sum)
							plt.title('''alg_sum''')
							plt.grid(True)

							plt.subplot(4, 3, 8)
							plt.plot(X, alg_product)
							plt.title('''alg_product''')
							plt.grid(True)

							plt.subplot(4, 3, 9)
							plt.plot(X, bdd_sum)
							plt.title('''bdd_sum''')
							plt.grid(True)

							plt.subplot(4, 3, 10)
							plt.plot(X, bdd_difference)
							plt.title('''bdd_difference''')
							plt.grid(True)

							plt.subplots_adjust(hspace=0.5)
							plt.show()





import functools





def 	__lowerCamelCase							(UpperCAmelCase__     :							list[int]      , UpperCAmelCase__     :							list[int]  ):

					# Validation
					if not isinstance(UpperCAmelCase__      , UpperCAmelCase__  ) or not all(isinstance(UpperCAmelCase__      , UpperCAmelCase__  ) for day in days  ):
										raise ValueError("The parameter days should be a list of integers"  )

					if len(UpperCAmelCase__  ) != 3 or not all(isinstance(UpperCAmelCase__      , UpperCAmelCase__  ) for cost in costs  ):
										raise ValueError("The parameter costs should be a list of three integers"  )

					if len(UpperCAmelCase__  ) == 0:
										return 0

					if min(UpperCAmelCase__  ) <= 0:
										raise ValueError("All days elements should be greater than 0"  )

					if max(UpperCAmelCase__  ) >= 3_6_6:
										raise ValueError("All days elements should be less than 366"  )

					SCREAMING_SNAKE_CASE    			=       set(UpperCAmelCase__  )

					@functools.cache
					def dynamic_programming(UpperCAmelCase__     :							int  ) -> int:
										if index > 3_6_5:
															return 0

										if index not in days_set:
															return dynamic_programming(index + 1  )

										return min(
										    costs[0] + dynamic_programming(index + 1  )      , costs[1] + dynamic_programming(index + 7  )      , costs[2] + dynamic_programming(index + 3_0  )      , )

					return dynamic_programming(1  )


if __name__ == "__main__":
							import doctest

							doctest.testmod()




