



from __future__ import annotations

import os


class    _lowercase :
				'''simple docstring'''







				lowercase__     =    (
				    """High card""",
				    """One pair""",
				    """Two pairs""",
				    """Three of a kind""",
				    """Straight""",
				    """Flush""",
				    """Full house""",
				    """Four of a kind""",
				    """Straight flush""",
				    """Royal flush""",
				)

				lowercase__     =    (
				    """""",  # placeholder as tuples are zero-indexed
				    """One""",
				    """Two""",
				    """Three""",
				    """Four""",
				    """Five""",
				    """Six""",
				    """Seven""",
				    """Eight""",
				    """Nine""",
				    """Ten""",
				    """Jack""",
				    """Queen""",
				    """King""",
				    """Ace""",
				)

				def __init__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if not isinstance(snake_case__  ,			snake_case__     ):
														UpperCamelCase_			= F"""Hand should be of type 'str': {hand!r}"""
														raise TypeError(snake_case__     )
									# split removes duplicate whitespaces so no need of strip
									if len(hand.split(" "     )     ) != 5:
														UpperCamelCase_			= F"""Hand should contain only 5 cards: {hand!r}"""
														raise ValueError(snake_case__     )
									UpperCamelCase_			= hand
									UpperCamelCase_			= 0
									UpperCamelCase_			= 0
									UpperCamelCase_	,     UpperCamelCase_			= self._internal_state()
									UpperCamelCase_			= self._get_hand_type()
									UpperCamelCase_			= self._card_values[0]

				@property
				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									return self._hand

				def    _lowerCamelCase       (			self  ,			snake_case__     ):

									'''simple docstring'''


									if self._hand_type > other._hand_type:
														return "Win"
									elif self._hand_type < other._hand_type:
														return "Loss"
									elif self._first_pair == other._first_pair:
														if self._second_pair == other._second_pair:
																			return self._compare_cards(snake_case__     )
														else:
																			return "Win" if self._second_pair > other._second_pair else "Loss"
									return "Win" if self._first_pair > other._first_pair else "Loss"

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									UpperCamelCase_			= PokerHand._HAND_NAME[self._hand_type - 14]
									UpperCamelCase_			= PokerHand._CARD_NAME[self._high_card]
									UpperCamelCase_			= PokerHand._CARD_NAME[self._first_pair]
									UpperCamelCase_			= PokerHand._CARD_NAME[self._second_pair]
									if self._hand_type in [22, 19, 18]:
														return name + F""", {high}-high"""
									elif self._hand_type in [21, 17, 15]:
														return name + F""", {paira}s"""
									elif self._hand_type in [20, 16]:
														UpperCamelCase_			= "over" if self._hand_type == 20 else "and"
														return name + F""", {paira}s {join} {paira}s"""
									elif self._hand_type == 23:
														return name
									else:
														return name + F""", {high}"""

				def    _lowerCamelCase       (			self  ,			snake_case__     ):

									'''simple docstring'''


									for index, card_value in enumerate(self._card_values     ):
														if card_value != other._card_values[index]:
																			return "Win" if card_value > other._card_values[index] else "Loss"
									return "Tie"

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									if self._is_flush():
														if self._is_five_high_straight() or self._is_straight():
																			return 23 if sum(self._card_values     ) == 60 else 22
														return 19
									elif self._is_five_high_straight() or self._is_straight():
														return 18
									return 14 + self._is_same_kind()

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									return len(self._card_suit     ) == 1

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									if sorted(self._card_values     ) == [2, 3, 4, 5, 14]:
														if self._card_values[0] == 14:
																			# Remember, our list is sorted in reverse order
																			UpperCamelCase_			= self._card_values.pop(0     )
																			self._card_values.append(snake_case__     )
														return True
									return False

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									for i in range(4     ):
														if self._card_values[i] - self._card_values[i + 1] != 1:
																			return False
									return True

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									UpperCamelCase_			= UpperCamelCase_			= UpperCamelCase_			= 0
									for i in range(4     ):
														# Compare two cards at a time, if they are same increase 'kind',
														# add the value of the card to val1, if it is repeating again we
														# will add 2 to 'kind' as there are now 3 cards with same value.
														# If we get card of different value than val1, we will do the same
														# thing with val2
														if self._card_values[i] == self._card_values[i + 1]:
																			if not vala:
																								UpperCamelCase_			= self._card_values[i]
																								kind += 1
																			elif vala == self._card_values[i]:
																								kind += 2
																			elif not vala:
																								UpperCamelCase_			= self._card_values[i]
																								kind += 1
																			elif vala == self._card_values[i]:
																								kind += 2
        # For consistency in hand type (look at note in _get_hand_type function)
									UpperCamelCase_			= kind + 2 if kind in [4, 5] else kind
									# first meaning first pair to compare in 'compare_with'
									UpperCamelCase_			= max(snake_case__  ,			snake_case__     )
									UpperCamelCase_			= min(snake_case__  ,			snake_case__     )
									# If it's full house (three count pair + two count pair), make sure
									# first pair is three count and if not then switch them both.
									if kind == 6 and self._card_values.count(snake_case__     ) != 3:
														UpperCamelCase_	,     UpperCamelCase_			= second, first
									UpperCamelCase_			= first
									UpperCamelCase_			= second
									return kind

				def    _lowerCamelCase       (			self     ):

									'''simple docstring'''


									UpperCamelCase_			= {"T": "10", "J": "11", "Q": "12", "K": "13", "A": "14"}
									UpperCamelCase_			= self._hand.translate(str.maketrans(snake_case__     )     ).split()
									UpperCamelCase_			= [int(card[:-1]     ) for card in new_hand]
									UpperCamelCase_			= {card[-1] for card in new_hand}
									return sorted(snake_case__  ,			reverse=snake_case__     ), card_suit

				def __repr__(			self     ):

									'''simple docstring'''


									return F"""{self.__class__}(\"{self._hand}\")"""

				def __str__(			self     ):

									'''simple docstring'''


									return self._hand

				def __eq__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if isinstance(snake_case__  ,			snake_case__     ):
														return self.compare_with(snake_case__     ) == "Tie"
									return NotImplemented

				def __lt__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if isinstance(snake_case__  ,			snake_case__     ):
														return self.compare_with(snake_case__     ) == "Loss"
									return NotImplemented

				def __le__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if isinstance(snake_case__  ,			snake_case__     ):
														return self < other or self == other
									return NotImplemented

				def __gt__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if isinstance(snake_case__  ,			snake_case__     ):
														return not self < other and self != other
									return NotImplemented

				def __ge__(			self  ,			snake_case__     ):

									'''simple docstring'''


									if isinstance(snake_case__  ,			snake_case__     ):
														return not self < other
									return NotImplemented

				def __hash__(			self     ):

									'''simple docstring'''


									return object.__hash__(self     )




