





'''simple docstring'''







import tensorflow as tf

from ...tf_utils import shape_list


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

							def __init__(							self							:   Optional[Any]				,   __magic_name__							:   str				,   __magic_name__							:   Optional[int]				,   __magic_name__							:   List[str]				,   __magic_name__							:   int				,   __magic_name__							:   str=1				,   __magic_name__							:   Union[str, Any]=False				,   **__magic_name__							:   str      )    ->				Any:







													"""simple docstring"""
													super().__init__(**_lowerCAmelCase      )

													UpperCAmelCase_	:					Optional[Any]     =     vocab_size
													UpperCAmelCase_	:					Any     =     d_embed
													UpperCAmelCase_	:					Union[str, Any]     =     d_proj

													UpperCAmelCase_	:					Any     =     cutoffs + [vocab_size]
													UpperCAmelCase_	:					List[str]     =     [0] + self.cutoffs
													UpperCAmelCase_	:					Any     =     div_val

													UpperCAmelCase_	:					List[str]     =     self.cutoffs[0]
													UpperCAmelCase_	:					Tuple     =     len(self.cutoffs      ) - 1
													UpperCAmelCase_	:					Any     =     self.shortlist_size + self.n_clusters
													UpperCAmelCase_	:					Any     =     keep_order

													UpperCAmelCase_	:					Optional[Any]     =     []
													UpperCAmelCase_	:					Any     =     []

							def 			UpperCAmelCase__		(							self							:   Union[str, Any]				,   __magic_name__							:   Optional[int]      )    ->				List[Any]:







													"""simple docstring"""
													if self.n_clusters > 0:
																			UpperCAmelCase_	:					str     =     self.add_weight(
																			    shape=(self.n_clusters, self.d_embed)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name='''cluster_weight'''      )
																			UpperCAmelCase_	:					Union[str, Any]     =     self.add_weight(
																			    shape=(self.n_clusters,)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name='''cluster_bias'''      )

													if self.div_val == 1:
																			for i in range(len(self.cutoffs      )      ):
																									if self.d_proj != self.d_embed:
																															UpperCAmelCase_	:					Dict     =     self.add_weight(
																															    shape=(self.d_embed, self.d_proj)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_projs_._{i}"""				,   )
																															self.out_projs.append(_lowerCAmelCase      )
																									else:
																															self.out_projs.append(_lowerCAmelCase      )
																									UpperCAmelCase_	:					List[Any]     =     self.add_weight(
																									    shape=(self.vocab_size, self.d_embed)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_layers_._{i}_._weight"""				,   )
																									UpperCAmelCase_	:					int     =     self.add_weight(
																									    shape=(self.vocab_size,)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_layers_._{i}_._bias"""				,   )
																									self.out_layers.append((weight, bias)      )
													else:
																			for i in range(len(self.cutoffs      )      ):
																									UpperCAmelCase_	:					int     =     self.cutoff_ends[i], self.cutoff_ends[i + 1]
																									UpperCAmelCase_	:					List[Any]     =     self.d_embed // (self.div_val**i)

																									UpperCAmelCase_	:					Optional[int]     =     self.add_weight(
																									    shape=(d_emb_i, self.d_proj)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_projs_._{i}"""      )
																									self.out_projs.append(_lowerCAmelCase      )
																									UpperCAmelCase_	:					List[str]     =     self.add_weight(
																									    shape=(r_idx - l_idx, d_emb_i)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_layers_._{i}_._weight"""				,   )
																									UpperCAmelCase_	:					List[str]     =     self.add_weight(
																									    shape=(r_idx - l_idx,)				,   initializer='''zeros'''				,   trainable=_lowerCAmelCase				,   name=F"""out_layers_._{i}_._bias"""				,   )
																									self.out_layers.append((weight, bias)      )
													super().build(_lowerCAmelCase      )

							@staticmethod
							def 			UpperCAmelCase__		(							__magic_name__							:   Tuple				,   __magic_name__							:   List[Any]				,   __magic_name__							:   List[Any]				,   __magic_name__							:   Dict=None      )    ->				List[str]:







													"""simple docstring"""
													UpperCAmelCase_	:					List[str]     =     x
													if proj is not None:
																			UpperCAmelCase_	:					Dict     =     tf.einsum('''ibd,ed->ibe'''				,   _lowerCAmelCase				,   _lowerCAmelCase      )
													return tf.einsum('''ibd,nd->ibn'''				,   _lowerCAmelCase				,   _lowerCAmelCase      ) + b

							@staticmethod
							def 			UpperCAmelCase__		(							__magic_name__							:   Union[str, Any]				,   __magic_name__							:   Tuple      )    ->				Optional[Any]:







													"""simple docstring"""
													UpperCAmelCase_	:					Dict     =     shape_list(_lowerCAmelCase      )
													UpperCAmelCase_	:					str     =     tf.range(lp_size[0]				,   dtype=target.dtype      )
													UpperCAmelCase_	:					Dict     =     tf.stack([r, target]				,   1      )
													return tf.gather_nd(_lowerCAmelCase				,   _lowerCAmelCase      )



							def 			UpperCAmelCase__		(							self							:   List[Any]				,   __magic_name__							:   List[Any]				,   __magic_name__							:   List[str]				,   __magic_name__							:   Optional[Any]=True				,   __magic_name__							:   Any=False      )    ->				Tuple:







													"""simple docstring"""
													UpperCAmelCase_	:					Optional[Any]     =     0
													if self.n_clusters == 0:
																			UpperCAmelCase_	:					List[str]     =     self._logit(_lowerCAmelCase				,   self.out_layers[0][0]				,   self.out_layers[0][1]				,   self.out_projs[0]      )
																			if target is not None:
																									UpperCAmelCase_	:					Tuple     =     tf.nn.sparse_softmax_cross_entropy_with_logits(labels=_lowerCAmelCase				,   logits=_lowerCAmelCase      )
																			UpperCAmelCase_	:					Optional[Any]     =     tf.nn.log_softmax(_lowerCAmelCase				,   axis=-1      )
													else:
																			UpperCAmelCase_	:					Tuple     =     shape_list(_lowerCAmelCase      )
																			UpperCAmelCase_	:					int     =     []
																			UpperCAmelCase_	:					Union[str, Any]     =     tf.zeros(hidden_sizes[:2]      )
																			for i in range(len(self.cutoffs      )      ):
																									UpperCAmelCase_	:					int     =     self.cutoff_ends[i], self.cutoff_ends[i + 1]
																									if target is not None:
																															UpperCAmelCase_	:					Any     =     (target >= l_idx) & (target < r_idx)
																															UpperCAmelCase_	:					Optional[int]     =     tf.where(_lowerCAmelCase      )
																															UpperCAmelCase_	:					int     =     tf.boolean_mask(_lowerCAmelCase				,   _lowerCAmelCase      ) - l_idx

																									if self.div_val == 1:
																															UpperCAmelCase_	:					Dict     =     self.out_layers[0][0][l_idx:r_idx]
																															UpperCAmelCase_	:					Optional[Any]     =     self.out_layers[0][1][l_idx:r_idx]
																									else:
																															UpperCAmelCase_	:					Optional[Any]     =     self.out_layers[i][0]
																															UpperCAmelCase_	:					str     =     self.out_layers[i][1]

																									if i == 0:
																															UpperCAmelCase_	:					Union[str, Any]     =     tf.concat([cur_W, self.cluster_weight]				,   0      )
																															UpperCAmelCase_	:					Optional[int]     =     tf.concat([cur_b, self.cluster_bias]				,   0      )

																															UpperCAmelCase_	:					List[Any]     =     self._logit(_lowerCAmelCase				,   _lowerCAmelCase				,   _lowerCAmelCase				,   self.out_projs[0]      )
																															UpperCAmelCase_	:					Union[str, Any]     =     tf.nn.log_softmax(_lowerCAmelCase      )
																															out.append(head_logprob[..., : self.cutoffs[0]]      )
																															if target is not None:
																																					UpperCAmelCase_	:					Union[str, Any]     =     tf.boolean_mask(_lowerCAmelCase				,   _lowerCAmelCase      )
																																					UpperCAmelCase_	:					Optional[Any]     =     self._gather_logprob(_lowerCAmelCase				,   _lowerCAmelCase      )
																									else:
																															UpperCAmelCase_	:					Any     =     self._logit(_lowerCAmelCase				,   _lowerCAmelCase				,   _lowerCAmelCase				,   self.out_projs[i]      )
																															UpperCAmelCase_	:					Union[str, Any]     =     tf.nn.log_softmax(_lowerCAmelCase      )
																															UpperCAmelCase_	:					int     =     self.cutoffs[0] + i - 1  # No probability for the head cluster
																															UpperCAmelCase_	:					Any     =     head_logprob[..., cluster_prob_idx, None] + tail_logprob
																															out.append(_lowerCAmelCase      )
																															if target is not None:
																																					UpperCAmelCase_	:					Tuple     =     tf.boolean_mask(_lowerCAmelCase				,   _lowerCAmelCase      )
																																					UpperCAmelCase_	:					Any     =     tf.boolean_mask(_lowerCAmelCase				,   _lowerCAmelCase      )
																																					UpperCAmelCase_	:					int     =     self._gather_logprob(_lowerCAmelCase				,   _lowerCAmelCase      )
																																					cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1]
																									if target is not None:
																															loss += tf.scatter_nd(_lowerCAmelCase				,   -cur_logprob				,   shape_list(_lowerCAmelCase      )      )
																			UpperCAmelCase_	:					Optional[Any]     =     tf.concat(_lowerCAmelCase				,   axis=-1      )

													if target is not None:
																			if return_mean:
																									UpperCAmelCase_	:					Union[str, Any]     =     tf.reduce_mean(_lowerCAmelCase      )
																			# Add the training-time loss value to the layer using `self.add_loss()`.
																			self.add_loss(_lowerCAmelCase      )

																			# Log the loss as a metric (we could log arbitrary metrics,
																			# including different metrics for training and inference.
																			self.add_metric(_lowerCAmelCase				,   name=self.name				,   aggregation='''mean''' if return_mean else ''''''      )

													return out











import math
import sys



def 					UpperCAmelCase__     (   lowerCamelCase      ):
  if number != int(lowerCamelCase      ):
    raise ValueError("the value of input must be a natural number"      )
  if number < 0:
    raise ValueError("the value of input must not be a negative number"      )
  if number == 0:
    return 1
  lowercase			:Dict							=  [-1] * (number + 1)
  lowercase			:Optional[Any]							=  0
  for i in range(1,	number + 1      ):
    lowercase			:Optional[int]							=  sys.maxsize
    lowercase			:Any							=  int(math.sqrt(lowerCamelCase      )      )
    for j in range(1,	root + 1      ):
      lowercase			:Any							=  1 + answers[i - (j**2)]
      lowercase			:Dict							=  min(lowerCamelCase,	lowerCamelCase      )
    lowercase			:Union[str, Any]							=  answer
  return answers[number]


if __name__ == "__main__":
     import doctest

     doctest.testmod()



