





from typing import Optional, Tuple, Union

import tensorflow as tf

from ...activations_tf import ACTaFN
from ...file_utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward
from ...modeling_tf_outputs import (
    TFBaseModelOutputWithNoAttention,
    TFBaseModelOutputWithPoolingAndNoAttention,
    TFSequenceClassifierOutput,
)
from ...modeling_tf_utils import TFPreTrainedModel, TFSequenceClassificationLoss, keras_serializable, unpack_inputs
from ...tf_utils import shape_list
from ...utils import logging
from .configuration_regnet import RegNetConfig


_UpperCAmelCase             =							logging.get_logger(__name__)

# General docstring
_UpperCAmelCase             =							'RegNetConfig'

# Base docstring
_UpperCAmelCase             =							'facebook/regnet-y-040'
_UpperCAmelCase             =							[1, 1088, 7, 7]

# Image classification docstring
_UpperCAmelCase             =							'facebook/regnet-y-040'
_UpperCAmelCase             =							'tabby, tabby cat'

_UpperCAmelCase             =							[
    'facebook/regnet-y-040',
    # See all regnet models at https://huggingface.co/models?filter=regnet
]






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Optional[Any]       ,  _snake_case			:					int       ,  _snake_case			:					int = 3       ,  _snake_case			:					int = 1       ,  _snake_case			:					int = 1       ,  _snake_case			:					Optional[str] = "relu"       ,  **_snake_case			:					List[Any]       ,  )->str:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   # The padding and conv has been verified in
   # https://colab.research.google.com/gist/sayakpaul/854bc10eeaf21c9ee2119e0b9f3841a7/scratchpad.ipynb
   __lowerCAmelCase					:	Union[str, Any]      =       tf.keras.layers.ZeroPaddingaD(padding=kernel_size // 2      )
   __lowerCAmelCase					:	Union[str, Any]      =       tf.keras.layers.ConvaD(
       filters=_snake_case       ,  kernel_size=_snake_case       ,  strides=_snake_case       ,  padding="""VALID"""       ,  groups=_snake_case       ,  use_bias=_snake_case       ,  name="""convolution"""       ,  )
   __lowerCAmelCase					:	Tuple      =       tf.keras.layers.BatchNormalization(epsilon=1E-5       ,  momentum=0.9       ,  name="""normalization"""      )
   __lowerCAmelCase					:	Any      =       ACTaFN[activation] if activation is not None else tf.identity






  def 				UpperCAmelCase__						(							self			:					Tuple       ,  _snake_case			:					Optional[int]      )->Any:






   '''simple docstring'''

   __lowerCAmelCase					:	Union[str, Any]      =       self.convolution(self.padding(_snake_case      )      )
   __lowerCAmelCase					:	Optional[Any]      =       self.normalization(_snake_case      )
   __lowerCAmelCase					:	Union[str, Any]      =       self.activation(_snake_case      )
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Optional[int]       ,  _snake_case			:					RegNetConfig       ,  **_snake_case			:					Union[str, Any]      )->int:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	Any      =       config.num_channels
   __lowerCAmelCase					:	str      =       TFRegNetConvLayer(
       out_channels=config.embedding_size       ,  kernel_size=3       ,  stride=2       ,  activation=config.hidden_act       ,  name="""embedder"""       ,  )






  def 				UpperCAmelCase__						(							self			:					int       ,  _snake_case			:					List[Any]      )->int:






   '''simple docstring'''

   __lowerCAmelCase					:	Optional[Any]      =       shape_list(_snake_case      )[1]
   if tf.executing_eagerly() and num_channels != self.num_channels:
    raise ValueError(
        """Make sure that the channel dimension of the pixel values match with the one set in the configuration."""      )

   # When running on CPU, `tf.keras.layers.Conv2D` doesn't support `NCHW` format.
   # So change the input format from `NCHW` to `NHWC`.
   # shape = (batch_size, in_height, in_width, in_channels=num_channels)
   __lowerCAmelCase					:	Dict      =       tf.transpose(_snake_case       ,  perm=(0, 2, 3, 1)      )
   __lowerCAmelCase					:	int      =       self.embedder(_snake_case      )
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Tuple       ,  _snake_case			:					int       ,  _snake_case			:					int = 2       ,  **_snake_case			:					List[str]      )->Optional[Any]:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	List[str]      =       tf.keras.layers.ConvaD(
       filters=_snake_case       ,  kernel_size=1       ,  strides=_snake_case       ,  use_bias=_snake_case       ,  name="""convolution"""      )
   __lowerCAmelCase					:	Union[str, Any]      =       tf.keras.layers.BatchNormalization(epsilon=1E-5       ,  momentum=0.9       ,  name="""normalization"""      )






  def 				UpperCAmelCase__						(							self			:					List[str]       ,  _snake_case			:					tf.Tensor       ,  _snake_case			:					bool = False      )->tf.Tensor:






   '''simple docstring'''

   return self.normalization(self.convolution(_snake_case      )       ,  training=_snake_case      )






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Dict       ,  _snake_case			:					int       ,  _snake_case			:					int       ,  **_snake_case			:					Optional[int]      )->List[str]:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	Optional[int]      =       tf.keras.layers.GlobalAveragePoolingaD(keepdims=_snake_case       ,  name="""pooler"""      )
   __lowerCAmelCase					:	int      =       [
       tf.keras.layers.ConvaD(filters=_snake_case       ,  kernel_size=1       ,  activation="""relu"""       ,  name="""attention.0"""      ),
       tf.keras.layers.ConvaD(filters=_snake_case       ,  kernel_size=1       ,  activation="""sigmoid"""       ,  name="""attention.2"""      ),
   ]






  def 				UpperCAmelCase__						(							self			:					Optional[Any]       ,  _snake_case			:					Tuple      )->List[Any]:






   '''simple docstring'''

   __lowerCAmelCase					:	Union[str, Any]      =       self.pooler(_snake_case      )
   for layer_module in self.attention:
    __lowerCAmelCase					:	Any      =       layer_module(_snake_case      )
   __lowerCAmelCase					:	Optional[Any]      =       hidden_state * pooled
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Optional[int]       ,  _snake_case			:					RegNetConfig       ,  _snake_case			:					int       ,  _snake_case			:					int       ,  _snake_case			:					int = 1       ,  **_snake_case			:					Union[str, Any]      )->Optional[int]:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	Optional[int]      =       in_channels != out_channels or stride != 1
   __lowerCAmelCase					:	int      =       max(1       ,  out_channels // config.groups_width      )
   __lowerCAmelCase					:	str      =       (
       TFRegNetShortCut(_snake_case       ,  stride=_snake_case       ,  name="""shortcut"""      )
       if should_apply_shortcut
       else tf.keras.layers.Activation("""linear"""       ,  name="""shortcut"""      )
   )
   # `self.layers` instead of `self.layer` because that is a reserved argument.
   __lowerCAmelCase					:	Tuple      =       [
       TFRegNetConvLayer(_snake_case       ,  kernel_size=1       ,  activation=config.hidden_act       ,  name="""layer.0"""      ),
       TFRegNetConvLayer(
           _snake_case       ,  stride=_snake_case       ,  groups=_snake_case       ,  activation=config.hidden_act       ,  name="""layer.1"""      ),
       TFRegNetConvLayer(_snake_case       ,  kernel_size=1       ,  activation=_snake_case       ,  name="""layer.2"""      ),
   ]
   __lowerCAmelCase					:	Optional[int]      =       ACTaFN[config.hidden_act]






  def 				UpperCAmelCase__						(							self			:					Dict       ,  _snake_case			:					Optional[Any]      )->str:






   '''simple docstring'''

   __lowerCAmelCase					:	str      =       hidden_state
   for layer_module in self.layers:
    __lowerCAmelCase					:	List[Any]      =       layer_module(_snake_case      )
   __lowerCAmelCase					:	Dict      =       self.shortcut(_snake_case      )
   hidden_state += residual
   __lowerCAmelCase					:	List[str]      =       self.activation(_snake_case      )
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					int       ,  _snake_case			:					RegNetConfig       ,  _snake_case			:					int       ,  _snake_case			:					int       ,  _snake_case			:					int = 1       ,  **_snake_case			:					Optional[int]      )->int:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	List[str]      =       in_channels != out_channels or stride != 1
   __lowerCAmelCase					:	Union[str, Any]      =       max(1       ,  out_channels // config.groups_width      )
   __lowerCAmelCase					:	int      =       (
       TFRegNetShortCut(_snake_case       ,  stride=_snake_case       ,  name="""shortcut"""      )
       if should_apply_shortcut
       else tf.keras.layers.Activation("""linear"""       ,  name="""shortcut"""      )
   )
   __lowerCAmelCase					:	List[str]      =       [
       TFRegNetConvLayer(_snake_case       ,  kernel_size=1       ,  activation=config.hidden_act       ,  name="""layer.0"""      ),
       TFRegNetConvLayer(
           _snake_case       ,  stride=_snake_case       ,  groups=_snake_case       ,  activation=config.hidden_act       ,  name="""layer.1"""      ),
       TFRegNetSELayer(_snake_case       ,  reduced_channels=int(round(in_channels / 4      )      )       ,  name="""layer.2"""      ),
       TFRegNetConvLayer(_snake_case       ,  kernel_size=1       ,  activation=_snake_case       ,  name="""layer.3"""      ),
   ]
   __lowerCAmelCase					:	Optional[Any]      =       ACTaFN[config.hidden_act]






  def 				UpperCAmelCase__						(							self			:					Union[str, Any]       ,  _snake_case			:					List[Any]      )->Union[str, Any]:






   '''simple docstring'''

   __lowerCAmelCase					:	List[Any]      =       hidden_state
   for layer_module in self.layers:
    __lowerCAmelCase					:	Any      =       layer_module(_snake_case      )
   __lowerCAmelCase					:	str      =       self.shortcut(_snake_case      )
   hidden_state += residual
   __lowerCAmelCase					:	Optional[int]      =       self.activation(_snake_case      )
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					Dict       ,  _snake_case			:					RegNetConfig       ,  _snake_case			:					int       ,  _snake_case			:					int       ,  _snake_case			:					int = 2       ,  _snake_case			:					int = 2       ,  **_snake_case			:					str      )->Dict:






   '''simple docstring'''

   super().__init__(**_snake_case      )

   __lowerCAmelCase					:	str      =       TFRegNetXLayer if config.layer_type == """x""" else TFRegNetYLayer
   __lowerCAmelCase					:	Optional[int]      =       [
       # downsampling is done in the first layer with stride of 2
       layer(_snake_case       ,  _snake_case       ,  _snake_case       ,  stride=_snake_case       ,  name="""layers.0"""      ),
       *[layer(_snake_case       ,  _snake_case       ,  _snake_case       ,  name=F'''layers.{i+1}'''      ) for i in range(depth - 1      )],
   ]






  def 				UpperCAmelCase__						(							self			:					Any       ,  _snake_case			:					List[Any]      )->int:






   '''simple docstring'''

   for layer_module in self.layers:
    __lowerCAmelCase					:	str      =       layer_module(_snake_case      )
   return hidden_state






