jueves, 30 de junio de 2022

Números con cifras crecientes o decrecientes (3)

Números con factores primos crecientes

Nos proponemos ahora una cuestión intrascendente con el solo objetivo de practicar algoritmos. Hemos estudiado las cifras de los números y los tipos de los mismos  (triangulares, cubos, de Fibonacci), y ahora nos dedicaremos a sus factores primos. La idea es construir un arreglo de factores en el que todas las cifras formen un conjunto creciente (o decreciente en su caso). Por ejemplo, 282=2*3*47.

Nos dedicaremos a los factores primos sin contar repeticiones, para simplificar la tarea. El orden que exigiremos será creciente en sentido amplio.

Para conseguir el conjunto creciente podemos dar los siguientes pasos:

  1. Descomponer el número en factores primos y usarlos ignorando sus exponentes
  2. Exigir que todos los factores tengan cifras crecientes (o decrecientes)
  3. Ordenar dichos factores según su primera cifra, porque si esto falla, no se puede seguir.
  4. Una vez todo ordenado, exigir también que la primera cifra de cada factor sea mayor o igual que la última del anterior.

1.- Los primos deben tener cifras crecientes

En Excel y Calc disponemos de la función sacaprimos, para obtener tanto los primos como sus exponentes. La salida de esa función es el número de primos distintos. Si la deseas reproducir, debes comenzar con la declaración de variables globales:

Global primo(50), expo(50)

Global numomega

Esta declaración te permite usar los primos en cualquier otra función. El vector primo(50) recoge los primos y expo(50) sus exponentes (máximo 50). La variable numomega cuenta los primos.

La función sacaprimos está diseñada así:

Public Function sacaprimos(n)

Dim f, a, e

a = n

f = 2: i = 0: numomega = 0

While f * f <= a

e = 0

While a / f = Int(a / f) ‘Busca primos y sus repeticiones

e = e + 1 ‘Se va formando el exponente

a = a / f

Wend

If e > 0 Then

numomega = numomega + 1 ‘Hay un primo más

primo(numomega) = f ‘Se guarda el primo

expo(numomega) = e ‘Se guarda el exponente

End If

If f = 2 Then f = 3 Else f = f + 2

Wend

If a > 1 Then

numomega = numomega + 1

primo(numomega) = a

expo(numomega) = 1

End If

sacaprimos = numomega

End Function

Con esta función obtenemos los vectores primo y expo para recoger los primos y los exponentes, y numomega para contar los primos. Es importante recordar que la salida de la función es esta variable.

Con el uso de esta función podemos responder a la primera cuestión: que todos los primos tengan cifras crecientes (o decrecientes en su caso):

Estudiaremos la función que hemos diseñado, concatpandigi, a trozos:

 

m=numomega

For i = 1 To m

If Not cifras_crecientes(primo(i)) Then concatpandigi = "": Exit Function

Next i

Se lee el número de primos y se almacena en la variable m. Se recorren los primos, y si uno no tiene cifras crecientes, salimos de la función.

2.- Ordenar los factores según su primera cifra:

El siguiente trozo de función ordena los primos según su primera cifra. En realidad es la última, porque nuestras funciones leen las cifras de derecha a izquierda. Puede ser este:

If m > 1 Then  ‘Si m=1, no se ordena

i = 2

Do Until i > m ‘Usamos una rutina de ordenación

j = i

‘Lo que sigue es complicado por tener que ordenar mediante la última cifra, que para nosotros es la primera

While j > 1 And cifra(primo(j), numcifras(primo(j))) < cifra(primo(j - 1), numcifras(primo(j - 1)))

v = primo(j): primo(j) = primo(j - 1): primo(j - 1) = v

j = j - 1

Wend

i = i + 1

Loop

End If

3.- Exigir  que la primera cifra de cada factor sea mayor o igual que la última del anterior.

vale = True

i = 1

While i < m And vale

If cifra(primo(i), 1) > cifra(primo(i + 1), numcifras(primo(i + 1))) Then vale = False

i = i + 1

Wend

4.- Si todo va bien, se recogen los primos en un string:

