A `bouncy number` is a positive integer whose digits neither increase nor decrease. For example, 1235 is an increasing number, 5321 is a decreasing number, and 2351 is a bouncy number. By definition, all numbers under 100 are non-bouncy, and 101 is the first bouncy number.

Determining if a number is bouncy is easy, but counting all bouncy numbers with N digits can be challenging for large values of N. To complete this kata, you must write a function that takes a number N and return the count of bouncy numbers with N digits. For example, a "4 digit" number includes zero-padded, smaller numbers, such as 0001, 0002, up to 9999.

For clarification, the bouncy numbers between 100 and 125 are: 101, 102, 103, 104, 105, 106, 107, 108, 109, 120, and 121.

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Mathematics

Starter code: def bouncy_count(n):
	

Solutions:
def bouncy_count(m):
	num = den = 1
	for i in range(1, 11):
		num *= m + i + i * (i == 10)
		den *= i
	return 10 ** m - num // den + 10 * m + 1


def bouncy_count(n):
	k = m = 1
	for i in range(1, 11):
		k *= n + i * (1 + (i == 10))
		m *= i
	return 10 * (10 ** (n - 1) + n) - k // m + 1


from scipy.special import comb

def bouncy_count(number):
	return 10 ** number + 10 * number + 1 - comb(10 + number, 10, True) - comb(9 + number, 9, True)


import operator as op
from functools import reduce

def Combi(n, k):
	if k > n:
		return 0
	(k1, k2) = sorted((k, n - k))
	num = reduce(op.mul, range(n, k2, -1), 1)
	d = reduce(op.mul, range(1, k1 + 1), 1)
	return num // d

def bouncy_count(n):
	if n <= 2:
		return 0
	return 10 ** n - (Combi(n + 10, 10) + Combi(n + 9, 9) - 2 - 10 * n + 1)


from functools import reduce

def nCr(n, k):
	numer = reduce(lambda x, y: x * y, list(range(n, n - k, -1)))
	denom = reduce(lambda x, y: x * y, list(range(1, k + 1)))
	return numer // denom

def bouncy_count(number):
	r = int(nCr(number + 10, 10) + nCr(number + 9, 9) - 2 - 10 * number)
	return 10 ** number - r % (1000000000000000000 + 7) - 1


from math import factorial as f

def nCk(n, k):
	return f(n) // f(k) // f(n - k)

def bouncy_count(x):
	return 10 ** x - (nCk(10 + x, 10) + nCk(9 + x, 9) - 10 * x - 1)


from scipy.special import comb

def bouncy_count(n):
	return 10 ** n - comb(n + 9, n, exact=True) - comb(n + 10, n, exact=True) + 1 + n * 9 + n


from scipy.special import comb

def bouncy_count(n):
	if n < 3:
		return 0
	b = 10
	incline_sum = 0
	decline_sum = 0
	for i in range(3, n + 1):
		incline_sum += comb(b + i - 1, i, exact=True) - 10
		decline_sum += comb(b + i - 2, i, exact=True)
	return b ** n - b ** 2 - incline_sum - decline_sum