# 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: introductory

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 +.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

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):
    return 1 + (n > 1) + sum(2 - (k == n // k) for k in range(2, int(n**0.5) + 1) if n % k == 0)


div = lambda x:len(set(sum([[i,x//i] for i in range(2,int(x**.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**.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:   # candidat est un diviseur de nombre
                diviseurs.append(candidat)
                diviseurs.append(nombre // candidat)
            candidat += 1
        if candidat * candidat == nombre: # nombre est un carré
            diviseurs.append(candidat)
        if precedente < len(diviseurs):
            number = nombre
            precedente = len(diviseurs)
    return number