Many years ago, Roman numbers were defined by only `4` digits: `I, V, X, L`, which represented `1, 5, 10, 50`. These were the only digits used. The value of a sequence was simply the sum of digits in it. For instance:
```
IV = VI = 6
IX = XI = 11
XXL = LXX = XLX = 70
```
It is easy to see that this system is ambiguous, and some numbers could be written in many different ways. Your goal is to determine how many distinct integers could be represented by exactly `n` Roman digits grouped together. For instance:
```Perl
solve(1) = 4, because groups of 1 are [I, V, X, L]. 
solve(2) = 10, because the groups of 2 are [II, VI, VV, XI, XV, XX, IL, VL, XL, LL] corresponding to [2,6,10,11,15,20,51,55,60,100]. 
solve(3) = 20, because groups of 3 start with [III, IIV, IVV, ...etc]
```

`n <= 10E7`

More examples in test cases. Good luck!

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Starter code: def solve(n):
	

Solutions:
INITIAL = [0, 4, 10, 20, 35, 56, 83, 116, 155, 198, 244, 292]

def solve(n):
	return INITIAL[n] if n < 12 else 292 + 49 * (n - 11)


from functools import lru_cache
DIGITS = [1, 5, 10, 50]
THRESHOLD = 12

def solve_naive(n):
	minimal = n * min(DIGITS)
	maximal = n * max(DIGITS)
	return maximal - minimal

@lru_cache(maxsize=THRESHOLD)
def solve_brute(n):
	from itertools import product
	combinations = product(DIGITS, repeat=n)
	values = list(map(sum, combinations))
	return len(set(values))

@lru_cache(maxsize=THRESHOLD)
def determine_delta(tries):
	deltas = (solve_naive(n) - solve_brute(n) for n in range(1, tries + 1))
	return max(deltas)

def solve(n):
	if n > THRESHOLD:
		return solve_naive(n) - determine_delta(THRESHOLD)
	return solve_brute(n)


basics = [0, 4, 10, 20, 35, 56, 83, 116, 155, 198, 244, 292]

def solve(n):
	return basics[n] if n < 12 else 49 * n - 247


def solve(n):
	c = 0
	for i in range(min(8, n) + 1):
		for j in range(min(4 if i != 0 else 8, n - i) + 1):
			c += n - i - j + 1
	return c


OPTIONS = [1, 5, 10, 50]

def solve(n):
	print(n)
	base_answer = len(rec_solve(min(n, 11)))
	if n < 12:
		return base_answer
	else:
		return base_answer + 49 * (n - 11)

def rec_solve(n, options=4, val=0):
	if n == 1:
		return_set = set()
		for i in range(1, options + 1):
			return_set.add(val + OPTIONS[-i])
		return return_set
	elif options == 1:
		return {val + 50 * n}
	return_set = set()
	for option_num in range(options, 0, -1):
		return_set = return_set.union(rec_solve(n - 1, option_num, val + OPTIONS[-option_num]))
	return return_set


def solve(n):
	return 292 + (n - 11) * 49 if n > 10 else len(set((n - v - x - l + v * 5 + x * 10 + l * 50 for l in range(n + 1) for x in range(n + 1 - l) for v in range(n + 1 - l - x))))


def solve(n):
	m = {1: 4, 2: 10, 3: 20, 4: 35, 5: 56, 6: 83, 7: 116, 8: 155, 9: 198, 10: 244, 11: 292, 12: 341}
	if n <= 12:
		return m[n]
	else:
		return m[12] + 49 * (n - 12)