Ho ho! So you think you know integers, do you? Well then, young wizard, tell us what the Nth digit of the [Champernowne constant](https://en.wikipedia.org/wiki/Champernowne_constant) is!

The constant proceeds like this: `0.12345678910111213141516...`

I hope you see the pattern!

Conjure a function that will accept an integer, `n`, and return the (one-indexed) `n`th digit of Champernowne's constant. Can you get it to run in _constant_ time?

For example:

`n = 1` should return `0` (the very first digit)

`n = 2` should return `1` (we ignore the period character since it's not a digit!)

`n = 20` should return `4` (that's the `4` in the number `14`, 20th in sequence)

For any invalid values, such as `0` and below, or non-integers, return... `NaN`!

I hope (for your sake) that you've been practicing your mathemagical spells, because a naïve solution will _not_ be fast enough to compete in this championship!

Invoke with _precision_, and be wary of rounding errors in the realms of enormity!

May the best integer win!

Source: codewars | Difficulty: EASY
Tags: Mathematics

Starter code: def champernowneDigit(n):
	

Solutions:
def champernowne_digit(n):
	if not type(n) is int or n < 1:
		return float('NaN')
	(i, l) = (1, 11)
	while l <= n:
		(i, l) = (i + 1, l + 9 * (i + 1) * 10 ** i)
	return (n - l) // (i * 10 ** (i - 1 - (n - l) % i)) % 10
champernowneDigit = champernowne_digit


DIGIT_CNTS = [1] + [(10 ** i - 10 ** (i - 1)) * i for i in range(1, 20)]

def champernowneDigit(n):
	if not isinstance(n, int) or n is True or n <= 0:
		return float('nan')
	n -= 1
	for (digits, cnt) in enumerate(DIGIT_CNTS):
		if n < cnt:
			break
		n -= cnt
	start = int(10 ** (digits - 1))
	(q, r) = divmod(n, digits) if digits > 1 else (n, 0)
	return int(str(start + q)[r])


def champernowneDigit(n):
	if not isinstance(n, int) or isinstance(n, bool) or n <= 0:
		return float('nan')
	elif n <= 10:
		return n - 1
	nr_digits = 1
	mag_len = 10
	while n > mag_len:
		n -= mag_len
		nr_digits += 1
		mag_len = nr_digits * (10 ** nr_digits - 10 ** (nr_digits - 1))
		print(n, nr_digits, mag_len)
	(quoitent, reminder) = divmod(n - 1, nr_digits)
	print(quoitent, reminder)
	return int(str(quoitent + 10 ** (nr_digits - 1))[reminder])


def champernowneDigit(n):
	result = float('NaN')
	if type(n) == int and n > 0:
		if n <= 10:
			result = n - 1
		else:
			i = 1
			c = 10
			while n > c:
				i += 1
				c = c + i * 9 * 10 ** (i - 1)
			number = (n - c) // i + 10 ** i - 1
			reste = (n - c) % i
			if reste:
				number += 1
			result = int(str(number)[reste - 1])
	return result


from math import floor

def champernowneDigit(n):
	print(n)
	if n == None or isinstance(n, bool) or (not isinstance(n, int)) or (n < 1):
		return float('nan')
	(t, c) = (10, 1)
	while t < n:
		c += 1
		t += 9 * 10 ** (c - 1) * c
	num = str(10 ** c - 1 - floor((t - n) / c))
	return int(num[c - 1 - (t - n) % c])


def champernowneDigit(n):
	if not n or type(n) != int or n < 0:
		return float('nan')
	if n <= 10:
		return n - 1
	digs = 1
	tot = 1
	while 1:
		if tot + digs * 9 * 10 ** (digs - 1) >= n:
			break
		tot += digs * 9 * 10 ** (digs - 1)
		digs += 1
	number = (n - tot - 1) // digs + 10 ** (digs - 1)
	return int(str(number)[(n - tot - 1) % digs])


def champernowneDigit(n):
	if not isinstance(n, int) or isinstance(n, bool) or n < 1:
		return float('nan')
	n -= 1
	sc = [9 * (x + 1) * pow(10, x) for x in range(50)]
	i = 0
	while n > sc[i]:
		n -= sc[i]
		i += 1
	(L, d) = divmod(n - 1, i + 1)
	return int(str(pow(10, i) + L)[d])


g1 = lambda n: (9 * (n + 1) * 10 ** n - 10 ** (n + 1) + 1) // 9
g2 = lambda n: int(''.join((str(n - 1), '8' * (n - 1), '9')))
L = [g1(x) for x in range(1, 1000)]

def champernowneDigit(n):
	if not (type(n) == int and 0 < n):
		return float('nan')
	if n == 1:
		return 0
	n -= 1
	x = next((i for (i, v) in enumerate(L, 1) if v > n))
	(q, r) = divmod(L[x - 1] - n, x)
	return int(str(10 ** x - 1 - q)[-r - 1])


def champernowneDigit(n):
	if not n or not type(n) == int or n < 1:
		return float('nan')
	(dig, i) = (10, 1)
	while dig < n:
		i += 1
		dig += 9 * 10 ** (i - 1) * i
	num = str(10 ** i - 1 - (dig - n) // i)
	return int(num[-1 - (dig - n) % i])