We all know about Roman Numerals, and if not, here's a nice [introduction kata](http://www.codewars.com/kata/5580d8dc8e4ee9ffcb000050). And if you were anything like me, you 'knew' that the numerals were not used for zeroes or fractions; but not so!

I learned something new today: the [Romans did use fractions](https://en.wikipedia.org/wiki/Roman_numerals#Special_values) and there was even a glyph used to indicate zero.

So in this kata, we will be implementing Roman numerals and fractions.

Although the Romans used base 10 for their counting of units, they used base 12 for their fractions. The system used dots to represent twelfths, and an `S` to represent a half like so:

* ^(1)/12 = `.`
* ^(2)/12 = `:`
* ^(3)/12 = `:.`
* ^(4)/12 = `::`
* ^(5)/12 = `:.:`
* ^(6)/12 = `S`
* ^(7)/12 = `S.`
* ^(8)/12 = `S:`
* ^(9)/12 = `S:.`
* ^(10)/12 = `S::`
* ^(11)/12 = `S:.:`
* ^(12)/12 = `I` (as usual)

Further, zero was represented by `N`

## Kata

Complete the method that takes two parameters: an integer component in the range 0 to 5000 inclusive, and an optional fractional component in the range 0 to 11 inclusive.

You must return a string with the encoded value. Any input values outside the ranges given above should return `"NaR"` (i.e. "Not a Roman" :-)

## Examples

```python
roman_fractions(-12)     #=> "NaR"
roman_fractions(0, -1)   #=> "NaR"
roman_fractions(0, 12)   #=> "NaR"
roman_fractions(0)       #=> "N"
roman_fractions(0, 3)    #=> ":."
roman_fractions(1)       #=> "I"
roman_fractions(1, 0)    #=> "I"
roman_fractions(1, 5)    #=> "I:.:"
roman_fractions(1, 9)    #=> "IS:."
roman_fractions(1632, 2) #=> "MDCXXXII:"
roman_fractions(5000)    #=> "MMMMM"
roman_fractions(5001)    #=> "NaR"
```

Difficulty: introductory

Starter code:

def roman_fractions(integer, fraction=None):
	

Solutions:
FRACTIONS = " . : :. :: :.: S S. S: S:. S:: S:.:".split(" ")
UNITS     = " I II III IV V VI VII VIII IX"      .split(" ")
TENS      = " X XX XXX XL L LX LXX LXXX XC"      .split(" ")
HUNDREDS  = " C CC CCC CD D DC DCC DCCC CM"      .split(" ")
THOUSANDS = " M MM MMM MMMM MMMMM"               .split(" ")    


def roman_fractions(n, f=0):
    return ( "NaR"  if n < 0 or n > 5000 or f < 0 or f > 11
                    else "N" if n + f == 0
                    else  THOUSANDS [n//1000]
                        + HUNDREDS  [n%1000//100]
                        + TENS      [n%100//10]
                        + UNITS     [n%10]
                        + FRACTIONS [f] )

def roman_fractions(num, fraction=0):
    rom = ''
    FACT = { 1:'.', 2:':', 3:':.',4:'::',5:':.:',6:'S',7:'S.',8:'S:', 9:'S:.',10:'S::', 11:'S:.:' }
    ENCO = { 1:'I',  5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M' }
    EDGE = {
         0:lambda x, elem,  dict, number : dict.get(elem, '') * number, 
         1:lambda e, i, D, l : e +D.get(i*(l+1),'M'*(l-1)) if l in [4,9] else D.get(i*l, 'M'*5) if l is 5 else D[i*5] + (e * (l%5))
           }
    if num < 0 or num>5000 or fraction and fraction not in FACT:
        return 'NaR' 
        
    for element in list(ENCO.keys())[0::2][::-1]:
        left = num // element
        rom += EDGE.get(left>3, '')( ENCO[element] , element, ENCO, left )
        num %= element
    
    ret = rom + FACT.get(fraction,'') 

    return  ret if ret else 'N'


TOME = dict(zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1), 'M CM D CD C XC L XL X IX V IV I'.split()))
FRAC = dict(enumerate((".",":",":.","::",":.:","S","S.","S:","S:.","S::","S:.:"),1))

def roman_fractions(i, f=0):
    if i<0 or f<0 or f==12 or i>5000: return "NaR"
    lst = []
    for v,r in TOME.items():
        n,i = divmod(i,v)
        if n: lst.extend([r]*n)
    if f: lst.append(FRAC[f])
    return ''.join(lst) or 'N'

from enum import Enum
from collections import Counter
from itertools import chain
from operator import itemgetter, attrgetter

def roman_fractions (integer, fraction=0):
    if not (0 <= integer <= 5000 and 0 <= fraction < 12):
        return 'NaR'
    if integer == 0 and fraction == 0:
        return 'N'
    
    class Rom (Enum):
        I = 1
        V = 5
        X = 10
        L = 50
        C = 100
        D = 500
        M = 1000
    
    def paired_romans ():
        negatives = Counter({Rom.I: 2, Rom.X: 2, Rom.C: 2})
        for digit, prefix in zip(Rom, chain([None], negatives.elements())):
            yield (digit,), digit.value
            if prefix:
                yield (prefix, digit), digit.value - prefix.value

    def greedy_collect (iter_symbols, total):
        symbols = []
        symbol, value = next(iter_symbols)
        while total:
            if total >= value:
                total -= value
                symbols.extend(symbol)
            else:
                symbol, value = next(iter_symbols)
        return symbols

    extended_romans = iter(sorted(paired_romans(), key=itemgetter(1), reverse=True))
    symbols = greedy_collect(extended_romans, integer)
    integer_part = ''.join(symbol.name for symbol in symbols)
    
    fractions = iter(list({'S': 6, ':.:': 5, ':': 2, '.': 1}.items()))
    symbols = greedy_collect(fractions, fraction)
    fractional_part = ''.join(symbols)
    
    return integer_part + fractional_part
    
    


def roman_fractions(integer, fraction=0):
    if not 0 <= integer <= 5000 or not 0 <= fraction < 12:
        return "NaR"
    if not integer and not fraction: return "N"
    m, n = divmod(integer, 1000)
    roman = "M" * m
    c, n = divmod(n, 100)
    roman += ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"][c]
    x, i = divmod(n, 10)
    roman += ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"][x]
    roman += ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"][i]
    roman += ["", ".", ":", ":.", "::", ":.:", "S", "S.", "S:", "S:.", "S::", "S:.:"][fraction]
    return roman

def roman_fractions(n, f=0):
    
    if n < 0 or n > 5000 or f < 0 or f > 11: return 'NaR'
    if n + f == 0: return 'N'
    
    s = ''
    for r, d in zip('M CM D CD C XC L XL X IX V IV I'.split(), [1000,900,500,400,100,90,50,40,10,9,5,4,1]):
        appearances = n // d
        s, n = s + r * appearances, n - appearances * d

    return s + ([''] + '. : :. :: :.: S S. S: S:. S:: S:.:'.split())[f]

dictio = {1:".",2:":",3:":.",4:"::",5:":.:"}
def roman_fractions(integer, fraction=None):
    if integer < 0  or integer > 5000 or fraction and (fraction<0 or fraction>11):
        return "NaR"
    if integer == 0 and not fraction : return "N"
    return encoder(integer) + dictio.get(fraction,"S"+dictio.get(fraction-6,"")) if fraction else encoder(integer)
    
def encoder(n):
    num = "M CM D CD C XC L XL X IX V IV I".split()
    ls = [1000,900,500,400,100,90,50,40,10,9,5,4,1]
    s = ""
    for i,j in enumerate(num):
        while n >= ls[i]:
            s += j
            n -= ls[i]
    return s  

def roman_fractions(integer, fraction=0):
    fracs=['.',':',':.','::',':.:','S','S.','S:','S:.','S::','S:.:']
    res='NaR'
    if(integer>=0 and integer<=5000 and fraction>=0 and fraction<=11):
        print(integer,fraction)
        res=''
        if(integer==0 and fraction==0):
            return 'N'
        while(integer>0):
            if(integer>=1000):
                res+='M'
                integer-=1000
            elif(integer>=900):
                res+='CM'
                integer-=900
            elif(integer>=500):
                res+='D'
                integer-=500
            elif(integer>=400):
                res+='CD'
                integer-=400
            elif(integer>=100):
                res+='C'
                integer-=100
            elif(integer>=90):
                res+='XC'
                integer-=90
            elif(integer>=50):
                res+='L'
                integer-=50
            elif(integer>=40):
                res+='XL'
                integer-=40
            elif(integer>=10):
                res+='X'
                integer-=10
            elif(integer>=9):
                res+='IX'
                integer-=9
            elif(integer>=5):
                res+='V'
                integer-=5
            elif(integer>=4):
                res+='IV'
                integer-=4
            elif(integer>=1):
                res+='I'
                integer-=1
        '''
        while(fraction>0):
            if(fraction>=6):
                res+='S'
                fraction-=6
            elif(fraction>=2):
                res+=':'
                fraction-=2
            elif(fraction>=1):
                res+='.'
                fraction-=1
        '''
        if(fraction>0):
            res+=fracs[fraction-1]
    return res

ROMANS = {'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1}
s_numbers = {'CM': 900, 'CD': 400, 'XC': 90, 'XL': 40, 'IX': 9, 'IV': 4}
ROMANS.update(s_numbers)
ROMANS = {v:k for k, v in ROMANS.items()}

lst = ['', '.', ':', ':.', '::', ':.:', 'S', 'S.', 'S:', 'S:.', 'S::', 'S:.:']


def roman_fractions(integer, fraction=None):
    if integer == 0 and fraction in [None, 0]:
        return 'N'
    if integer < 0 or integer > 5000 or (integer == 0 and (fraction >= 12 or fraction < 0)):
        return "NaR"
    if fraction != None:
        if fraction < 0 or fraction >= 12:
            return "NaR"
    roman = ''
    for a in reversed(sorted(ROMANS.keys())):
        while (a <= integer):
            integer = integer - a;
            roman = roman + ROMANS[a]
    return roman + lst[fraction] if fraction != None else roman