def get_best_hands_generic(hand_strength_function, board, hands):
    """ get the index of the best omaha hand given a board

    :param hand_strength_function: (function)
        inputs (board, hand), outputs (tuple)
    :param board: ([str]) list of 5 cards
    :param hands: ([set(str)]) list of sets of 4 cards
    :return: ([[int]]) indices of `hands` that makes the strongest omaha hand
        --> this is a list of lists because it is possible to "chop" with
            every hand rank except straight flushes, quads and flushes
    """
    hand_strengths = {}
    for ii, hand in enumerate(hands):
        hand_strength = hand_strength_function(board, hand)
        if hand_strength not in hand_strengths:
            hand_strengths[hand_strength] = []
        hand_strengths[hand_strength].append(ii)

    return [
        hand_strengths[hs]
        for hs in sorted(hand_strengths, reverse=True)
    ]