class        snake_case_    (		tf.keras.layers.Layer						):






  def __init__(							self			:					str       ,  _snake_case			:					RegNetConfig       ,  **_snake_case			:					Union[str, Any]      )->int:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	Union[str, Any]      =       []
   # based on `downsample_in_first_stage`, the first layer of the first stage may or may not downsample the input
   self.stages.append(
       TFRegNetStage(
           _snake_case       ,  config.embedding_size       ,  config.hidden_sizes[0]       ,  stride=2 if config.downsample_in_first_stage else 1       ,  depth=config.depths[0]       ,  name="""stages.0"""       ,  )      )
   __lowerCAmelCase					:	Optional[int]      =       zip(config.hidden_sizes       ,  config.hidden_sizes[1:]      )
   for i, ((in_channels, out_channels), depth) in enumerate(zip(_snake_case       ,  config.depths[1:]      )      ):
    self.stages.append(TFRegNetStage(_snake_case       ,  _snake_case       ,  _snake_case       ,  depth=_snake_case       ,  name=F'''stages.{i+1}'''      )      )






  def 				UpperCAmelCase__						(							self			:					int       ,  _snake_case			:					tf.Tensor       ,  _snake_case			:					bool = False       ,  _snake_case			:					bool = True      )->TFBaseModelOutputWithNoAttention:






   '''simple docstring'''

   __lowerCAmelCase					:	str      =       () if output_hidden_states else None

   for stage_module in self.stages:
    if output_hidden_states:
     __lowerCAmelCase					:	str      =       hidden_states + (hidden_state,)

    __lowerCAmelCase					:	str      =       stage_module(_snake_case      )

   if output_hidden_states:
    __lowerCAmelCase					:	Optional[int]      =       hidden_states + (hidden_state,)

   if not return_dict:
    return tuple(v for v in [hidden_state, hidden_states] if v is not None      )

   return TFBaseModelOutputWithNoAttention(last_hidden_state=_snake_case       ,  hidden_states=_snake_case      )






