Functions¶

In [1]:
def romanCode(i) :
    """
    Determine possibilities for a string of 'I's.

    Parameters:
    i - Number of 'I's.
    
    Returns:
    Set of possibilities, where each possibility is a set.
    """
    
    #Nothing left!
    if i == 0 :
        return([[]])
    
    #Ends in I.
    elif i == 1 :
        return([[1]])
    
    #Ends in II.    
    elif i == 2 :
        return([[1, 1], [2]])
    
    #Ends in III.
    elif i == 3 :
        return([[1, 1, 1], [1, 2], [2, 1], [3]])
    
    #RECURSIVE!
    #If ending in IIII or more, 1, 2, or 3 could be the next digit before looking at the remaining right numerals.
    else :
        P = []
        
        #..., 1, ...
        for j in romanCode(i-1) :
            P.append([1]+j)
            
        #..., 2, ...
        for l in romanCode(i-2) :
            P.append([2]+l)
        
        #..., 3, ...
        for k in romanCode(i-3) :
            P.append([3]+k)
            
        return(P)

    
    
    
    
    
    
def romanCodeEC(S) :
    """
    Determine possibilities for string of 'I's and 'V's.

    Parameters:
    i - Number of 'I's.
    
    Returns:
    Set of possibilities, where each possibility is a set.
    """
    
    #Nothing left!    
    if S == '' :
        return([[]])

    #Ends in I.    
    elif S == 'I' :
        return([[1]])

    #Ends in II.    
    elif S == 'II' :
        return([[1, 1],
                [2]])

    #Ends in III.    
    elif S == 'III' :
        return([[1, 1, 1], [1, 2],
                [2, 1],
                [3]])

    #Ends in IV.    
    elif S == 'IV' :
        return([[1, 5], [4]])    
    
    #Ends in V.    
    elif S == 'V' :
        return([[5]])

    #Ends in VI.    
    elif S == 'VI' :
        return([[5, 1],
                [6]])

    #Ends in VII.    
    elif S == 'VII' :
        return([[5, 1, 1], [5, 2],
                [6, 1],
                [7]])

    elif S == 'VIII' :
        return([[5, 1, 1, 1], [5, 1, 2], [5, 2, 1], [5, 3],
                [6, 1, 1], [6, 2],
                [7, 1],
                [8]])
               
    #RECURSIVE!
    #If ending in IIII or more, 1, 2, or 3 could be the next digit before looking at the remaining right numerals.    
    else :
        P = []

        #..., 1, ...
        if S[0] == 'I' :
            for j in romanCodeEC(S[1:]) :
                P.append([1] + j)

        #..., 2, ...
        if S[0:2] == 'II' :
            for j in romanCodeEC(S[2:]) :
                P.append([2] + j)

        #..., 3, ...
        if S[0:3] == 'III' :
            for j in romanCodeEC(S[3:]) :
                P.append([3] + j)
                
        #..., 4, ...
        if S[0:2] == 'IV' :
            for j in romanCodeEC(S[2:]) :
                P.append([4] + j)                

        #..., 5, ...
        if S[0] == 'V' :
            for j in romanCodeEC(S[1:]) :
                P.append([5] + j)

        #..., 6, ...
        if S[0:2] == 'VI' :
            for j in romanCodeEC(S[2:]) :
                P.append([6] + j)

        #..., 7, ...
        if S[0:3] == 'VII' :
            for j in romanCodeEC(S[3:]) :
                P.append([7] + j)

        #..., 8, ...
        if S[0:4] == 'VIII' :
            for j in romanCodeEC(S[4:]) :
                P.append([8] + j)
                
        return(P)
    

def createDist(L) :
    """
    Create distribution frequency

    Parameters:
    L - List of lists.
    
    Returns:
    Dictionary with keys that are length, frequency is values.
    """
    dist = {}
    for l in L :
        n = len(l)
        if n in dist.keys() :
            dist[n] += 1
        else :
            dist[n] = 1
    return(dist)
In [2]:
createDist(romanCode(10))
Out[2]:
{10: 1, 9: 9, 8: 36, 7: 77, 6: 90, 5: 51, 4: 10}
In [3]:
len(romanCode(10))
Out[3]:
274
In [4]:
createDist(romanCodeEC('IIIVIIIVIIIVIII'))
Out[4]:
{15: 1,
 14: 14,
 13: 85,
 12: 295,
 11: 650,
 10: 955,
 9: 955,
 8: 650,
 7: 295,
 6: 85,
 5: 14,
 4: 1}

Fiddler¶

In [5]:
len(romanCodeEC('IIIVIIIVIIIVIII'))
Out[5]:
4000
In [6]:
for code in ['IVI', 'IVIVI', 'IVIVIVI', 'IVIVIVIVI',
             'IVVI', 'IVVIVVI', 'IVVIVVIVVI', 'IVVIVVIVVIVVI',
             'IIVII', 'IIVIIVII', 'IIVIIVIIVII', 'IIVIIVIIVIIVII',
             'IIVVII', 'IIVVIIVVII', 'IIVVIIVVIIVVII', 'IIVVIIVVIIVVIIVVII', 
             'IIIVIII', 'IIIVIIIVIII', 'IIIVIIIVIIIVIII', 'IIIVIIIVIIIVIIIVIII'] :
    print('<b>' + code + '</b> has ' + str(len(romanCodeEC(code))) + ' combinations.')
<b>IVI</b> has 3 combinations.
<b>IVIVI</b> has 8 combinations.
<b>IVIVIVI</b> has 21 combinations.
<b>IVIVIVIVI</b> has 55 combinations.
<b>IVVI</b> has 4 combinations.
<b>IVVIVVI</b> has 12 combinations.
<b>IVVIVVIVVI</b> has 36 combinations.
<b>IVVIVVIVVIVVI</b> has 108 combinations.
<b>IIVII</b> has 10 combinations.
<b>IIVIIVII</b> has 50 combinations.
<b>IIVIIVIIVII</b> has 250 combinations.
<b>IIVIIVIIVIIVII</b> has 1250 combinations.
<b>IIVVII</b> has 12 combinations.
<b>IIVVIIVVII</b> has 72 combinations.
<b>IIVVIIVVIIVVII</b> has 432 combinations.
<b>IIVVIIVVIIVVIIVVII</b> has 2592 combinations.
<b>IIIVIII</b> has 40 combinations.
<b>IIIVIIIVIII</b> has 400 combinations.
<b>IIIVIIIVIIIVIII</b> has 4000 combinations.
<b>IIIVIIIVIIIVIIIVIII</b> has 40000 combinations.
Rohan Lewis¶

2025.06.27¶