miércoles, 4 de julio de 2018

Números que contienen las cifras de sus divisores


No es infrecuente que un número expresado en un sistema de numeración (nos limitaremos a la base decimal) contenga las cifras bien ordenadas de alguno o de todos sus divisores. Por ejemplo, 1734 contiene a sus divisores 17 y 34 como  subconjuntos ordenados de cifras. Existen publicadas muchas listas, de las que veremos algunas, especialmente con números primos. Para efectuar búsquedas sería conveniente disponer de alguna función que nos devolviera si un número contiene las cifras (siempre consecutivas) de algún divisor o, mejor aún, que indicara esos divisores.

Funciones necesarias

El criterio de si las cifras de un número están contenidas dentro de otro es fundamental en esta cuestión, pero existen dos inconvenientes:

  • Los números deberán convertirse en cadenas de texto
  • El formato de hoja de cálculo puede añadir espacios en blanco delante de los números positivos.
Estos dos problemas los resuelve la función AJUSTA$, como podemos observar en su listado:

Function ajusta$(a)
Dim d$

d$ = Str$(a) ‘Convierte el número en String
While Left$(d$, 1) = " "
d$ = Right$(d$, Len(d$) - 1) ‘Le suprime los espacios en blanco
Wend
ajusta$ = d$ ‘El resultado es una cadena de caracteres
End Function

Con esta función es fácil construir otra, DENTROCIFRAS, que indique si las cifras de un número contienen a las de otro  de forma consecutiva, es decir que el segundo sea una subcadena del primero.

Public Function dentrocifras(a, b) As Boolean 'Ve si las cifras de b están en a
Dim aa$, bb$
aa$ = ajusta(a) ‘Ajusta ambos números
bb$ = ajusta(b) ‘después, con función InStr averigua si está contenido
If InStr(aa$, bb$) > 0 Then dentrocifras = True Else dentrocifras = False
End Function

Es una función tipo boolean, que devuelve VERDADERO (True) o FALSO (False). Puedes probarla: DENTROCIFRAS(2431;43) debe dar VERDADERO y DENTROCIFRAS(818;88), FALSO, porque las cifras han de ser consecutivas.

Función CONTIENEDIV

Con esta función ya estamos preparados para saber si las cifras de un número contienen las de un divisor determinado, como ocurre con 725 y 25. Bastará hacernos las preguntas de si es divisor y después de si sus cifras están contenidas. Podemos organizarlo así:

Public Function contienediv(a, b) As Boolean
contienediv = a / b = a \ b And dentrocifras(a, b)
End Function

En primer lugar determina si es divisor, mediante a/b=a\b, que significa que al dividirlos resulta el mismo cociente que en la división entera \ (no aparece resto, por lo que se puede usar también la expresión a MOD b = 0) y después, con dentrocifras, si está contenido. Así, contienediv(912;12)=VERDADERO, porque 12 es divisor y sus cifras están contenidas en 912. Por el contrario, contienediv(324;24) da FALSO, porque 24 está contenido pero no es divisor.

Están publicadas las listas de aquellos números múltiplos de alguno de los veinte primeros que contienen sus cifras. Por ejemplo, la de múltiplos de 17 es

17, 170, 1173, 1700, 1717, 1734, 1751, 1768, 1785, 2176, 3179, 3417, 5117, 6171, 6817, 7174, 8177, 8517, 10217, 11713,…

Todos contienen un 17 y son múltiplos de él. Los tienes publicados en http://oeis.org/A121037

Con las funciones que hemos presentado puedes emprender otras búsquedas. Aquí tienes los primeros que contienen 23 como divisor entre sus cifras:

23, 230, 2231, 2300, 2323, 2346, 2369, 2392, 4232, 4623,…

Aunque es algo complicado, se adjunta a continuación el código PARI correspondiente. En la última línea el resultado sería cero, ya que hemos visto que es falso que 324 contenga a 24 como divisor. Hay que recordar que en PARI el valor VERDADERO se codifica como 1 y el FALSO como 0.