@keras_serializable
class        snake_case_    (		tf.keras.layers.Layer						):
  A_      							=   RegNetConfig






  def __init__(							self			:					int       ,  _snake_case			:					Optional[Any]       ,  **_snake_case			:					Tuple      )->Optional[Any]:






   '''simple docstring'''

   super().__init__(**_snake_case      )
   __lowerCAmelCase					:	str      =       config
   __lowerCAmelCase					:	Any      =       TFRegNetEmbeddings(_snake_case       ,  name="""embedder"""      )
   __lowerCAmelCase					:	Optional[int]      =       TFRegNetEncoder(_snake_case       ,  name="""encoder"""      )
   __lowerCAmelCase					:	Any      =       tf.keras.layers.GlobalAveragePoolingaD(keepdims=_snake_case       ,  name="""pooler"""      )






  @unpack_inputs
  def 				UpperCAmelCase__						(							self			:					Dict       ,  _snake_case			:					tf.Tensor       ,  _snake_case			:					Optional[bool] = None       ,  _snake_case			:					Optional[bool] = None       ,  _snake_case			:					bool = False       ,  )->TFBaseModelOutputWithPoolingAndNoAttention:






   '''simple docstring'''

   __lowerCAmelCase					:	Tuple      =       (
       output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
   )
   __lowerCAmelCase					:	List[str]      =       return_dict if return_dict is not None else self.config.use_return_dict

   __lowerCAmelCase					:	Optional[int]      =       self.embedder(_snake_case       ,  training=_snake_case      )

   __lowerCAmelCase					:	Optional[int]      =       self.encoder(
       _snake_case       ,  output_hidden_states=_snake_case       ,  return_dict=_snake_case       ,  training=_snake_case      )

   __lowerCAmelCase					:	List[Any]      =       encoder_outputs[0]
   __lowerCAmelCase					:	Optional[Any]      =       self.pooler(_snake_case      )

   # Change to NCHW output format have uniformity in the modules
   __lowerCAmelCase					:	Any      =       tf.transpose(_snake_case       ,  perm=(0, 3, 1, 2)      )
   __lowerCAmelCase					:	int      =       tf.transpose(_snake_case       ,  perm=(0, 3, 1, 2)      )

   # Change the other hidden state outputs to NCHW as well
   if output_hidden_states:
    __lowerCAmelCase					:	Optional[int]      =       tuple([tf.transpose(_snake_case       ,  perm=(0, 3, 1, 2)      ) for h in encoder_outputs[1]]      )

   if not return_dict:
    return (last_hidden_state, pooled_output) + encoder_outputs[1:]

   return TFBaseModelOutputWithPoolingAndNoAttention(
       last_hidden_state=_snake_case       ,  pooler_output=_snake_case       ,  hidden_states=hidden_states if output_hidden_states else encoder_outputs.hidden_states       ,  )






