import gc
import unittest

from transformers import MODEL_FOR_MASKED_LM_MAPPING, TF_MODEL_FOR_MASKED_LM_MAPPING, FillMaskPipeline, pipeline
from transformers.pipelines import PipelineException
from transformers.testing_utils import (
    is_pipeline_test,
    is_torch_available,
    nested_simplify,
    require_tf,
    require_torch,
    require_torch_gpu,
    slow,
)

from .test_pipelines_common import ANY



@is_pipeline_test
class        lowerCamelCase__				(   unittest.TestCase				):
			UpperCamelCase__    							=MODEL_FOR_MASKED_LM_MAPPING
			UpperCamelCase__    							=TF_MODEL_FOR_MASKED_LM_MAPPING





			def   SCREAMING_SNAKE_CASE__     (       self	:	Optional[Any]						):
										super().tearDown()
										# clean-up as much as possible GPU memory occupied by PyTorch
										gc.collect()
										if is_torch_available():
																	import torch

																	torch.cuda.empty_cache()





			@require_tf
			def   SCREAMING_SNAKE_CASE__     (       self	:	Tuple						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='sshleifer/tiny-distilroberta-base'  ,  top_k=2  ,  framework='tf'						)
										_lowerCAmelCase							=							unmasker('My name is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {'sequence': 'My name is grouped', 'score': 2.1e-05, 'token': 3_80_15, 'token_str': ' grouped'},
										        {'sequence': 'My name is accuser', 'score': 2.1e-05, 'token': 2_55_06, 'token_str': ' accuser'},
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('The largest city in France is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {
										            'sequence': 'The largest city in France is grouped',
										            'score': 2.1e-05,
										            'token': 3_80_15,
										            'token_str': ' grouped',
										        },
										        {
										            'sequence': 'The largest city in France is accuser',
										            'score': 2.1e-05,
										            'token': 2_55_06,
										            'token_str': ' accuser',
										        },
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('My name is <mask>'  ,  targets=[' Patrick', ' Clara', ' Teven']  ,  top_k=3						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {'sequence': 'My name is Clara', 'score': 2e-05, 'token': 1_36_06, 'token_str': ' Clara'},
										        {'sequence': 'My name is Patrick', 'score': 2e-05, 'token': 34_99, 'token_str': ' Patrick'},
										        {'sequence': 'My name is Te', 'score': 1.9e-05, 'token': 29_41, 'token_str': ' Te'},
										    ]  ,  )





			@require_torch
			def   SCREAMING_SNAKE_CASE__     (       self	:	int						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='sshleifer/tiny-distilroberta-base'  ,  top_k=2  ,  framework='pt'						)

										_lowerCAmelCase							=							unmasker('My name is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {'sequence': 'My name is Maul', 'score': 2.2e-05, 'token': 3_56_76, 'token_str': ' Maul'},
										        {'sequence': 'My name isELS', 'score': 2.2e-05, 'token': 1_64_16, 'token_str': 'ELS'},
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('The largest city in France is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {
										            'sequence': 'The largest city in France is Maul',
										            'score': 2.2e-05,
										            'token': 3_56_76,
										            'token_str': ' Maul',
										        },
										        {'sequence': 'The largest city in France isELS', 'score': 2.2e-05, 'token': 1_64_16, 'token_str': 'ELS'},
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('My name is <mask>'  ,  targets=[' Patrick', ' Clara', ' Teven']  ,  top_k=3						)
										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        {'sequence': 'My name is Patrick', 'score': 2.1e-05, 'token': 34_99, 'token_str': ' Patrick'},
										        {'sequence': 'My name is Te', 'score': 2e-05, 'token': 29_41, 'token_str': ' Te'},
										        {'sequence': 'My name is Clara', 'score': 2e-05, 'token': 1_36_06, 'token_str': ' Clara'},
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('My name is <mask> <mask>'  ,  top_k=2						)

										self.assertEqual(
										    nested_simplify(lowercase__  ,  decimals=6						)  ,  [
										        [
										            {
										                'score': 2.2e-05,
										                'token': 3_56_76,
										                'token_str': ' Maul',
										                'sequence': '<s>My name is Maul<mask></s>',
										            },
										            {'score': 2.2e-05, 'token': 1_64_16, 'token_str': 'ELS', 'sequence': '<s>My name isELS<mask></s>'},
										        ],
										        [
										            {
										                'score': 2.2e-05,
										                'token': 3_56_76,
										                'token_str': ' Maul',
										                'sequence': '<s>My name is<mask> Maul</s>',
										            },
										            {'score': 2.2e-05, 'token': 1_64_16, 'token_str': 'ELS', 'sequence': '<s>My name is<mask>ELS</s>'},
										        ],
										    ]  ,  )





			@require_torch_gpu
			def   SCREAMING_SNAKE_CASE__     (       self	:	Union[str, Any]						):
										_lowerCAmelCase							=							pipeline('fill-mask'  ,  model='hf-internal-testing/tiny-random-distilbert'  ,  device=0  ,  framework='pt'						)

										# convert model to fp16
										pipe.model.half()

										_lowerCAmelCase							=							pipe('Paris is the [MASK] of France.'						)
										# We actually don't care about the result, we just want to make sure
										# it works, meaning the float16 tensor got casted back to float32
										# for postprocessing.
										self.assertIsInstance(lowercase__  ,  lowercase__						)





			@slow
			@require_torch
			def   SCREAMING_SNAKE_CASE__     (       self	:	Any						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='distilroberta-base'  ,  top_k=2  ,  framework='pt'						)
										self.run_large_test(lowercase__						)





			@slow
			@require_tf
			def   SCREAMING_SNAKE_CASE__     (       self	:	Dict						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='distilroberta-base'  ,  top_k=2  ,  framework='tf'						)
										self.run_large_test(lowercase__						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	Any  ,  lowercase__	:	Union[str, Any]						):
										_lowerCAmelCase							=							unmasker('My name is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__						)  ,  [
										        {'sequence': 'My name is John', 'score': 0.0_0_8, 'token': 6_10, 'token_str': ' John'},
										        {'sequence': 'My name is Chris', 'score': 0.0_0_7, 'token': 15_73, 'token_str': ' Chris'},
										    ]  ,  )
										_lowerCAmelCase							=							unmasker('The largest city in France is <mask>'						)
										self.assertEqual(
										    nested_simplify(lowercase__						)  ,  [
										        {
										            'sequence': 'The largest city in France is Paris',
										            'score': 0.2_5_1,
										            'token': 22_01,
										            'token_str': ' Paris',
										        },
										        {
										            'sequence': 'The largest city in France is Lyon',
										            'score': 0.2_1_4,
										            'token': 1_27_90,
										            'token_str': ' Lyon',
										        },
										    ]  ,  )

										_lowerCAmelCase							=							unmasker('My name is <mask>'  ,  targets=[' Patrick', ' Clara', ' Teven']  ,  top_k=3						)
										self.assertEqual(
										    nested_simplify(lowercase__						)  ,  [
										        {'sequence': 'My name is Patrick', 'score': 0.0_0_5, 'token': 34_99, 'token_str': ' Patrick'},
										        {'sequence': 'My name is Clara', 'score': 0.0_0_0, 'token': 1_36_06, 'token_str': ' Clara'},
										        {'sequence': 'My name is Te', 'score': 0.0_0_0, 'token': 29_41, 'token_str': ' Te'},
										    ]  ,  )





			@require_torch
			def   SCREAMING_SNAKE_CASE__     (       self	:	List[str]						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='sshleifer/tiny-distilroberta-base'  ,  framework='pt'						)
										_lowerCAmelCase							=							None
										_lowerCAmelCase							=							None
										self.run_pipeline_test(lowercase__  ,  []						)





			@require_tf
			def   SCREAMING_SNAKE_CASE__     (       self	:	List[str]						):
										_lowerCAmelCase							=							pipeline(task='fill-mask'  ,  model='sshleifer/tiny-distilroberta-base'  ,  framework='tf'						)
										_lowerCAmelCase							=							None
										_lowerCAmelCase							=							None
										self.run_pipeline_test(lowercase__  ,  []						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	int  ,  lowercase__	:	List[Any]  ,  lowercase__	:	int  ,  lowercase__	:	List[str]						):
										if tokenizer is None or tokenizer.mask_token_id is None:
																	self.skipTest('The provided tokenizer has no mask token, (probably reformer or wav2vec2)'						)

										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)
										_lowerCAmelCase							=							[
										    f'This is another {tokenizer.mask_token} test',
										]
										return fill_masker, examples





			def   SCREAMING_SNAKE_CASE__     (       self	:	Dict  ,  lowercase__	:	int  ,  lowercase__	:	Optional[Any]						):
										_lowerCAmelCase							=							fill_masker.tokenizer
										_lowerCAmelCase							=							fill_masker.model

										_lowerCAmelCase							=							fill_masker(
										    f'This is a {tokenizer.mask_token}'  ,  )
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )

										_lowerCAmelCase							=							fill_masker([f'This is a {tokenizer.mask_token}']						)
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )

										_lowerCAmelCase							=							fill_masker([f'This is a {tokenizer.mask_token}', f'Another {tokenizer.mask_token} great test.']						)
										self.assertEqual(
										    lowercase__  ,  [
										        [
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        ],
										        [
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        ],
										    ]  ,  )

										with self.assertRaises(lowercase__						):
																	fill_masker([None]						)
										# No mask_token is not supported
										with self.assertRaises(lowercase__						):
																	fill_masker('This is'						)

										self.run_test_top_k(lowercase__  ,  lowercase__						)
										self.run_test_targets(lowercase__  ,  lowercase__						)
										self.run_test_top_k_targets(lowercase__  ,  lowercase__						)
										self.fill_mask_with_duplicate_targets_and_top_k(lowercase__  ,  lowercase__						)
										self.fill_mask_with_multiple_masks(lowercase__  ,  lowercase__						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	List[Any]  ,  lowercase__	:	Optional[Any]  ,  lowercase__	:	Optional[int]						):
										_lowerCAmelCase							=							tokenizer.get_vocab()
										_lowerCAmelCase							=							sorted(vocab.keys()						)[:2]
										# Pipeline argument
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__  ,  targets=lowercase__						)
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'						)
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )
										_lowerCAmelCase							=							{vocab[el] for el in targets}
										self.assertEqual({el['token'] for el in outputs}  ,  lowercase__						)
										_lowerCAmelCase							=							[tokenizer.decode([x]						) for x in target_ids]
										self.assertEqual({el['token_str'] for el in outputs}  ,  set(lowercase__						)						)

										# Call argument
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=lowercase__						)
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )
										_lowerCAmelCase							=							{vocab[el] for el in targets}
										self.assertEqual({el['token'] for el in outputs}  ,  lowercase__						)
										_lowerCAmelCase							=							[tokenizer.decode([x]						) for x in target_ids]
										self.assertEqual({el['token_str'] for el in outputs}  ,  set(lowercase__						)						)

										# Score equivalence
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=lowercase__						)
										_lowerCAmelCase							=							[top_mask['token_str'] for top_mask in outputs]
										_lowerCAmelCase							=							[top_mask['score'] for top_mask in outputs]

										# For some BPE tokenizers, `</w>` is removed during decoding, so `token_str` won't be the same as in `targets`.
										if set(lowercase__						) == set(lowercase__						):
																	_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=lowercase__						)
																	_lowerCAmelCase							=							[top_mask['score'] for top_mask in unmasked_targets]
																	self.assertEqual(nested_simplify(lowercase__						)  ,  nested_simplify(lowercase__						)						)

										# Raises with invalid
										with self.assertRaises(lowercase__						):
																	_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=[]						)
										# For some tokenizers, `""` is actually in the vocabulary and the expected error won't raised
										if "" not in tokenizer.get_vocab():
																	with self.assertRaises(lowercase__						):
																								_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=['']						)
																	with self.assertRaises(lowercase__						):
																								_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  targets=''						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	Tuple  ,  lowercase__	:	Dict  ,  lowercase__	:	Any						):
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__  ,  top_k=2						)
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'						)
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )

										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  top_k=2						)
										self.assertEqual(
										    lowercase__  ,  [
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										    ]  ,  )
										self.assertEqual(nested_simplify(lowercase__						)  ,  nested_simplify(lowercase__						)						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	Any  ,  lowercase__	:	str  ,  lowercase__	:	Dict						):
										_lowerCAmelCase							=							tokenizer.get_vocab()
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)

										# top_k=2, ntargets=3
										_lowerCAmelCase							=							sorted(vocab.keys()						)[:3]
										_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  top_k=2  ,  targets=lowercase__						)

										# If we use the most probably targets, and filter differently, we should still
										# have the same results
										_lowerCAmelCase							=							[el['token_str'] for el in sorted(lowercase__  ,  key=lambda lowercase__						: x["score"]  ,  reverse=lowercase__						)]
										# For some BPE tokenizers, `</w>` is removed during decoding, so `token_str` won't be the same as in `targets`.
										if set(lowercase__						).issubset(lowercase__						):
																	_lowerCAmelCase							=							fill_masker(f'This is a {tokenizer.mask_token}'  ,  top_k=3  ,  targets=lowercase__						)
																	# They should yield exactly the same result
																	self.assertEqual(nested_simplify(lowercase__						)  ,  nested_simplify(lowercase__						)						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	Optional[int]  ,  lowercase__	:	str  ,  lowercase__	:	Union[str, Any]						):
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)
										_lowerCAmelCase							=							tokenizer.get_vocab()
										# String duplicates + id duplicates
										_lowerCAmelCase							=							sorted(vocab.keys()						)[:3]
										_lowerCAmelCase							=							[targets[0], targets[1], targets[0], targets[2], targets[1]]
										_lowerCAmelCase							=							fill_masker(f'My name is {tokenizer.mask_token}'  ,  targets=lowercase__  ,  top_k=10						)

										# The target list contains duplicates, so we can't output more
										# than them
										self.assertEqual(len(lowercase__						)  ,  3						)





			def   SCREAMING_SNAKE_CASE__     (       self	:	Tuple  ,  lowercase__	:	Union[str, Any]  ,  lowercase__	:	Optional[Any]						):
										_lowerCAmelCase							=							FillMaskPipeline(model=lowercase__  ,  tokenizer=lowercase__						)

										_lowerCAmelCase							=							fill_masker(
										    f'This is a {tokenizer.mask_token} {tokenizer.mask_token} {tokenizer.mask_token}'  ,  top_k=2						)
										self.assertEqual(
										    lowercase__  ,  [
										        [
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        ],
										        [
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        ],
										        [
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										            {'sequence': ANY(lowercase__						), 'score': ANY(lowercase__						), 'token': ANY(lowercase__						), 'token_str': ANY(lowercase__						)},
										        ],
										    ]  ,  )







import functools






def _lowerCamelCase  (		snake_case     , snake_case  ):

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

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

							if len(snake_case  ) == 0:
														return 0

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

							if max(snake_case  ) >= 366:
														raise ValueError('All days elements should be less than 366'  )

							_lowerCAmelCase							=							set(snake_case  )

							@functools.cache
							def dynamic_programming(snake_case  ) -> int:
														if index > 365:
																					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 + 30  )     , )

							return dynamic_programming(1  )


if __name__ == "__main__":
				import doctest

				doctest.testmod()