indigit(a, b)={ local(u,v,indi=0,la,lb,i,d,x);u=Vec(Str(a)); v=Vec(Str(b)); la=#u; lb=#v; i=1; while(i<=la-lb+1&&indi==0, d=0; for(x=1, lb, if(v[x]==u[i+x-1], d+=1)); indi=(d==lb) ; i+=1); indi}
indigitdiv(a,b)=(a%b==0)&&indigit(a,b)
print(indigitdiv(324,24))

Números que contienen todos sus factores primos

En la propuesta anterior fijábamos el valor del divisor que debería estar contenido en las cifras del número, pero ese dato no tenemos por qué saberlo.

Podíamos introducir una función que recorriera los factores primos del número y fuera probando uno a uno para ver si están contenidos o no como subcadena.
El problema está en esa extracción de factores primos. Si deseas profundizar lee la entrada de este blog

http://hojaynumeros.blogspot.com.es/2013/09/tus-funciones-disponibles-en-todas-las.html

En ella se explica la rutina sacaprimos y la función factores. Si las usamos, los factores primos  se guardarán en la matriz primo(n), y es esta la que vamos a usar ahora. Crearemos la función CONTIENEDIVPRIM(A,TIPO). Ella recorrerá los factores primos de A, comprobará con CONTIENEDIV si las cifras de estos están contenidas en el total y las irá acumulando en un string, al que añadirá la expresión del número de primos contenidos localizado. Así,
CONTIENEDIVPRIM (432;0)=2  3 y k= 2

Significa que contiene los factores 2 y 3 y que se han encontrado 2.

El parámetro TIPO nos sirve para, si vale 0, exigir que aparezcan todos los factores primos del número, como en el ejemplo anterior, y si es distinto de  0, fijará el número de factores que deseemos.

Public Function contienedivprim(a, tipo) As String
Dim n, i, k
Dim c$

c$ = ""
n = sacaprimos(a)
k = 0
For i = 1 To n
If contienediv(a, primo(i)) Then c$ = c$ + Str$(primo(i)) + " ": k = k + 1
Next i
c$ = c$ + "y k=" + Str$(k)
If tipo = 0 Then
If k = n Then contienedivprim = c Else contienedivprim = ""
Else
If k >= tipo Then contienedivprim = c Else contienedivprim = ""
End If
End Function

Con el TIPO=0 podemos confeccionar un listado de aquellos números compuestos que contienen a todos sus factores (el caso primo carece de interés):
25, 32, 125, 128, 135, 175, 243, 250, 256, 324, 375, 432, 512, 625, 735, 875, 1024,...

http://oeis.org/A050694

Números que contienen algunos factores primos

Con la función CONTIENEDIVPRIM, modificando el TIPO desde 1 hasta el tope que deseemos, se obtendrán los números que al menos coinciden con tantos factores primos como indique el valor de TIPO. Así, para dos factores obtenemos:

Figuran en la tabla los números con al menos dos coincidencias, los factores con los que coinciden y el número k de ellos. Si prolongamos la lista, aparecerá algún número que coincida con tres factores o más. El primero, que figurará en la siguiente lista, será el 735, que contiene los factores 3, 5 y 7.

Con tres coincidencias o más, haciendo TIPO=3, obtenemos

735, 1326, 1365, 1785, 2346, 2510, 2570, 2730, 3162, 3192, 3276, 3570, 3675, 3792


Estos son los primeros que contienen cuatro primos:

21372, que contiene a 2, 3, 13 y 137
37296, respecto a los divisores 2, 3, 7 y 37

Y con cinco

271362, con divisores 2, 3, 7, 13 y 71
527310, con 2, 3, 5, 7 y 31

Por último, si hacemos TIPO=0, aparecerán los compuestos que contienen a todos sus factores primos (está publicada en http://oeis.org/A050694)

25, 32, 125, 128, 135, 175, 243, 250, 256, 324, 375, 432, 512, 625, 735, 875, 1024, 1250, 1352, 1372, 1593, 1675, 1715, 1792, 2048, 2176, 2304, 2500, 2510, 2560, 2570, 2744, 3072, 3087, 3125, 3375, 3645, 3675, 3792, 4232, 4375, 5120, 5210, 5230, 5832…

Con esta entrada despedimos el curso 2017-18. Volveremos en septiembre si el verano se da bien. Os deseo un buen descanso.