def assign_letter_codes(codes, code_numbers, unrhymed_verses, offset=None):
    """Adjust for unrhymed verses and assign letter codes.
    By default, all verses are checked, that means that a poem might match
    lines 1 and 100 if the ending is the same. To control how many lines
    should a matching rhyme occur in, an offset can be set to an arbitrary
    number, effectively allowing rhymes that only occur between
    lines i and i + offset."""
    letters = {}
    rhymes = []
    endings = []
    last_found = {}
    for index, rhyme in enumerate(code_numbers):
        if rhyme in unrhymed_verses:
            rhyme_letter = -1
            endings.append('')
        else:
            if rhyme not in letters:
                letters[rhyme] = len(letters)
            rhyme_letter = letters[rhyme]
            if (rhyme in last_found and offset is not None and index -
                last_found[rhyme] > offset):
                rhymes[last_found[rhyme]] = -1
                endings[last_found[rhyme]] = ''
            last_found[rhyme] = index
            endings.append(codes[rhyme])
        rhymes.append(rhyme_letter)
    return rhymes, endings