class        snake_case_    (		__lowercase						):
  A_      							=   RegNetConfig
  A_      							=   'regnet'
  A_      							=   'pixel_values'






  @property
  def 				UpperCAmelCase__						(							self			:					int      )->Any:






   '''simple docstring'''

   return {"pixel_values": tf.TensorSpec(shape=(None, self.config.num_channels, 224, 224)       ,  dtype=tf.floataa      )}



_UpperCAmelCase             =							R'\n    Parameters:\n    This model is a Tensorflow\n    [tf.keras.layers.Layer](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer) sub-class. Use it as a\n    regular Tensorflow Module and refer to the Tensorflow documentation for all matter related to general usage and\n    behavior.\n        config ([`RegNetConfig`]): Model configuration class with all the parameters of the model.\n            Initializing with a config file does not load the weights associated with the model, only the\n            configuration. Check out the [`~TFPreTrainedModel.from_pretrained`] method to load the model weights.\n'

_UpperCAmelCase             =							R'\n    Args:\n        pixel_values (`tf.Tensor` of shape `(batch_size, num_channels, height, width)`):\n            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See\n            [`ConveNextImageProcessor.__call__`] for details.\n        output_hidden_states (`bool`, *optional*):\n            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for\n            more detail.\n        return_dict (`bool`, *optional*):\n            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.\n'