If vale Then For i = 1 To m: s$ = s$ + Str$(primo(i)): Next i

concatpandigi = s

En el Anexo de esta entrada incluimos la función completa.

 

Números que cumplen lo exigido

Con la función concatpandigi ya podemos discriminar los números que cumplen lo exigido y los que no lo cumplen. Estos son los primeros cuyos primos forman una escala creciente (en sentido amplio), en los que hemos eliminado los de un solo factor primo, como 4, 8 o 9:

En forma de lista:

6, 10, 12, 14, 15, 18, 20, 21, 22, 24, 28, 30, 33, 35, 36, 39, 40, 42, 44, 45, 46, 48, 50, 54, 55, 56, 58, 60, 63, 65, 66, 69, 70, 72, 74, 75, 77, 80, 84, 88, 90, 91, 92, 94, 96, 98, 99, 100, 105, 108, 110, 111, 112, 115, 116, 117, 118, 119, 120,...

Observamos que aparecen muchos ejemplos, más de los esperados.

Si restringimos, por ejemplo, a los que poseen cuatro divisores primos, nos quedan:


Como curiosidad, estos son los de más de cuatro primos:

 


Un ejercicio divertido es imaginar números con más factores, como 11*2*3*5*67*7*89=13774530

 ¿Podrá existir un ejemplo pandigital? Si prescidimos del 0 y el 1, podemos usar 2438778=2*3*4567*89, o bien 0+1*2*3*4567*89

Dejamos abiertas las variantes de cifras estrictamente crecientes o las de cifras decrecientes. Se manejarían de igual forma, adaptando los algoritmos. Queda como reto o ejercicio.

 Con esta entrada finalizamos el curso 2021-22. Después del verano, en septiembre, volveremos a buscar temas de interés. Saludos.

 

 

Anexo

 

Function concatpandigi$(n)

Dim s$

Dim v, m, i, j

Dim vale As Boolean

 

'Devuelve cadena vacía o un string con los primos

 

s$ = ""

m = sacaprimos(n)

'Todos los primos han de tener cifras crecientes

For i = 1 To m

If Not cifras_crecientes(primo(i)) Then concatpandigi = "": Exit Function

Next i

'Ordena los primos según su primera cifra

If m > 1 Then

i = 2

Do Until i > m

j = i

While j > 1 And cifra(primo(j), numcifras(primo(j))) < cifra(primo(j - 1), numcifras(primo(j - 1)))

v = primo(j): primo(j) = primo(j - 1): primo(j - 1) = v

j = j - 1

Wend

i = i + 1

Loop

End If

 

'Ve si la primera cifra es menor que la última anterior

vale = True

i = 1

While i < m And vale

If cifra(primo(i), 1) > cifra(primo(i + 1), numcifras(primo(i + 1))) Then vale = False

i = i + 1

Wend

If vale Then For i = 1 To m: s$ = s$ + Str$(primo(i)): Next i

concatpandigi = s

End Function

lunes, 20 de junio de 2022

Números con cifras crecientes o decrecientes (2)

Comenzamos las búsquedas donde las dejamos en la entrada anterior, con los cubos.

Cubos con cifras decrecientes

Mediante un proceso similar se pueden encontrar los cubos perfectos que presentan cifras decrecientes (en sentido amplio). En PARI vale todo lo explicado, pero hay que sustituir vecsort(digits(m)), por vecsort(digits(m),,4), que ordena las cifras en sentido contrario.

En este caso sí aparecen infinitos cubos, pero la conjetura que se deduce de ellos es distinta:

Cubos: 0, 1, 8, 64, 1000, 8000, 64000, 1000000, 8000000, 64000000, 1000000000, 8000000000, 64000000000, 1000000000000, 8000000000000, 64000000000000, 1000000000000000, 8000000000000000, 64000000000000000, 1000000000000000000, 8000000000000000000, 64000000000000000000, 1000000000000000000000,…

Conjetura: Todos los cubos con cifras decrecientes (en sentido amplio) en base10 pertenecen a uno de estos tipos: 0, 10^k, 8*10^k, 64*10^k, con k entero mayor o igual a cero.

