



import re
import string

import numpy as np

import datasets


lowerCAmelCase__		:     Optional[Any]       						='''
Returns the rate at which the input predicted strings exactly match their references, ignoring any strings input as part of the regexes_to_ignore list.
'''

lowerCAmelCase__		:     List[Any]       						='''
Args:
    predictions: List of predicted texts.
    references: List of reference texts.
    regexes_to_ignore: List, defaults to None. Regex expressions of characters to
        ignore when calculating the exact matches. Note: these regexes are removed
        from the input data before the changes based on the options below (e.g. ignore_case,
        ignore_punctuation, ignore_numbers) are applied.
    ignore_case: Boolean, defaults to False. If true, turns everything
        to lowercase so that capitalization differences are ignored.
    ignore_punctuation: Boolean, defaults to False. If true, removes all punctuation before
        comparing predictions and references.
    ignore_numbers: Boolean, defaults to False. If true, removes all punctuation before
        comparing predictions and references.
Returns:
    exact_match: Dictionary containing exact_match rate. Possible values are between 0.0 and 100.0, inclusive.
Examples:
    >>> exact_match = datasets.load_metric("exact_match")
    >>> refs = ["the cat", "theater", "YELLING", "agent007"]
    >>> preds = ["cat?", "theater", "yelling", "agent"]
    >>> results = exact_match.compute(references=refs, predictions=preds)
    >>> print(round(results["exact_match"], 1))
    25.0

    >>> exact_match = datasets.load_metric("exact_match")
    >>> refs = ["the cat", "theater", "YELLING", "agent007"]
    >>> preds = ["cat?", "theater", "yelling", "agent"]
    >>> results = exact_match.compute(references=refs, predictions=preds, regexes_to_ignore=["the ", "yell"], ignore_case=True, ignore_punctuation=True)
    >>> print(round(results["exact_match"], 1))
    50.0


    >>> exact_match = datasets.load_metric("exact_match")
    >>> refs = ["the cat", "theater", "YELLING", "agent007"]
    >>> preds = ["cat?", "theater", "yelling", "agent"]
    >>> results = exact_match.compute(references=refs, predictions=preds, regexes_to_ignore=["the ", "yell", "YELL"], ignore_case=True, ignore_punctuation=True)
    >>> print(round(results["exact_match"], 1))
    75.0

    >>> exact_match = datasets.load_metric("exact_match")
    >>> refs = ["the cat", "theater", "YELLING", "agent007"]
    >>> preds = ["cat?", "theater", "yelling", "agent"]
    >>> results = exact_match.compute(references=refs, predictions=preds, regexes_to_ignore=["the ", "yell", "YELL"], ignore_case=True, ignore_punctuation=True, ignore_numbers=True)
    >>> print(round(results["exact_match"], 1))
    100.0

    >>> exact_match = datasets.load_metric("exact_match")
    >>> refs = ["The cat sat on the mat.", "Theaters are great.", "It\'s like comparing oranges and apples."]
    >>> preds = ["The cat sat on the mat?", "Theaters are great.", "It\'s like comparing apples and oranges."]
    >>> results = exact_match.compute(references=refs, predictions=preds)
    >>> print(round(results["exact_match"], 1))
    33.3

'''

lowerCAmelCase__		:     str       						='''
'''