@add_start_docstrings(
    'The bare RegNet model outputting raw features without any specific head on top.'					,__lowercase					,)
class        snake_case_    (		__lowercase						):






  def __init__(							self			:					Optional[int]       ,  _snake_case			:					RegNetConfig       ,  *_snake_case			:					Any       ,  **_snake_case			:					Tuple      )->Optional[Any]:






   '''simple docstring'''

   super().__init__(_snake_case       ,  *_snake_case       ,  **_snake_case      )
   __lowerCAmelCase					:	Any      =       TFRegNetMainLayer(_snake_case       ,  name="""regnet"""      )






  @unpack_inputs
  @add_start_docstrings_to_model_forward(_snake_case      )
  @add_code_sample_docstrings(
      checkpoint=_CHECKPOINT_FOR_DOC       ,  output_type=_snake_case       ,  config_class=_CONFIG_FOR_DOC       ,  modality="""vision"""       ,  expected_output=_EXPECTED_OUTPUT_SHAPE       ,  )
  def 				UpperCAmelCase__						(							self			:					Optional[Any]       ,  _snake_case			:					tf.Tensor       ,  _snake_case			:					Optional[bool] = None       ,  _snake_case			:					Optional[bool] = None       ,  _snake_case			:					Optional[Any]=False       ,  )->Union[TFBaseModelOutputWithPoolingAndNoAttention, Tuple[tf.Tensor]]:






   '''simple docstring'''

   __lowerCAmelCase					:	int      =       (
       output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
   )
   __lowerCAmelCase					:	int      =       return_dict if return_dict is not None else self.config.use_return_dict

   __lowerCAmelCase					:	Optional[Any]      =       self.regnet(
       pixel_values=_snake_case       ,  output_hidden_states=_snake_case       ,  return_dict=_snake_case       ,  training=_snake_case       ,  )
   if not return_dict:
    return (outputs[0],) + outputs[1:]

   return TFBaseModelOutputWithPoolingAndNoAttention(
       last_hidden_state=outputs.last_hidden_state       ,  pooler_output=outputs.pooler_output       ,  hidden_states=outputs.hidden_states       ,  )






@add_start_docstrings(
    '\n    RegNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for\n    ImageNet.\n    '					,__lowercase					,)