Como la anterior, la hemos verificado hasta 10^24, por lo que también queda abierta hasta que se encuentre un contraejemplo.

Como curiosidad, por si a alguien le interesa, se reproduce el código de nuestra función CIFRAS_DECRECIENTES, que no requiere más explicaciones:

Función en VBASIC

Public Function cifras_decrecientes(n) As Boolean

Dim j, l

Dim c As Boolean

l = numcifras(n)

c = True

If l > 1 Then

j = l

While j >= 2 And c

If cifra(n, j) < cifra(n, j - 1) Then c = False

j = j - 1

Wend

End If

cifras_decrecientes = c

End Function

Por dar variedad al tema, no repetiremos algunos ejemplos tratados en la entrada anterior. Podemos buscar otros tipos. Por ejemplo, los primos. En Vbasic de Excel puedes usar nuestra función ESPRIMO, muy usada en nuestras publicaciones. Puedes buscar en Google ESPRIMO Roldán hoja. Si solo escribes ESPRIMO te aparecen unos productos informáticos. Con ella y CIFRAS_DECRECIENTES, puedes buscar los primeros ejemplos de primos con cifras decrecientes (en sentido amplio):

2, 3, 5, 7, 11, 31, 41, 43, 53, 61, 71, 73, 83, 97, 211, 311, 331, 421, 431, 433, 443, 521, 541, 631, 641, 643, 653, 661, 733, 743, 751, 761, 773, 811, 821, 853, 863, 877, 881, 883, 887, 911, 941, 953, 971, 977, 983, 991, 997

Los tienes en http://oeis.org/A028867. En esa página figura una versión en PARI de la búsqueda que es mejorable. Proponemos mejor esta otra:

ok(n) = digits(n) == vecsort(digits(n),,4) && isprime(n)

for(i=2,10^3,if(ok(i),print1(i,", ")))

La comprobamos en la página de PARI/GP:


Números de Fibonacci con cifras decrecientes

Otro ejemplo interesante es el de los números de Fibonacci, porque parece que dan lugar también a una sucesión finita:

1, 2, 3, 5, 8, 21, 55, 610, 987

Para hoja de cálculo podemos usar nuestra función ESFIBO, que determina si un número es de Fibonacci o no.

Public Function esfibo(n) As Boolean 'Devuelve verdadero si N es de Fibonacci

Dim f As Boolean

Dim a

f = False

a = 5 * n * n + 4

If escuad(a) Then f = True

a = 5 * n * n - 4

If escuad(a) Then f = True

esfibo = f

End Function

Se basa en popular criterio para saber si un número pertenece a la sucesión de Fibonacci. Lo puedes consultar en Gaussianos:

https://www.gaussianos.com/algunas-curiosidades-sobre-los-numeros-de-fibonacci/

Si aplicamos esta función ESFIBO con CIFRAS_DECRECIENTES llegaremos al resultado presentado.

En estos casos de sucesiones finitas hay que avanzar bastante para plantear una conjetura. Por eso debemos pasar a PARI, que llega más lejos en sus cálculos:

ok(n) = digits(n) == vecsort(digits(n),,4) && (issquare(5*n^2+4) || issquare(5*n^2-4))

for(i=2,10^6,if(ok(i),print1(i,", ")))

Hasta 10^6 devuelve los mismos resultados que la hoja de cálculo, salvo el 1, que se da por supuesto:

Le hemos exigido algo más, que llegue a 10^8, y no ha aparecido ningún ejemplo más.

Podemos intentar generar los números de Fibonacci según su definición. Con este otro algoritmo hemos recorrido los 10^4 primeros con el mismo resultado:

m=1;n=1;for(i=1,10^4,p=m+n;m=n;n=p;if(digits(p) == vecsort(digits(p),,4),print1(p,", ")))

En la sucesión  A273046, el colaborador  Charles R Greathouse IV, llega a la misma conclusión de que es probable que no existan más ejemplos.