def  _lowerCAmelCase     ():
					# Solution for problem number 54 from Project Euler
					# Input from poker_hands.txt file
					UpperCamelCase_			= 0
					UpperCamelCase_			= os.path.abspath(os.path.dirname(_lowerCAmelCase))
					UpperCamelCase_			= os.path.join(_lowerCAmelCase ,						"poker_hands.txt")
					with open(_lowerCAmelCase) as file_hand:
										for line in file_hand:
															UpperCamelCase_			= line[:14].strip()
															UpperCamelCase_			= line[15:].strip()
															UpperCamelCase_	,     UpperCamelCase_			= PokerHand(_lowerCAmelCase), PokerHand(_lowerCAmelCase)
															UpperCamelCase_			= player.compare_with(_lowerCAmelCase)
															if output == "Win":
																				answer += 1
					return answer


if __name__ == "__main__":
	solution()


import tempfile

import torch

from diffusers import (
    DEISMultistepScheduler,
    DPMSolverMultistepScheduler,
    DPMSolverSinglestepScheduler,
    UniPCMultistepScheduler,
)

from .test_schedulers import SchedulerCommonTest


class 	UpperCamelCase__       (  UpperCAmelCase__):

						'''simple docstring'''



						__a     :    List[Any]												=			(DPMSolverMultistepScheduler,)
						__a     :    Dict												=			(("""num_inference_steps""", 2_5),)


						def    A__       (  self  , **A	)  ->List[Any]:
									UpperCAmelCase__		:int 		=    {
									    'num_train_timesteps': 10_00,
									    'beta_start': 0.0001,
									    'beta_end': 0.02,
									    'beta_schedule': 'linear',
									    'solver_order': 2,
									    'prediction_type': 'epsilon',
									    'thresholding': False,
									    'sample_max_value': 1.0,
									    'algorithm_type': 'dpmsolver++',
									    'solver_type': 'midpoint',
									    'lower_order_final': False,
									    'lambda_min_clipped': -float('inf'	),
									    'variance_type': None,
									}

									config.update(**A	)
									return config


						def    A__       (  self  , A=0  , **A	)  ->Tuple:
									UpperCAmelCase__		:List[str] 		=    dict(self.forward_default_kwargs	)
									UpperCAmelCase__		:Any 		=    kwargs.pop('num_inference_steps'  , A	)
									UpperCAmelCase__		:int 		=    self.dummy_sample
									UpperCAmelCase__		:Optional[int] 		=    0.1 * sample
									UpperCAmelCase__		:Any 		=    [residual + 0.2, residual + 0.15, residual + 0.10]

									for scheduler_class in self.scheduler_classes:
												UpperCAmelCase__		:Optional[int] 		=    self.get_scheduler_config(**A	)
												UpperCAmelCase__		:List[Any] 		=    scheduler_class(**A	)
												scheduler.set_timesteps(A	)
												# copy over dummy past residuals
												UpperCAmelCase__		:Optional[Any] 		=    dummy_past_residuals[: scheduler.config.solver_order]

												with tempfile.TemporaryDirectory() as tmpdirname:
															scheduler.save_config(A	)
															UpperCAmelCase__		:List[Any] 		=    scheduler_class.from_pretrained(A	)
															new_scheduler.set_timesteps(A	)
															# copy over dummy past residuals
															UpperCAmelCase__		:Union[str, Any] 		=    dummy_past_residuals[: new_scheduler.config.solver_order]

												UpperCAmelCase__		,       UpperCAmelCase__		:int 		=    sample, sample
												for t in range(A  , time_step + scheduler.config.solver_order + 1	):
															UpperCAmelCase__		:Dict 		=    scheduler.step(A  , A  , A  , **A	).prev_sample
															UpperCAmelCase__		:Optional[Any] 		=    new_scheduler.step(A  , A  , A  , **A	).prev_sample

															assert torch.sum(torch.abs(output - new_output	)	) < 1e-5, "Scheduler outputs are not identical"


						def    A__       (  self	)  ->List[Any]:
									pass


						def    A__       (  self  , A=0  , **A	)  ->Tuple:
									UpperCAmelCase__		:List[str] 		=    dict(self.forward_default_kwargs	)
									UpperCAmelCase__		:Dict 		=    kwargs.pop('num_inference_steps'  , A	)
									UpperCAmelCase__		:str 		=    self.dummy_sample
									UpperCAmelCase__		:Union[str, Any] 		=    0.1 * sample
									UpperCAmelCase__		:Union[str, Any] 		=    [residual + 0.2, residual + 0.15, residual + 0.10]

									for scheduler_class in self.scheduler_classes:
												UpperCAmelCase__		:List[Any] 		=    self.get_scheduler_config()
												UpperCAmelCase__		:List[str] 		=    scheduler_class(**A	)
												scheduler.set_timesteps(A	)

												# copy over dummy past residuals (must be after setting timesteps)
												UpperCAmelCase__		:Tuple 		=    dummy_past_residuals[: scheduler.config.solver_order]

												with tempfile.TemporaryDirectory() as tmpdirname:
															scheduler.save_config(A	)
															UpperCAmelCase__		:int 		=    scheduler_class.from_pretrained(A	)
															# copy over dummy past residuals
															new_scheduler.set_timesteps(A	)

															# copy over dummy past residual (must be after setting timesteps)
															UpperCAmelCase__		:Optional[int] 		=    dummy_past_residuals[: new_scheduler.config.solver_order]

												UpperCAmelCase__		:Any 		=    scheduler.step(A  , A  , A  , **A	).prev_sample
												UpperCAmelCase__		:Dict 		=    new_scheduler.step(A  , A  , A  , **A	).prev_sample

												assert torch.sum(torch.abs(output - new_output	)	) < 1e-5, "Scheduler outputs are not identical"


						def    A__       (  self  , A=None  , **A	)  ->List[str]:
									if scheduler is None:
												UpperCAmelCase__		:Optional[Any] 		=    self.scheduler_classes[0]
												UpperCAmelCase__		:Optional[Any] 		=    self.get_scheduler_config(**A	)
												UpperCAmelCase__		:Union[str, Any] 		=    scheduler_class(**A	)

									UpperCAmelCase__		:List[Any] 		=    10
									UpperCAmelCase__		:int 		=    self.dummy_model()
									UpperCAmelCase__		:int 		=    self.dummy_sample_deter
									scheduler.set_timesteps(A	)

									for i, t in enumerate(scheduler.timesteps	):
												UpperCAmelCase__		:Union[str, Any] 		=    model(A  , A	)
												UpperCAmelCase__		:str 		=    scheduler.step(A  , A  , A	).prev_sample

									return sample


						def    A__       (  self	)  ->str:
									UpperCAmelCase__		:Tuple 		=    dict(self.forward_default_kwargs	)

									UpperCAmelCase__		:Optional[Any] 		=    kwargs.pop('num_inference_steps'  , A	)

									for scheduler_class in self.scheduler_classes:
												UpperCAmelCase__		:Union[str, Any] 		=    self.get_scheduler_config()
												UpperCAmelCase__		:Optional[Any] 		=    scheduler_class(**A	)

												UpperCAmelCase__		:Dict 		=    self.dummy_sample
												UpperCAmelCase__		:Dict 		=    0.1 * sample

												if num_inference_steps is not None and hasattr(A  , 'set_timesteps'	):
															scheduler.set_timesteps(A	)
												elif num_inference_steps is not None and not hasattr(A  , 'set_timesteps'	):
															UpperCAmelCase__		:List[Any] 		=    num_inference_steps

												# copy over dummy past residuals (must be done after set_timesteps)
												UpperCAmelCase__		:List[Any] 		=    [residual + 0.2, residual + 0.15, residual + 0.10]
												UpperCAmelCase__		:Any 		=    dummy_past_residuals[: scheduler.config.solver_order]

												UpperCAmelCase__		:str 		=    scheduler.timesteps[5]
												UpperCAmelCase__		:str 		=    scheduler.timesteps[6]

												UpperCAmelCase__		:List[str] 		=    scheduler.step(A  , A  , A  , **A	).prev_sample
												UpperCAmelCase__		:List[Any] 		=    scheduler.step(A  , A  , A  , **A	).prev_sample

												self.assertEqual(output_a.shape  , sample.shape	)
												self.assertEqual(output_a.shape  , output_a.shape	)


						def    A__       (  self	)  ->Optional[Any]:
									for timesteps in [25, 50, 1_00, 9_99, 10_00]:
												self.check_over_configs(num_train_timesteps=A	)


						def    A__       (  self	)  ->str:
									self.check_over_configs(thresholding=A	)
									for order in [1, 2, 3]:
												for solver_type in ["midpoint", "heun"]:
															for threshold in [0.5, 1.0, 2.0]:
																		for prediction_type in ["epsilon", "sample"]:
																					self.check_over_configs(
																					    thresholding=A  , prediction_type=A  , sample_max_value=A  , algorithm_type='dpmsolver++'  , solver_order=A  , solver_type=A  , )


						def    A__       (  self	)  ->Optional[int]:
									for prediction_type in ["epsilon", "v_prediction"]:
												self.check_over_configs(prediction_type=A	)


						def    A__       (  self	)  ->List[str]:
									for algorithm_type in ["dpmsolver", "dpmsolver++", "sde-dpmsolver", "sde-dpmsolver++"]:
												for solver_type in ["midpoint", "heun"]:
															for order in [1, 2, 3]:
																		for prediction_type in ["epsilon", "sample"]:
																					if algorithm_type in ["sde-dpmsolver", "sde-dpmsolver++"]:
																								if order == 3:
																											continue
																					else:
																								self.check_over_configs(
																								    solver_order=A  , solver_type=A  , prediction_type=A  , algorithm_type=A  , )
																					UpperCAmelCase__		:Optional[int] 		=    self.full_loop(
																					    solver_order=A  , solver_type=A  , prediction_type=A  , algorithm_type=A  , )
																					assert not torch.isnan(A	).any(), "Samples have nan numbers"


						def    A__       (  self	)  ->List[Any]:
									self.check_over_configs(lower_order_final=A	)
									self.check_over_configs(lower_order_final=A	)


						def    A__       (  self	)  ->Optional[Any]:
									self.check_over_configs(lambda_min_clipped=-float('inf'	)	)
									self.check_over_configs(lambda_min_clipped=-5.1	)


						def    A__       (  self	)  ->Union[str, Any]:
									self.check_over_configs(variance_type=A	)
									self.check_over_configs(variance_type='learned_range'	)


						def    A__       (  self	)  ->List[str]:
									for num_inference_steps in [1, 2, 3, 5, 10, 50, 1_00, 9_99, 10_00]:
												self.check_over_forward(num_inference_steps=A  , time_step=0	)


						def    A__       (  self	)  ->int:
									UpperCAmelCase__		:int 		=    self.full_loop()
									UpperCAmelCase__		:Optional[int] 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 0.3301	) < 1e-3


						def    A__       (  self	)  ->Any:
									UpperCAmelCase__		:Optional[int] 		=    self.full_loop(thresholding=A  , dynamic_thresholding_ratio=0.87  , sample_max_value=0.5	)
									UpperCAmelCase__		:Any 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 1.1364	) < 1e-3


						def    A__       (  self	)  ->Union[str, Any]:
									UpperCAmelCase__		:Optional[Any] 		=    self.full_loop(prediction_type='v_prediction'	)
									UpperCAmelCase__		:int 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 0.2251	) < 1e-3


						def    A__       (  self	)  ->str:
									UpperCAmelCase__		:Optional[int] 		=    self.full_loop(prediction_type='v_prediction'  , use_karras_sigmas=A	)
									UpperCAmelCase__		:Optional[int] 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 0.2096	) < 1e-3


						def    A__       (  self	)  ->List[Any]:
									# make sure that iterating over schedulers with same config names gives same results
									# for defaults
									UpperCAmelCase__		:Tuple 		=    DPMSolverMultistepScheduler(**self.get_scheduler_config()	)
									UpperCAmelCase__		:Optional[int] 		=    self.full_loop(scheduler=A	)
									UpperCAmelCase__		:List[Any] 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 0.3301	) < 1e-3

									UpperCAmelCase__		:Dict 		=    DPMSolverSinglestepScheduler.from_config(scheduler.config	)
									UpperCAmelCase__		:List[str] 		=    UniPCMultistepScheduler.from_config(scheduler.config	)
									UpperCAmelCase__		:Union[str, Any] 		=    DEISMultistepScheduler.from_config(scheduler.config	)
									UpperCAmelCase__		:List[str] 		=    DPMSolverMultistepScheduler.from_config(scheduler.config	)

									UpperCAmelCase__		:Dict 		=    self.full_loop(scheduler=A	)
									UpperCAmelCase__		:Dict 		=    torch.mean(torch.abs(A	)	)

									assert abs(result_mean.item() - 0.3301	) < 1e-3


						def    A__       (  self	)  ->Dict:
									UpperCAmelCase__		:Tuple 		=    self.scheduler_classes[0]
									UpperCAmelCase__		:List[str] 		=    self.get_scheduler_config(thresholding=A  , dynamic_thresholding_ratio=0	)
									UpperCAmelCase__		:str 		=    scheduler_class(**A	)

									UpperCAmelCase__		:int 		=    10
									UpperCAmelCase__		:Optional[int] 		=    self.dummy_model()
									UpperCAmelCase__		:List[str] 		=    self.dummy_sample_deter.half()
									scheduler.set_timesteps(A	)

									for i, t in enumerate(scheduler.timesteps	):
												UpperCAmelCase__		:str 		=    model(A  , A	)
												UpperCAmelCase__		:Union[str, Any] 		=    scheduler.step(A  , A  , A	).prev_sample

									assert sample.dtype == torch.floataa


						def    A__       (  self  , **A	)  ->Any:
									for scheduler_class in self.scheduler_classes:
												UpperCAmelCase__		:Optional[int] 		=    self.get_scheduler_config(**A	)
												UpperCAmelCase__		:int 		=    scheduler_class(**A	)

												scheduler.set_timesteps(scheduler.config.num_train_timesteps	)
												assert len(scheduler.timesteps.unique()	) == scheduler.num_inference_steps