class        snake_case_    (		__lowercase					,__lowercase						):






  def __init__(							self			:					int       ,  _snake_case			:					RegNetConfig       ,  *_snake_case			:					Tuple       ,  **_snake_case			:					List[str]      )->int:






   '''simple docstring'''

   super().__init__(_snake_case       ,  *_snake_case       ,  **_snake_case      )
   __lowerCAmelCase					:	Dict      =       config.num_labels
   __lowerCAmelCase					:	Optional[Any]      =       TFRegNetMainLayer(_snake_case       ,  name="""regnet"""      )
   # classification head
   __lowerCAmelCase					:	str      =       [
       tf.keras.layers.Flatten(),
       tf.keras.layers.Dense(config.num_labels       ,  name="""classifier.1"""      ) if config.num_labels > 0 else tf.identity,
   ]






  @unpack_inputs
  @add_start_docstrings_to_model_forward(_snake_case      )
  @add_code_sample_docstrings(
      checkpoint=_IMAGE_CLASS_CHECKPOINT       ,  output_type=_snake_case       ,  config_class=_CONFIG_FOR_DOC       ,  expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT       ,  )
  def 				UpperCAmelCase__						(							self			:					str       ,  _snake_case			:					tf.Tensor = None       ,  _snake_case			:					tf.Tensor = None       ,  _snake_case			:					bool = None       ,  _snake_case			:					bool = None       ,  _snake_case			:					Tuple=False       ,  )->Union[TFSequenceClassifierOutput, Tuple[tf.Tensor]]:






   '''simple docstring'''

   __lowerCAmelCase					:	List[Any]      =       (
       output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
   )
   __lowerCAmelCase					:	Union[str, Any]      =       return_dict if return_dict is not None else self.config.use_return_dict

   __lowerCAmelCase					:	List[str]      =       self.regnet(
       _snake_case       ,  output_hidden_states=_snake_case       ,  return_dict=_snake_case       ,  training=_snake_case      )

   __lowerCAmelCase					:	Tuple      =       outputs.pooler_output if return_dict else outputs[1]

   __lowerCAmelCase					:	str      =       self.classifier[0](_snake_case      )
   __lowerCAmelCase					:	Union[str, Any]      =       self.classifier[1](_snake_case      )

   __lowerCAmelCase					:	Optional[int]      =       None if labels is None else self.hf_compute_loss(labels=_snake_case       ,  logits=_snake_case      )

   if not return_dict:
    __lowerCAmelCase					:	Optional[Any]      =       (logits,) + outputs[2:]
    return ((loss,) + output) if loss is not None else output

   return TFSequenceClassifierOutput(loss=_snake_case       ,  logits=_snake_case       ,  hidden_states=outputs.hidden_states      )






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:list   )      ->   Dict:
 _enforce_args(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
 if n == 0:
  return 0
 __lowerCAmelCase					:	Union[str, Any]      =       float("""-inf"""   )
 for i in range(1   ,   n + 1   ):
  __lowerCAmelCase					:	Union[str, Any]      =       max(
      SCREAMING_SNAKE_CASE   ,   prices[i - 1] + naive_cut_rod_recursive(n - i   ,   SCREAMING_SNAKE_CASE   )   )

 return max_revue






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:list   )      ->   List[str]:
 _enforce_args(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
 __lowerCAmelCase					:	List[str]      =       [float("""-inf"""   ) for _ in range(n + 1   )]
 return _top_down_cut_rod_recursive(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:list   ,   SCREAMING_SNAKE_CASE		:list   )      ->   List[str]:
 if max_rev[n] >= 0:
  return max_rev[n]
 elif n == 0:
  return 0
 else:
  __lowerCAmelCase					:	str      =       float("""-inf"""   )
  for i in range(1   ,   n + 1   ):
   __lowerCAmelCase					:	List[Any]      =       max(
       SCREAMING_SNAKE_CASE   ,   prices[i - 1] + _top_down_cut_rod_recursive(n - i   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )   ,   )

  __lowerCAmelCase					:	List[str]      =       max_revenue

 return max_rev[n]






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:list   )      ->   Union[str, Any]:
 _enforce_args(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )

 # length(max_rev) = n + 1, to accommodate for the revenue obtainable from a rod of
 # length 0.
 __lowerCAmelCase					:	Optional[int]      =       [float("""-inf"""   ) for _ in range(n + 1   )]
 __lowerCAmelCase					:	List[str]      =       0

 for i in range(1   ,   n + 1   ):
  __lowerCAmelCase					:	Optional[Any]      =       max_rev[i]
  for j in range(1   ,   i + 1   ):
   __lowerCAmelCase					:	Optional[int]      =       max(SCREAMING_SNAKE_CASE   ,   prices[j - 1] + max_rev[i - j]   )

  __lowerCAmelCase					:	Optional[int]      =       max_revenue_i

 return max_rev[n]






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:list   )      ->   List[Any]:
 if n < 0:
  __lowerCAmelCase					:	Any      =       F'''n must be greater than or equal to 0. Got n = {n}'''
  raise ValueError(SCREAMING_SNAKE_CASE   )

 if n > len(SCREAMING_SNAKE_CASE   ):
  __lowerCAmelCase					:	Any      =       (
      """Each integral piece of rod must have a corresponding price. """
      F'''Got n = {n} but length of prices = {len(SCREAMING_SNAKE_CASE   )}'''
  )
  raise ValueError(SCREAMING_SNAKE_CASE   )






def 	_SCREAMING_SNAKE_CASE		(      )      ->   Optional[int]:
 __lowerCAmelCase					:	Tuple      =       [6, 10, 12, 15, 20, 23]
 __lowerCAmelCase					:	List[str]      =       len(SCREAMING_SNAKE_CASE   )

 # the best revenue comes from cutting the rod into 6 pieces, each
 # of length 1 resulting in a revenue of 6 * 6 = 36.
 __lowerCAmelCase					:	Union[str, Any]      =       36

 __lowerCAmelCase					:	Optional[int]      =       top_down_cut_rod(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
 __lowerCAmelCase					:	List[str]      =       bottom_up_cut_rod(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
 __lowerCAmelCase					:	int      =       naive_cut_rod_recursive(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )

 assert expected_max_revenue == max_rev_top_down
 assert max_rev_top_down == max_rev_bottom_up
 assert max_rev_bottom_up == max_rev_naive


if __name__ == "__main__":
      main()