def match_signature(args, signatures, strict=False):
    """
    Dynamically match arguments to the corresponding types signature.

    Return matching types signature from `signatures` to the
    given types of arguments from `args` by inspecting their types
    dynamically, or None if no match.

    :param `args`: Sequence of function arguments.
    :type `args`: Sequence[object]

    :param `signatures`: Sequence of type signatures.
    :type `signatures`: Sequence[Sequence[type]]

    :param `strict`: If set to False, try to keep duck-typing support
        as much as possible.
    :type `strict`: bool

    :return: matched signature
    :rtype: type
    """
    # check for duplicate signatures
    if len(set(signatures)) != len(signatures):
        raise TypeError("Duplicate signatures")

    matched_signatures = []
    # check number of arguments
    for sig in signatures:
        if len(sig) == len(args):
            matched_signatures.append(sig)

    if not matched_signatures:
        return

    if not strict and len(matched_signatures) == 1:
        return matched_signatures[0]

    signatures = matched_signatures
    # check types of arguments
    for sig in signatures:
        for arg, type_ in zip(args, sig):
            if not isinstance(arg, type_):
                break
        else:
            return sig

    if not strict:
        for sig in signatures:
            for arg, type_ in zip(args, sig):
                try:
                    type_(arg)
                except (ValueError, TypeError):
                    break
            else:
                return sig