Es interesante que en una misma cuestión hayamos presentado tres sucesiones finitas. Es una especie de probabilidad decreciente, de tal forma que, al crecer mucho los números, la misma tiende a cero, perdiendo la posibilidad de aparición de ejemplos nuevos. Como esto es solo una explicación no matemática, se quedarán en conjeturas.

Números de Bouncy

Son aquellos números tales que sus cifras no son crecientes ni decrecientes. Como siempre queda la duda de si hablamos de orden en sentido amplio o estricto, diremos que, en el segundo caso, están publicados en http://oeis.org/A152054, con orden estricto. Probemos con el orden amplio. Bastará unir las funciones que hemos usado (para crecientes y para decrecientes) mediante las conectivas lógicas NOT y AND:

NOT CIFRAS_CRECIENTES(N) AND NOT CIFRAS_DECRECIENTES(N)

Como era de esperar, casi todos los números aparecen:

101, 102, 103, 104, 105, 106, 107, 108, 109, 120, 121, 130, 131, 132, 140, 141, 142, 143, 150, 151, 152, 153, 154, 160, 161, 162, 163, 164, 165, 170, 171, 172, 173, 174, 175, 176, 180, 181, 182, 183, 184, 185, 186, 187, 190, 191, 192, 193, 194, 195, 196, 197

No obtenemos números de una o dos cifras porque todos son crecientes o decrecientes en sentido amplio. Existirán diferencias entre los dos tipos de orden, como por ejemplo con el número 1133 que no es creciente en sentido estricto, pero sí lo es en el amplio.

En OEIS, para evitar ambigüedades, al amplio lo identifican como nonincreasing o nondecreasing.

Son tantos estos números que no merece la pena dividirlos entre los distintos tipos.

viernes, 10 de junio de 2022

Números con cifras crecientes o decrecientes (1)

En este estudio nos dedicaremos a cuestiones derivadas del orden de las cifras de un número. Serán desarrollos sin mucha trascendencia, pues tan solo se pretende efectuar ejercicios de creación de funciones o de búsquedas. Al igual que nos ocurrió en otros desarrollos, en este comenzaremos con distintos tipos de números y sus propiedades respecto al orden de sus cifras, y seguiremos investigando con temas afines hasta constatar que pierden interés.

En todas las cuestiones deberemos concretar el tipo de orden, que puede ser creciente, en sentido amplio, con cifras repetidas, o en sentido estricto, en el que no se permiten cifras consecutivas iguales. Igualmente, en el orden decreciente también usaremos los dos sentidos. Como el tema es amplio, daremos preferencia a las cifras crecientes.

Tipos de números y orden de sus cifras

Están publicadas muchas sucesiones que relacionan tipos de números con sus cifras. Unos ejemplos:

Triangulares con cifras crecientes (sentido amplio)

Están publicados en http://oeis.org/A234848:

0, 1, 3, 6, 15, 28, 36, 45, 55, 66, 78, 136, 378, 666, 1128, 1225, 1378, 2278, 2346, 2556, 5778, 12246, 13366, 22366, 22578,…

Aprovechamos esta sucesión para presentar nuestra función en VBasic destinada a detectar este tipo de orden creciente:

Function cifras_crecientes(n) As Boolean

Dim j, l

Dim c As Boolean

l = numcifras(n) ‘Cuenta las cifras del número

c = True

If l > 1 Then ‘Si tiene una cifra, no lo estudiamos

j = l

While j >= 2 And c

If cifra(n, j) > cifra(n, j - 1) Then c = False ‘Si una cifra rompe el orden, no es creciente (se estudia de derecha a izquierda)

j = j - 1

Wend

End If

cifras_crecientes = c

End Function

 

La función NUMCIFRAS se define como

Function numcifras(n)

Dim nn, a

a = 1: nn = 0

While a <= n

a = a * 10: nn = nn + 1

Wend

numcifras = nn

End Function

 

Y la función CIFRA como

Function cifra(m, n)

Dim a, b

If n > numcifras(m) Then

  cifra = -1

  Else

  a = 10 ^ (n - 1)

  b = Int(m / a) - 10 * Int(m / a / 10)

  cifra = b

  End If

End Function

