from collections import Counter
from typing import Callable
from typing import List


def generate_tuples(generator: Callable, observation_n: int) -> List:
    """ Given a function that generates repeat lengths (e.g. a model's sample function), repeat this process
    observation_n times and transform all resulting runs into the tuple representation.

    :param generator: Function that generates a collection of repeat lengths.
    :param observation_n: Number of times to run generator for.
    :return: 2D list of (int, float) tuples representing the (repeat length, frequency) tuples.
    """

    to_tuples = lambda a: [(b[0], b[1] / len(a)) for b in Counter(a).items()]
    return [to_tuples(generator()) for _ in range(observation_n)]