"""One solution to shortcuts_practice.py. Try it yourself first."""
import math


def cosine(a: list[float], b: list[float]) -> float:
    dot = sum(x * y for x, y in zip(a, b))
    return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))


def cache_reuses(ok: list[bool], sims: list[float], cutoff: float) -> dict:
    reused = [good for good, s in zip(ok, sims) if s >= cutoff]
    return {"good": sum(reused), "wrong": len(reused) - sum(reused)}


def confidence(logprob: float) -> float:
    return math.exp(logprob)


def cascade(tickets: list[dict], cutoff: float) -> dict:
    right = sent_up = 0
    cost = 0.0
    for t in tickets:
        cost += t["small"]["cost"]
        use = t["small"]
        if t["small"]["confidence"] < cutoff:
            sent_up += 1
            cost += t["big"]["cost"]  # both calls are paid for
            use = t["big"]
        right += use["answer"] == t["priority"]
    return {"right": right, "sent_up": sent_up, "cost": cost}


def choose_cutoff(dev: list[dict], candidates: list[float]) -> float:
    target = sum(t["big"]["answer"] == t["priority"] for t in dev)
    for c in sorted(candidates):
        if cascade(dev, c)["right"] >= target:
            return c
    return max(candidates)