@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION    ,    _KWARGS_DESCRIPTION       )
class    UpperCAmelCase_  (   datasets.Metric       ):

						'''simple docstring'''




						def        _A	(    self		):







													'''simple docstring'''

													return datasets.MetricInfo(
													    description=_DESCRIPTION      ,							citation=_CITATION      ,							inputs_description=_KWARGS_DESCRIPTION      ,							features=datasets.Features(
													        {
													            'predictions': datasets.Value('string'      ,							id='sequence'		),
													            'references': datasets.Value('string'      ,							id='sequence'		),
													        }		)      ,							reference_urls=[]      ,							)






						def        _A	(    self      ,							_A      ,							_A      ,							_A=None      ,							_A=False      ,							_A=False      ,							_A=False      ,							):







													'''simple docstring'''

													if regexes_to_ignore is not None:
																				for s in regexes_to_ignore:
																											__SCREAMING_SNAKE_CASE									=					np.array([re.sub(snake_case__      ,							''      ,							snake_case__		) for x in predictions]		)
																											__SCREAMING_SNAKE_CASE									=					np.array([re.sub(snake_case__      ,							''      ,							snake_case__		) for x in references]		)
													else:
																				__SCREAMING_SNAKE_CASE									=					np.asarray(snake_case__		)
																				__SCREAMING_SNAKE_CASE									=					np.asarray(snake_case__		)

													if ignore_case:
																				__SCREAMING_SNAKE_CASE									=					np.char.lower(snake_case__		)
																				__SCREAMING_SNAKE_CASE									=					np.char.lower(snake_case__		)

													if ignore_punctuation:
																				__SCREAMING_SNAKE_CASE									=					string.punctuation.maketrans(''      ,							''      ,							string.punctuation		)
																				__SCREAMING_SNAKE_CASE									=					np.char.translate(snake_case__      ,							table=snake_case__		)
																				__SCREAMING_SNAKE_CASE									=					np.char.translate(snake_case__      ,							table=snake_case__		)

													if ignore_numbers:
																				__SCREAMING_SNAKE_CASE									=					string.digits.maketrans(''      ,							''      ,							string.digits		)
																				__SCREAMING_SNAKE_CASE									=					np.char.translate(snake_case__      ,							table=snake_case__		)
																				__SCREAMING_SNAKE_CASE									=					np.char.translate(snake_case__      ,							table=snake_case__		)

													__SCREAMING_SNAKE_CASE									=					predictions == references

													return {"exact_match": np.mean(snake_case__		) * 100}










"""simple docstring"""







from __future__ import annotations

from collections import namedtuple
from dataclasses import dataclass


@dataclass
class       SCREAMING_SNAKE_CASE__				:
       """simple docstring"""


       a  :				int
       a  :				TreeNode | None   =None
       a  :				TreeNode | None   =None

lowerCAmelCase__      				=   namedtuple('''CoinsDistribResult''', '''moves excess''')
def 					a__			(				SCREAMING_SNAKE_CASE    :    TreeNode | None				):


  '''simple docstring'''







  if root is None:
    return 0

  # Validation
  def count_nodes(SCREAMING_SNAKE_CASE    :    TreeNode | None				) -> int:
    if node is None:
      return 0

    return count_nodes(node.left				) + count_nodes(node.right				) + 1

  def count_coins(SCREAMING_SNAKE_CASE    :    TreeNode | None				) -> int:
    if node is None:
      return 0

    return count_coins(node.left				) + count_coins(node.right				) + node.data

  if count_nodes(SCREAMING_SNAKE_CASE				) != count_coins(SCREAMING_SNAKE_CASE				):
    raise ValueError("The nodes number should be same as the number of coins"				)

  # Main calculation
  def get_distrib(SCREAMING_SNAKE_CASE    :    TreeNode | None				) -> CoinsDistribResult:

    if node is None:
      return CoinsDistribResult(0				,      1				)

    lowerCAmelCase						,  lowerCAmelCase     :     List[str]								=							get_distrib(node.left				)
    lowerCAmelCase						,  lowerCAmelCase     :     List[str]								=							get_distrib(node.right				)

    lowerCAmelCase     :     Union[str, Any]								=							1 - left_distrib_excess
    lowerCAmelCase     :     List[Any]								=							1 - right_distrib_excess

    lowerCAmelCase     :     int								=							(
        left_distrib_moves
        + right_distrib_moves
        + abs(SCREAMING_SNAKE_CASE				)
        + abs(SCREAMING_SNAKE_CASE				)
    )
    lowerCAmelCase     :     int								=							node.data - coins_to_left - coins_to_right

    return CoinsDistribResult(SCREAMING_SNAKE_CASE				,      SCREAMING_SNAKE_CASE				)

  return get_distrib(SCREAMING_SNAKE_CASE				)[0]


if __name__ == "__main__":
     import doctest

     doctest.testmod()





