"""One solution. Try the exercise first."""

DIGIT_WORDS = {"zero": "0", "oh": "0", "o": "0", "one": "1", "two": "2", "three": "3", "four": "4",
               "five": "5", "six": "6", "seven": "7", "eight": "8", "nine": "9"}


def basic(text: str) -> list[str]:
    text = text.lower().replace("-", " ")
    text = "".join(ch if ch.isalnum() or ch in " '" else " " for ch in text)
    return text.split()


def digit_runs(text: str) -> list[str]:
    runs, current = [], ""
    for token in basic(text):
        if token.isdigit():
            current += token
        elif token in DIGIT_WORDS:
            current += DIGIT_WORDS[token]
        else:
            if current:
                runs.append(current)
            current = ""
    return runs + ([current] if current else [])


def entity_correct(kind: str, expected: str, transcript: str) -> bool:
    if kind == "digits":
        return expected in digit_runs(transcript)
    words = " ".join(basic(expected))
    return f" {words} " in f" {' '.join(basic(transcript))} "


def entity_accuracy(items: list[tuple[str, str, str]]) -> float:
    if not items:
        return 0.0
    return sum(entity_correct(*item) for item in items) / len(items)
