miércoles, 13 de enero de 2010

Explorando Divisores Potentes con Python

A través de los compartidos de Jose Antonio Prado Bassas me encontré ayer con este curioso reto del blog Espejo Lúdico en el que juega con los divisores propios de un número.

Los divisores propios de un número son sus divisores menos el propio número. Así, por ejemplo, los divisores propios de 12 son 1, 2, 3, 4 y 6. Pues bien, si tomamos los divisores propios de 24: 1, 2, 3, 4, 6, 8 y 12 y los multiplicamos

1 * 2 * 3 * 4 * 6 * 8 * 12 = 13824

obtenemos 13824, que es potencia del propio 24 (en concreto, 24 al cubo). El post planteaba el siguiente reto
hay hasta seis números más de dos cifras con esa propiedad (por supuesto el exponente no tiene por qué ser un cubo). ¿Sabrías descubrirlos?
Bueno. Aquí hay un problemilla para explorar con Python. Primero cree una función que devuelve una lista de los divisores propios de un número
def divisoresPropios(n):
lista=[]
for i in range(1,(n/2)+1):
if (n%i)==0:
lista.append(i)
return lista

>>> divisoresPropios(6)
[1, 2, 3]
>>> divisoresPropios(12)
[1, 2, 3, 4, 6]
>>> divisoresPropios(15)
[1, 3, 5]
>>> divisoresPropios(24)
[1, 2, 3, 4, 6, 8, 12]
Parece que funciona. Ahora transformamos un poco la función anterior para que en vez de devolver una lista de los divisores propios los vaya multiplicando y devuelva el resultado
def mulDivisoresPropios(n):
res=1
for i in range(1,(n/2)+1):
if (n%i)==0:
res*=i
return res

>>> mulDivisoresPropios(6)
6
>>> mulDivisoresPropios(12)
144
>>> mulDivisoresPropios(15)
15
>>> mulDivisoresPropios(24)
13824
Ya casi está. Definimos una función que toma un número y el múltiplo de sus divisores propios, y busca si se da algún caso en el que el número elevado a alguna potencia sea igual al múltiplo antes calculado.
def esDivisorPotente(num,mul):
for potencia in range(2,num):
res=pow(num,potencia)
if res==mul:
print num,'^',potencia,'=',res,
return True
if res>mul:
return False
Veamos cuales son los números de dos cifras que cumplen esta condición
>>> for i in range(1,101):
if esDivisorPotente(i,mulDivisoresPropios(i)):
print

12 ^ 2 = 144
18 ^ 2 = 324
20 ^ 2 = 400
24 ^ 3 = 13824
28 ^ 2 = 784
30 ^ 3 = 27000
32 ^ 2 = 1024
40 ^ 3 = 64000
42 ^ 3 = 74088
44 ^ 2 = 1936
45 ^ 2 = 2025
48 ^ 4 = 5308416
50 ^ 2 = 2500
52 ^ 2 = 2704
54 ^ 3 = 157464
56 ^ 3 = 175616
60 ^ 5 = 777600000
63 ^ 2 = 3969
66 ^ 3 = 287496
68 ^ 2 = 4624
70 ^ 3 = 343000
72 ^ 5 = 1934917632
75 ^ 2 = 5625
76 ^ 2 = 5776
78 ^ 3 = 474552
80 ^ 4 = 40960000
84 ^ 5 = 4182119424
88 ^ 3 = 681472
90 ^ 5 = 5904900000
92 ^ 2 = 8464
96 ^ 5 = 8153726976
98 ^ 2 = 9604
99 ^ 2 = 9801
Ummm, salen más de 6. Ahora podemos adornar un poco más la cosa:
for i in range(90,101):
if esDivisorPotente(i,mulDivisoresPropios(i)):
lista=divisoresPropios(i)
print ' = ',
for i in range(len(lista)-1):
print lista[i],'*',
print lista[len(lista)-1]

90 ^ 5 = 5904900000 = 1 * 2 * 3 * 5 * 6 * 9 * 10 * 15 * 18 * 30 * 45
92 ^ 2 = 8464 = 1 * 2 * 4 * 23 * 46
96 ^ 5 = 8153726976 = 1 * 2 * 3 * 4 * 6 * 8 * 12 * 16 * 24 * 32 * 48
98 ^ 2 = 9604 = 1 * 2 * 7 * 14 * 49
99 ^ 2 = 9801 = 1 * 3 * 9 * 11 * 33
De hecho estos números no parecen escasear, así por ejemplo en el entorno al millón tenemos muchos números que cumplen con la condición
1000076 ^ 23 = 1001749462105722003405829447631732777649010002466398328988709223525747312767402349848863851215950119508215957162865997753165741643557502976  =  1 * 2 * 4 * 7 * 11 * 14 * 17 * 22 * 28 * 34 * 44 * 68 * 77 * 119 * 154 * 187 * 191 * 238 * 308 * 374 * 382 * 476 * 748 * 764 * 1309 * 1337 * 2101 * 2618 * 2674 * 3247 * 4202 * 5236 * 5348 * 6494 * 8404 * 12988 * 14707 * 22729 * 29414 * 35717 * 45458 * 58828 * 71434 * 90916 * 142868 * 250019 * 500038





Fuente: Espejo Lúdico a través de los compartidos de Jose Antonio Prado Bassas. Como siempre, gracias por venir. Si te gustó el post puedes apuntarte a través del correo electrónico o por medio del feed RSS (más información acerca del RSS). También puedes seguirme a través de mis elementos compartidos, y a partir de ahora desde Twitter o Friendfeed.

6 comentarios:

javcasta dijo...

Este post seguro que le interesa a Gaussianos

Wan Link Sniper dijo...

Buena página esa. Pero vamos, que esto es un divertimento menor, pura fuerza bruta que no demuestra matemáticamente nada :-)

Alfredo dijo...

No hace falta demostrar "matemáticamente" nada para epatar, está visto...La modestia también viste mucho. Ah...

Wan Link Sniper dijo...

amen

Wan Link Sniper dijo...

En efecto, un anónimo lectorde Espejo Lúdico nos explica lo que ocurre con estos divisores potentes

"Es que ocurre siempre. Los divisores de un número vienen siempre por pares, por lo que siempre ocurre esto. De hecho, basta con contar cuántos pares de divisores tiene un número: el producto de todos ellos será esa potencia del número original.

Por ejemplo, en el caso de 24, hay tres pares de divisores propios: 2·12, 3·8 y 4·6. Por eso, el producto de todos ellos es igual a 24³.

La gran excepción son los números que son cuadrados. Por ejemplo, 36 = 2·18 = 3·12 = 4·9 = 6·6. Cuando calculamos el producto de todos ellos, sólo podemos tomar una vez el 6."

Donde haya un bit de lógica que se quite un megabyte de fuerza bruta ;-)

refranero español dijo...

Más vale maña que fuerza