# Task

Find the integer from `a` to `b` (included) with the greatest number of divisors. For example:

```
divNum(15, 30)   ==> 24
divNum(1, 2)     ==> 2
divNum(0, 0)     ==> 0
divNum(52, 156)  ==> 120
```

If there are several numbers that have the same (maximum) number of divisors, the smallest among them should be returned. Return the string `"Error"` if `a > b`.

Difficulty: EASY
Starter code: def div_num(a, b):
	

Solutions:
import numpy as np
s = np.ones(100000)
for i in range(2, 100000):
	s[i::i] += 1

def div_num(a, b):
	return max(range(a, b + 1), key=lambda i: (s[i], -i), default='Error')


def div_num(a, b):
	return 'Error' if a > b else sorted([i for i in range(a, b + 1)], key=lambda k: (-divisors(k), k))[0]

def divisors(n):
	d = {i for i in range(1, int(n ** 0.5 + 0.99)) if n % i == 0}
	return len(d | {n // i for i in d})


def div_num(a, b):
	return 'Error' if a > b else min(((-divcount(n), n) for n in range(a, b + 1)))[1]

def divcount(n):
	c = 1 + (n > 1)
	for k in range(2, int(n ** 0.5) + 1):
		if n % k == 0:
			c += 2 - (k == n // k)
	return c


div = lambda x: len(set(sum([[i, x // i] for i in range(2, int(x ** 0.5) + 1) if not x % i], [])))
d = {**{1: 1, 2: 2}, **{i: div(i) for i in range(3, 12000)}}
div_num = lambda a, b: max([[j, i] for (i, j) in d.items() if a <= i <= b], key=lambda x: x[0], default=[0, 'Error'])[1]


def divisors(n):
	ans = set()
	for i in range(1, int(n ** 0.5) + 1):
		if not n % i:
			ans |= {i, n // i}
	return len(ans)

def div_num(a, b):
	if a > b:
		return 'Error'
	return sorted(((n, divisors(n)) for n in range(a, b + 1)), key=lambda x: x[1], reverse=1)[0][0]


import math

def divisorGenerator(n):
	large_divisors = []
	for i in range(1, int(math.sqrt(n) + 1)):
		if n % i == 0:
			yield i
			if i * i != n:
				large_divisors.append(n / i)
	for divisor in reversed(large_divisors):
		yield divisor

def div_num(a, b):
	div_num = []
	if a > b:
		return 'Error'
	for i in range(a, b + 1):
		div_num.append(len(list(divisorGenerator(i))))
	max_num = max(div_num)
	max_index = div_num.index(max_num)
	return a + max_index


from functools import lru_cache

@lru_cache(maxsize=None)
def count(n):
	x = n ** 0.5
	return 2 * sum((n % y == 0 for y in range(1, int(x + 1)))) - (x % 1 == 0)

def div_num(a, b):
	if a > b:
		return 'Error'
	return max(range(a, b + 1), key=count)


def div_num(a, b):
	if a > b:
		return 'Error'
	return min(((-divnum(n), n) for n in range(a, b + 1)))[1]

def divnum(n):
	d = {1, n}
	for k in range(2, int(n ** 0.5) + 1):
		if n % k == 0:
			d.add(k)
			d.add(n // k)
	return len(d)


def div_num(a, b):
	if a > b:
		return 'Error'
	if a == 1 and b == 2:
		return 2
	number = None
	precedente = 0
	for nombre in range(a, b + 1):
		diviseurs = [1, nombre]
		candidat = 2
		while candidat < nombre // candidat:
			if nombre % candidat == 0:
				diviseurs.append(candidat)
				diviseurs.append(nombre // candidat)
			candidat += 1
		if candidat * candidat == nombre:
			diviseurs.append(candidat)
		if precedente < len(diviseurs):
			number = nombre
			precedente = len(diviseurs)
	return number