#!/usr/bin/python3
import itertools
import math

# http://www.koders.com/python/fid45302A2EAC1605C197093DA0F34A3CC7BEAC9736.aspx?s=cdef%3Aconfig
def risingfactorial(n, m):
    """
    Return the rising factorial; n to the m rising, i.e. n(n+1)..(n+m-1).

    For example:
    >>> risingfactorial(7, 3)
    504
    """
    r = 1
    for i in range(n, n+m):
        r *= i
    return r

def gen_figurative_numbers (n):
    i=1
    while True:
        # see:
        # http://en.wikipedia.org/wiki/Triangular_number
        # http://en.wikipedia.org/wiki/Tetrahedral_number
        # http://en.wikipedia.org/wiki/Pentatope_number
        yield risingfactorial (i, n) / math.factorial(n)
        i=i+1

def get_increasing_numbers_total (digits_total):
     fig_numbers_from_1st=list(itertools.islice(gen_figurative_numbers(digits_total-1), 0, 9, 1)) # generator, start, stop, step
     return sum(fig_numbers_from_1st)

def get_decreasing_numbers_total (digits_total):
     # shifted
     fig_numbers_from_2nd=list(itertools.islice(gen_figurative_numbers(digits_total-1), 1, 10, 1)) # generator, start, stop, step
     return sum(fig_numbers_from_2nd)

def get_not_bouncy_numbers_total (digits_total):
    if digits_total==1:
        return 9
    return get_increasing_numbers_total (digits_total) + get_decreasing_numbers_total (digits_total) - 9

def get_not_bouncy_numbers_for_range (start, stop):
    return sum (map (get_not_bouncy_numbers_total, range (start, stop+1)))

print (get_not_bouncy_numbers_for_range (1, 6)) # must be 12951
print (get_not_bouncy_numbers_for_range (1, 10)) # must be 277032
print (get_not_bouncy_numbers_for_range (1, 100)) # gogool