Vemos que extrae las cifras en el orden desde las unidades hasta las decenas, centenas…

Con estas funciones es fácil encontrar los triangulares que tienen sus cifras en orden creciente amplio. El criterio sería

ESTRIANGULAR(N) AND CIFRAS_CRECIENTES(N)

La primera función la hemos usado mucho. Puedes usar la búsqueda estriangular( hoja en Google. Exige que 8*n+1 sea cuadrado.

El resultado sería:



Es evidente que coincide con lo publicado. Esto solo ha sido la comprobación de que nuestra función está correctamente diseñada.

En PARI la detección de cifras crecientes es brevísima. Basta plantear

digits(m)==vecsort(digits(m))

Es una solución muy ingeniosa, porque viene a decir que las cifras actuales coinciden con las cifras ordenadas. Si se desea orden estricto, sin repeticiones, ha de incorporarse el parámetro 8 de esta forma: vecsort(digits(m,,8))

Por ejemplo, con esta línea encuentras los triangulares con cifras en orden creciente estricto:

for(i=0,10^3,if(digits(i)==vecsort(digits(i),,8)&&issquare(8*i+1),print1(i,", ")))



Usamos los triangulares como introducción a las técnicas adecuadas. Si deseas practicar o profundizar puedes consultar estas sucesiones:

http://oeis.org/A028864: Primos con cifras crecientes.

http://oeis.org/A028820: Ídem cuadrados.

http://oeis.org/A273045: Números de Fibonacci.

Como los números oblongos, del tipo N(N+1) son olvidados fácilmente, los rescataremos aquí:

Oblongos con cifras crecientes

Un número oblongo es el doble de un triangular, luego si en estos 8*n+1 ha de ser cuadrado, en los oblongos lo será 4*n+1. En esto se basa nuestra función ESOBLONGO, y con ella podemos investigar en Excel junto a CIFRAS_CRECIENTES. El resultado es

Con PARI podemos llegar más lejos:

0, 2, 6, 12, 56, 156, 1122, 2256, 4556, 11556, 111222, 445556, 11112222, 44455556, 222233556, 1111122222, 4444555556, 111111222222, 444445555556, 11111112222222, 44444455555556, 1111111122222222, 4444444555555556, 111111111222222222,

Primera versión: generar los oblongos a partir del 2, sumando luego 4, 6, 8. 10. El inconveniente es que hay que partir siempre del 2, no se puede iniciar, por ejemplo en 10^10. Es muy rápido al principio, pero luego ralentiza.

m=2;k=2;while(m<10^8,if(digits(m)==vecsort(digits(m)),print1(m,", "));k+=2;m+=k)

Lo hemos probado en https://pari.math.u-bordeaux.fr/gp.html

 

Segunda versión: construir m(m+1) y después aplicar el criterio. Es más lento, porque tiene que multiplicar en cada caso

 for(i=10^3,10^7,m=i*(i+1);if(digits(m)==vecsort(digits(m)),print(m)))

Lo hemos probado con GP/PARI CALCULATOR con este resultado, que comprende los valores incluidos para m, 10^3 a 10^7: 

Tercera versión: Es la más lenta, porque, como en Excel, aplica el criterio de que sea cuadrada la expresión (4*n+1). Lo comprobamos para números no muy grandes en la web de PARI:

ok(n)=digits(n)==vecsort(digits(n))&&issquare(4*n+1)

for(i=0,10^6,if(ok(i),print(i)))


Potencias perfectas con cifras crecientes

En este tipo nos limitaremos a presentar el resultado, para animar a los lectores a intentar reproducirlo. Como pista, en PARI habría que usar la función ispower:

4, 8, 9, 16, 25, 27, 36, 49, 125, 128, 144, 169, 225, 256, 289, 1156, 1225, 1369, 1444, 4489, 6889, 11236, 11449, 13456, 13689, 27889, 33489, 111556, 112225, 113569, 134689, 146689, 344569, 444889, 2666689, 2778889, 11115556, 11122225, 11135569, 11336689, 11444689, 13446889,…

Cubos

Aquí nos detendremos, porque su número es, al parecer, finito. Sólo se han encontrado los cubos 0, 1, 8, 27 y 125 con cifras crecientes en sentido amplio (en el estricto tendríamos menos posibilidades).

Empleando diversas técnicas y lenguajes, no ha sido posible encontrar más ejemplos de cubos con cifras crecientes, por lo que se puede enunciar la conjetura:

Sólo existen cinco cubos perfectos con sus cifras crecientes en sentido amplio en base 10.

Con hoja de cálculo podemos usar la función ESCUBO junto a la de cifras crecientes. Por el problema de los decimales, no es fácil determinar si un número desconocido es un cubo. Hemos usado esta versión:

Function escubo(n)

Dim a

a = Int(n ^ (1 / 3) + 10 ^ (-6))

If a * a * a = n Then escubo = True Else escubo = False

End Function

Buscamos, por ejemplo, entre 0 y 10^6, y conseguiremos tan solo esos cinco casos:

En PARI se pueden plantear dos puntos de vista: en el primero usar una función que detecte la propiedad directamente en un número cualquiera, y en el segundo se trata de ir construyendo los cubos uno a uno y esperar a que se cumpla la condición en uno de ellos.

Función directa

ok(n)=digits(n)==vecsort(digits(n))&&ispower(n,3)

Se entiende fácilmente con lo explicado con anterioridad. Esta función, aplicada a un número natural, indica si es un cubo (ispower(n,3)) y si sus cifras crecen (digits(n)==vecsort(digits(n)).

Es muy directa y sencilla, pero resulta bastante lenta, por tener que probar todos los números, sean cubos o no.

Construcción de cubos

Para encontrar cubos es preferible construirlos desde 0. Esto es lo que efectúa esta otra variante:

for(i=0,1000,m=i^3;if(digits(m)==vecsort(digits(m)),print1(m,”, “)))

Es tres veces más veloz que la función anterior, porque la variable m siempre será un cubo. He aquí el resultado:

Hemos llegado de varias formas hasta 10^24, sin detectar otro cubo con cifras crecientes, por lo que podemos dar por cierta la conjetura hasta que alguien descubra un contraejemplo.

Lo dejamos aquí por hoy. En la siguiente entrada estudiaremos algunos ejemplos con cifras decrecientes.

jueves, 2 de junio de 2022

Los pandigitales completos

Se llaman pandigitales a los números que presentan en su representación todas las cifras posibles en una base de numeración. Aquí nos restringiremos a base 10 y a aquellos números que contienen todas las cifras del 0 al 9 (completos), pero sin repetición. Es el concepto más simple y útil respecto a otras variantes.

Es claro que el pandigital más pequeño de este tipo será 1023456789, y el mayor 9876543210. Como no consideramos repeticiones de cifras, su número será 10!=3628800 si admitimos el cero inicial, y 10!-9!= 3265920 si no lo admitimos.

Ningún número pandigital de este tipo puede ser un número primo, porque cumple el criterio de divisibilidad entre 9 y 3, al sumar sus cifras 45

Reconocimiento de pandigitales

No es fácil reconocer mediante un algoritmo si un número (del que no conocemos en principio su expresión decimal) es pandigital o no. Es evidente que normalmente conocemos sus cifras, pero en una búsqueda no. Por ejemplo, si buscamos un pandigital que sea triangular, no conocemos sus cifras hasta que lo encontremos.

Aquí, como es costumbre, estudiaremos dos versiones, una para hoja de cálculo y otra para PARI.

Proceso en PARI

La segunda es muy fácil de entender:

 pandigi(n)= #vecsort(digits(m), , 8)==10

Literalmente nos dice, que si ordenamos el vector formado por las cifras (vecsort(digits), eliminamos repetidos (parámetro 8), y luego las contamos (signo #), ha de resultar un número igual a 10, que sería el número de cifras sin repetición.

Un ejemplo de uso de esta función es el de encontrar el primer pandigital cuadrado. Tomamos la menor base cuyo cuadrado tiene diez cifras, que es  31623, y vamos avanzando cuadrados hasta encontrar un pandigital. Sería así:

pandigi(m)=#vecsort(digits(m), , 8)==10

m=31623;q=m^2;while(pandigi(q)==0,m+=1;q=m^2);print(m)

En primer lugar define la función pandigi, para reconocer pandigitales, y después avanza los cuadrados en un bucle while hasta encontrar un valor de pandigi que no sea cero.

El resultado es 1026753849=32043^2

El resto de los pandigitales cuadrados los puedes consultar en http://oeis.org/A036745

Proceso en hojas de cálculo

En este caso perdemos la potencia del lenguaje PARI, pero podemos imitar nuestro reconocimiento de un pandigital:

Nosotros iríamos recorriendo las cifras del número, y si falta una, lo rechazaríamos, y si existe una repetición, también. Después contaríamos que estuvieran las diez cifras.

Pues algo así realizaremos con VBasic. Para ello prepararemos diez memorias que alojen las frecuencias de las cifras. Cada vez que aparezca una incrementamos la memoria correspondiente. Podemos organizar todo con esta función:

Public Function pandigital(a) As Boolean

Dim ci(10)

Dim i

Dim t As Boolean

t = True

For i = 0 To 9: ci(i) = 0: Next i ‘Preparamos diez memorias

If numcifras(a)<>10 then pandigital=false:exit function

For i = 1 To 10

ci(cifra(a, i)) = ci(cifra(a, i)) + 1  ’Anotamos cada cifra

‘Si la frecuencia es mayor que 1, se rechaza el número

If ci(cifra(a, i)) > 1 Then pandigital = False: Exit Function

Next i

s = 0

For i = 0 To 9

If ci(i) = 0 Then t = False ‘Si queda una memoria vacía, se rechaza

Next i

pandigital = t ‘Devuelve verdadero o falso

End Function

Con esta función es fácil obtener un listado de los primeros pandigitales:

Podemos usar esta función para encontrar, por ejemplo, el primer número pandigital triangular. Partimos de 1000006281, primer triangular de 10 cifras, de orden 44721, y vamos recorriendo triangulares hasta encontrar un pandigital. Todo se basa en la fórmula de los triangulares, N(N+1)/2.

Function panditrian(n)

Dim m

m = n

Do Until pandigital(m * (m + 1) / 2)

m = m + 1

Loop

panditrian = m * (m + 1) / 2

End Function

Con esta función encontramos el primer pandigital triangular, 1062489753, de orden 46097. Está publicado en http://oeis.org/A241812, pero es interesante volverlo a encontrar con nuestros propios medios.

De esta forma podemos encontrar cubos, oblongos y otros que sean pandigitales sin repetición.

Por ejemplo, el menor oblongo de diez cifras es 1000045752=31623*31624. Con un pequeño cambio en la función de arriba obtenemos 1492083756=38627*38628 como el menor oblongo pandigital. No está publicado.

En el caso de los cubos, no hemos encontrado ningún ejemplo.

Los tipos que hemos buscado tienen forma polinómica, lo que ha acelerado el proceso. En otros casos la búsqueda sería mucho más lenta.

Existen muchos casos en los que un pandigital es múltiplo de otro, pero su búsqueda es lenta y no la abordaremos. Sí es sencillo buscar un múltiplo pandigital de cualquier otro número menor. En casi todos los casos se encuentra con éxito, e incluso circula por ahí la conjetura de que todos los números poseen un múltiplo pandigital, pero no es cierta, ya que los números terminados en 00 no lo tienen, y también muchos múltiplos de 25.

Con este código PARI encuentras fácilmente un múltiplo pandigital de otro cualquiera menor que 10^9:

multipan(n)={my(e=0,i=1,m=n);while(m<=10^10&&e==0,m=n*i;if(#vecsort(digits(m), , 8)==10,e=m);i+=1);e}

print(multipan(23322))

En el ejemplo se busca el múltiplo de 23322, y resulta ser 1053967824=45192*23322

Si cambias 23322 por otro número, obtendrás su múltiplo pandigital. Si no existe, te devolverá un cero. Prueba con un número terminado en dos ceros.