Ciencia y TecnologíaNacionalNacionales

Pilas de peniques

Imagen ilustrativa. Imagen creada por inteligencia artificial.

Todo conjunto de monedas puede distribuirse en pilas de distintos tamaños. Por ejemplo, cinco peniques podrían disponerse en exactamente siete formas diferentes:

  1. una sola pila,
  2. una pila de 4 peniques y una pila de 1,
  3. una pila de 3 y otra de 2,
  4. una pila de 3 y dos pilas de 1,
  5. dos pilas de 2 y una pila de 1,
  6. una pila de 2 y tres pilas de 1, o
  7. cinco pilas de 1.

Los diagramas de la derecha esbozan (usando esferas) estas posibles disposiciones. Tales arreglos suelen denominarse diagramas de Ferrers.1

Si trasladamos esta situación a un problema meramente numérico, no estamos sino expresando un entero positivo dado como suma de los enteros positivos menores o iguales que él. Así, en el ejemplo que hemos discutido, el 5 podría descomponerse como sigue

\begin{alignat*}{2}  5\quad  &= \quad 5\\  5\quad  &= \quad 4 + 1\\  5\quad  &= \quad 3 + 2\\  5\quad  &= \quad 3 + 1 + 1\\  5\quad  &= \quad 2 + 2 + 1\\  5\quad  &= \quad 2 + 1 + 1 + 1\\  5\quad  &= \quad 1 + 1 + 1 + 1 + 1 &  \end{alignat*}

El orden de los sumandos no es importante, de suerte que sumas como

\begin{equation*}\color{Crimson}3+1+1,\;\color{blue}1+3+1,\;\color{MediumVioletRed}1+1+3\end{equation*}

representan todas una misma forma.

Cada una de estas representaciones se denomina partición. Y, en general, denotaremos la cantidad de particiones de un número n por p\left(n\right).2

En este caso, claro está, p\left(5\right)=7.

Aunque los cálculos son bastante simples, pronto se tornan engorrosos. A título de ejemplo, p\left(12\right)=77, pero p\left(24\right)=1\,575.

Así pues, en el desafío de esta ocasión nuestros lectores se toparán, tarde que temprano, con cantidades mucho mayores que el número estimado de átomos en el universo (\sim 10^{80}).

Se pide hallar el menor valor de n para el que p\left(n\right) es divisible por 1\,000\,000.

Al igual que en nuestra más reciente entrega, lo grande de los valores involucrados hace indispensable el uso de una computadora.

Con nada más que lápiz, papel y un poco de paciencia podemos hallar fácilmente los valores de la función de partición para n=1,2,\ldots,10 :

\begin{equation*}\def\arraystretch{1.75}\begin{aligned}p\left(1\right) &= 1,  &\quad& p\left(2\right) &= 2,  &\quad& p\left(3\right) &= 3,  &\quad&	p\left(4\right) &= 5,  &\quad& p\left(5\right) &= 7,  & &\\p\left(6\right) &= 11 ,&\quad& p\left(7\right) &= 15, &\quad& p\left(8\right) &= 22, &\quad& p\left(9\right) &= 30, &\quad& p\left(10\right) &=  42. &&\end{aligned}\end{equation*}

Hasta p\left(6\right), inclusive, pareciera posible establecer una correspondencia ente p\left(n\right) y los números primos. No obstante, los valores que le siguen desdibujan nuestras esperanzas.

Así, tras una inspección más detallada, bien podríamos plantearnos la posibilidad de identificar algún patrón de recurrencia.

En ocasiones, sin embargo, este no es tan evidente. Veamos, por ejemplo, que

\begin{equation*}\def\arraystretch{1.5} \begin{aligned} p\left(3\right) &= p\left(2\right) + p\left(1\right)\\p\left(4\right) &= p\left(3\right) + p\left(2\right)\end{aligned}\end{equation*}

pero que

\begin{equation*}\def\arraystretch{1.5} \begin{aligned} p\left(5\right) &= p\left(4\right) + p\left(3\right) - 1 \\ p\left(6\right) &= p\left(5\right) + p\left(4\right) - 1 \\ p\left(7\right) &= p\left(6\right) + p\left(5\right) - 3 \end{aligned}\end{equation*}

Este procedimiento sugiere que de suponer que p\left(n\right) depende de la suma de sus dos antecesores inmediatos (salvo por los casos n=1 y n=2), requeriremos de una corrección (ya sea por exceso o por defecto). Es decir,

\begin{equation*}p\left(n\right)=p\left(n-1\right)+p\left(n-2\right)\textcolor{Tomato}{+\zeta_n\;}, \hspace{5mm} \zeta_n\in\mathbb{N}-\left\{1,2\right\}\end{equation*}

Para ilustrarlo, resaltamos a continuación en rojo las correcciones no nulas que precisarían los 10 primeros casos

\begin{equation*}	\def\arraystretch{1.25}	\begin{array}{rclc lclcl}		p(1)  &=& 1   & & &&&&\\		p(2)  &=& 2   &=& 1 &\textcolor{Tomato}{+}& \textcolor{Tomato}{1} &&   \\		p(3)  &=& 3   &=& 2 &+&1& &\\		p(4)  &=& 5   &=& 3 &+&2& &\\		p(5)  &=& 7   &=& 5 &+&3&\textcolor{Tomato}{-}  &\textcolor{Tomato}{1} \\		p(6)  &=& 11  &=& 7 &+&5&\textcolor{Tomato}{-}  &\textcolor{Tomato}{1} \\		p(7)  &=& 15  &=& 11&+&7&\textcolor{Tomato}{-}  &\textcolor{Tomato}{3} \\		p(8)  &=& 22  &=& 15&+&11&\textcolor{Tomato}{-} &\textcolor{Tomato}{4} \\		p(9)  &=& 30  &=& 22&+&15&\textcolor{Tomato}{-} &\textcolor{Tomato}{7} \\		p(10) &=& 42  &=& 30&+&22&\textcolor{Tomato}{-} &\textcolor{Tomato}{10}\\	\end{array}\end{equation*}

Como era de esperar, las columnas numéricas enseguida destacadas contienen la sucesión 1, 2, 3, 5, 7, 11, 15, 22,\ldots.

\begin{equation*} \def\arraystretch{1.25} \begin{array}{rclc lclcl}p(1)  &=& \colorbox{Khaki}{1}   & & &&&&\\p(2)  &=& \colorbox{Khaki}{2}   &=& \colorbox{Khaki}{1} &\textcolor{Tomato}{+}& \textcolor{Tomato}{1} &&   \\p(3)  &=& \colorbox{Khaki}{3}   &=& \colorbox{Khaki}{2} &+&\colorbox{Khaki}{1}& &\\p(4)  &=& \colorbox{Khaki}{5}   &=& \colorbox{Khaki}{3} &+&\colorbox{Khaki}{2}& &\\p(5)  &=& \colorbox{Khaki}{7}   &=& \colorbox{Khaki}{5} &+&\colorbox{Khaki}{3}&\textcolor{Tomato}{-}  &\textcolor{Tomato}{1} \\p(6)  &=& \colorbox{Khaki}{11}  &=& \colorbox{Khaki}{7} &+&\colorbox{Khaki}{5}&\textcolor{Tomato}{-}  &\textcolor{Tomato}{1} \\p(7)  &=& \colorbox{Khaki}{15}  &=& \colorbox{Khaki}{11}&+&\colorbox{Khaki}{7}&\textcolor{Tomato}{-}  &\textcolor{Tomato}{3} \\p(8)  &=& \colorbox{Khaki}{22}  &=& \colorbox{Khaki}{15}&+&\colorbox{Khaki}{11}&\textcolor{Tomato}{-} &\textcolor{Tomato}{4} \\p(9)  &=& \colorbox{Khaki}{30}  &=& \colorbox{Khaki}{22}&+&\colorbox{Khaki}{15}&\textcolor{Tomato}{-} &\textcolor{Tomato}{7} \\p(10) &=& \colorbox{Khaki}{42}  &=& \colorbox{Khaki}{30}&+&\colorbox{Khaki}{22}&\textcolor{Tomato}{-} &\textcolor{Tomato}{10}\\ \end{array}\end{equation*}

Así, si de alguna forma consiguiésemos distribuir las correcciones en dos sumandos que aseguren la aparición de esta misma sucesión por cuarta ocasión, estaremos en camino de esclarecer el patrón seguido.

En efecto, podemos escribir

\begin{equation*} \def\arraystretch{1.25} \begin{array}{rcl c lclclcl}p\left(1\right)  &=& 1   & &   & & & & & &\\p\left(2\right)  &=& 2   &=& 1 &\textcolor{Tomato}{+}& \textcolor{Tomato}{1} & & & &\\p\left(3\right)  &=& 3   &=& 2 &+&1 & & & &\\p\left(4\right)  &=& 5   &=& 3 &+&2 & & & &\\p\left(5\right)  &=& 7   &=& 5 &+&3 &\textcolor{Tomato}{-}  &\textcolor{Tomato}{1} & &\\p\left(6\right)  &=& 11  &=& 7 &+&5 &\textcolor{Tomato}{-}  &\colorbox{Khaki}{\textcolor{Tomato}{1}} & &\\p\left(7\right)  &=& 15  &=& 11&+&7 &-&\colorbox{Khaki}{2}&\textcolor{Tomato}{-} &\textcolor{Tomato}{1} \\p\left(8\right)  &=& 22  &=& 15&+&11&-&\colorbox{Khaki}{3}&\textcolor{Tomato}{-} &\colorbox{Khaki}{\textcolor{Tomato}{1}} \\p\left(9\right)  &=& 30  &=& 22&+&15&-&\colorbox{Khaki}{5}&\textcolor{Tomato}{-} &\colorbox{Khaki}{\textcolor{Tomato}{2}} \\p\left(10\right) &=& 42  &=& 30&+&22&-&\colorbox{Khaki}{7}&\textcolor{Tomato}{-} &\colorbox{Khaki}{\textcolor{Tomato}{3}} \end{array}\end{equation*}

Para ventura nuestra, con esta redistribución advertimos que la sucesión referida comienza a mostrarse por quinta vez. Este proceso, según lo intuimos, puede repetirse para cualquier valor de n.

Más aún, en términos de las funciones de partición, el arreglo anterior puede componerse como sigue

\begin{equation*} \def\arraystretch{1.25}	\begin{array}{r c lclclcl} p\left(1\right)  &=& 1& & & & & & \\ p\left(2\right)  &=& p\left(1\right)&\textcolor{Tomato}{+}& \textcolor{Tomato}{1} & & & &\\ p\left(3\right)  &=& p\left(2\right)&+&p\left(1\right)& & & &\\ p\left(4\right)  &=& p\left(3\right)&+&p\left(2\right)& & & &\\ p\left(5\right)  &=& p\left(4\right)&+&p\left(3\right)&\textcolor{Tomato}{-}&\textcolor{Tomato}{1}\\ p\left(6\right)  &=& p\left(5\right)&+&p\left(4\right)&-&p\left(1\right)& &\\ p\left(7\right)  &=& p\left(6\right)&+&p\left(5\right)&-&p\left(2\right)&\textcolor{Tomato}{-} &\textcolor{Tomato}{1} \\ p\left(8\right)  &=& p\left(7\right)&+&p\left(6\right)&-&p\left(3\right)&-&p\left(1\right)\\ p\left(9\right)  &=& p\left(8\right)&+&p\left(7\right)&-&p\left(4\right)&-&p\left(2\right)\\ p\left(10\right) &=& p\left(9\right)&+&p\left(8\right)&-&p\left(5\right)&-&p\left(3\right)\\	\end{array}\end{equation*}

Visto lo anterior, nos permitiremos definir

\begin{equation}p\left(0\right)=1\end{equation}

en virtud de lo que podremos escribir

\begin{equation*} \def\arraystretch{1.25} \begin{array}{r c lclclcl} p\left(1\right)  &=& p\left(0\right)& &  & & & &\\ p\left(2\right)  &=& p\left(1\right)&+&p\left(0\right)& & & &\\ p\left(3\right)  &=& p\left(2\right)&+&p\left(1\right)& & & &\\ p\left(4\right)  &=& p\left(3\right)&+&p\left(2\right)& & & &\\ p\left(5\right)  &=& p\left(4\right)&+&p\left(3\right)&-&p\left(0\right)\\ p\left(6\right)  &=& p\left(5\right)&+&p\left(4\right)&-&p\left(1\right)& &\\ p\left(7\right)  &=& p\left(6\right)&+&p\left(5\right)&-&p\left(2\right)&-&p\left(0\right)\\ p\left(8\right)  &=& p\left(7\right)&+&p\left(6\right)&-&p\left(3\right)&-&p\left(1\right)\\ p\left(9\right)  &=& p\left(8\right)&+&p\left(7\right)&-&p\left(4\right)&-&p\left(2\right)\\ p\left(10\right) &=& p\left(9\right)&+&p\left(8\right)&-&p\left(5\right)&-&p\left(3\right)\\ \end{array}\end{equation*}

De continuar con la tabla, advertiremos que

\begin{equation} \def\arraystretch{1.75}  \color{SteelBlue} \begin{array}{rcl} p\left(n\right)&=&p\left(n-1\right)+p\left(n-2\right)-p\left(n-5\right)-p\left(n-7\right)+\ldots\vphantom{\Big|}\\ &&+p\left(n-12\right)+p\left(n-15\right)-p\left(n-22\right)-p\left(n-26\right)+\ldots\vphantom{\bigg|}	\end{array}\end{equation}

El miembro derecho tendrá tantos términos como diferencias no negativas haya en la sucesión n-1, n-2, n-5, n-7, n-12, n-15, n-22, n-26, \ldots .

Con todo, poco útil nos es esta expresión si desconocemos qué números debemos restar de n.
Al lector bien versado, la secuencia

\begin{equation}1,2,5,7,12,15,22,26,\ldots\end{equation}

le resultará familiar. Se trata de los números pentagonales generalizados.

No obstante, en el supuesto de habernos topado por vez primera con ellos, es totalmente natural intentar hallar una expresión generatriz de los mismos.

A tal efecto, observemos que podemos escribir \left(3\right) como

\begin{equation}\textcolor{RoyalBlue}{1}, \textcolor{RoyalBlue}{1}+1,\textcolor{RoyalBlue}{5},\textcolor{RoyalBlue}{5}+2,\textcolor{RoyalBlue}{12},\textcolor{RoyalBlue}{12}+3,\textcolor{RoyalBlue}{22},\textcolor{RoyalBlue}{22}+4,\ldots\end{equation}

Aparentemente, esta sucesión está formada por dos secuencias:

\begin{alignat}{1}1,5,12,22,\ldots\vphantom{\Big|}\\2,7,15,26,\ldots \vphantom{\Big|}\end{alignat}

Si designamos por \omega_k al k- ésimo término de \left(5\right) , entonces \left(6\right) vendrá dada por \omega_k + k , tal y como lo refleja la tabla siguiente.

\begin{equation}\def\arraystretch{1.25}\begin{array}{c|c|c} k&\phantom{+}\omega_k\phantom{+}&\omega_k + k \\ \hline 1&1&2\\ 2&5&7\\ 3&12&15\\ 4&22&26\\ \vdots&\vdots&\vdots\end{array}\end{equation}

Habida cuenta de que la relación entre k y \omega_k no es lineal, podríamos ensayar, una vez más, una relación de recurrencia. Si, por ejemplo, restamos \omega_{k} de \omega_{k+1}, obtenemos

\begin{equation*} \def\arraystretch{1.35}	\begin{array}{cccclclcl} \Delta_1 &=&\omega_2-\omega_1&=&5-1&=&4&=&3\cdot1+1\\ \Delta_2 &=&\omega_3-\omega_2&=&12-5&=&7&=&3\cdot2+1\\ \Delta_3 &=&\omega_4-\omega_3&=&22-12&=&10&=&3\cdot3+1\\ \vdots   &&\vdots&&\vdots&&\vdots&&\vdots	\end{array}\end{equation*}

esto es

\begin{equation*}\Delta_k=\omega_{k+1}-\omega_k=3k+1\end{equation*}

o bien

\begin{equation}\omega_{k+1}=\omega_k+3k+1\end{equation}

Que la sucesión de las primeras diferencias 4,7,10,\ldots sea una progresión aritmética (es decir, que sea lineal en la variable k) y que la correspondiente sucesión de las segundas diferencias sea constante, son hechos notables que apuntan a que el término general de \left(5\right) tiene una expresión cuadrática.

A fin de develarla podemos ajustar un polinomio de segundo grado a un conjunto de tres pares cualesquiera de la forma \left(k,\omega_k\right).
Así, las tuplas habrían de satisfacer

\begin{equation}ak^2+bk+c=\omega_k, \hspace{5mm}a,b,c\in\mathbb{R}\end{equation}

Si, verbigracia, utilizásemos los tres primeros pares dados en la tabla \left(7\right), \left(1,1\right), \left(2,5\right) y \left(3,12\right), resultará el sistema de tres ecuaciones lineales y tres incógnitas

\begin{equation} \def\arraystretch{1.25} \left. \begin{array}{rcl}  a+b+c&=&1\\  4a+2b+c&=&5\\  9a+3b+c&=&12 \end{array} \color{LightGray} \right\}\end{equation}

cuya solución es

\begin{equation}a={}^{3}\!/\!_{2}, \hspace{5mm} b=-^{1}\!/\!_{2}, \hspace{5mm} c=0\end{equation}

Al introducir estos resultados en \left(9\right), queda

\begin{equation}\omega_k=\frac{k\left(3k-1\right)}{2}\end{equation}

Para verificar la validez de esta expresión echaremos mano del principio de inducción matemática.

El caso base, \omega_1=1, se cumple claramente, así que no nos resta más que probar que

\begin{equation*}\omega_{k+1}=\frac{\left(k+1\right)\left(3k+2\right)}{2}\end{equation*}

En efecto, en virtud de \left(9\right) y la hipótesis inductiva \left(12\right),

\begin{equation*} \def\arraystretch{3.125} \begin{array}{rcl} \omega_{k+1}&=&\displaystyle\frac{k\left(3k-1\right)}{2}+3k+1\\ &=&\displaystyle\frac{3}{2}k^2-\frac{1}{2}k+3k+1\\ &=&\displaystyle\frac{3}{2}k^2+\frac{5}{2}k+1\\ &=&\displaystyle\frac{1}{2}\left(3k^2+5k+2\right)\\ &=&\displaystyle\frac{1}{6}\left[\left(3k\right)^2+5\left(3k\right)+2\right]\\ &=&\displaystyle\frac{1}{6}\left(3k+3\right)\left(3k+2\right)\\ &=&\displaystyle\frac{\left(k+1\right)\left(3k+2\right)}{2} \end{array}\end{equation*}

de suerte que \left(12\right) es válida para todo k\in\mathbb{N}.

Consecuentemente

\begin{equation}\omega_k + k=\frac{k\left(3k+1\right)}{2}=\omega_{-k}\end{equation}

De aquí se sigue que \left(3\right) es de la forma

\begin{equation*}\omega_1,\omega_{-1},\omega_2,\omega_{-2},\omega_3,\omega_{-3},\omega_4,\omega_{-4} \end{equation*}

o, con mayor generalidad

\begin{equation} \fcolorbox{MediumSlateBlue}{white}{$\hspace{2.5mm}\displaystyle\omega\left(k\right)=\frac{k\left(3k-1\right)}{2},\hspace{5mm}k=1,-1,2,-2,3,-3\ldots\vphantom{\Bigg|_{|}^{|}}\hspace{2.5mm}$}\end{equation}

Existe una vía alternativa para llegar a este mismo resultado. Su riqueza visual amerita que la consideremos también.

Tal y como lo habíamos adelantado, a los elementos de la sucesión \left(3\right) se les suele llamar pentagonales y pertenecen a una clase más amplia de números, denominados poligonales.
Estos son números figurados, es decir, números naturales que tienen asociada una representación poligonal regular de puntos.

En la imagen situada al margen se ilustran las representaciones visuales de los primeros cinco números pentagonales: 1, 5, 12, 22 y 35.

Calcular su valor a partir de sus diagramas no es tarea difícil. De acuerdo con la Fig. 3, toda distribución pentagonal de puntos puede dividirse en tres regiones triangulares.

Fig. 3 - Disposición para el recuento de números pentagonales.


Fig. 3 – Disposición para el recuento de números pentagonales.

La cantidad de puntos en la región sombreada del (k-)ésimo número pentagonal sería

\begin{equation*}1+2+3+\ldots+k=\frac{k\left(k+1\right)}{2}\end{equation*}

mientras que en las regiones restantes su cuantía ascendería a

\begin{equation*}2\left(1+2+3+\ldots+k-1\right)=2\cdot\frac{\left(k-1\right)k}{2}= \left(k-1\right)k\end{equation*}

Por consiguiente, el total valdría

\begin{equation*} \frac{k\left(k+1\right)}{2}+\left(k-1\right)k=\frac{k\left(3k-1\right)}{2}\end{equation*}

como esperábamos.

Los números pentagonales generalizados se obtienen al admitir valores negativos de k; en concreto, como lo habíamos apuntado ya en \left(14\right), su sucesión dimana de tomar k=1,-1,2,-2,3,-3,\ldots .

Entendido esto, es evidente que podemos escribir \left(2\right) como

\small \begin{equation*}\def\arraystretch{1.75} \begin{array}{rcl}  p\left(n\right)&=&  p\left(n-\omega\left(1\right)\right)+  p\left(n-\omega\left(-1\right)\right)-  p\left(n-\omega\left(2\right)\right)-  p\left(n-\omega\left(-2\right)\right)+\ldots\\  &&+  p\left(n-\omega\left(3\right)\right)+  p\left(n-\omega\left(-3\right)\right)-  p\left(n-\omega\left(4\right)\right)-  p\left(n-\omega\left(-4\right)\right)+\ldots \end{array}\end{equation*}

O, mejor aún, estableciendo que

\begin{equation}p\left(m\right)=0, \hspace{5mm}m<0\end{equation}

es posible expresar la relación de recurrencia como la serie

\begin{equation}\fcolorbox{MediumSlateBlue}{Cornsilk}{\(\hspace{4.5mm}\displaystyle p\left(n\right)=\sum_{k=1}^{\infty}\left(-1\right)^{k+1}\left[p\left(n-\omega\left(k\right)\right)+p\left(n-\omega\left(-k\right)\right)\vphantom{\Big|}\right]\vphantom{\Bigg|_{\bigg|}^{\bigg|}}\hspace{4.5mm}\)}\end{equation}

El lector quizás se sorprenderá de que aún disponiendo de la elegante expresión recursiva recién hallada, nos decantemos por un método iterativo para su implementación en Python.

La razón estriba en la descomunal cantidad de llamadas que se requerirían en el primer caso.

Detallamos enseguida nuestra propuesta.


import math
import numpy as np
from prettytable import PrettyTable

# Función para el cálculo de números pentagonales.
def omega(n):
return (3*n**2 - n) // 2

def p(n):
#
# Designaremos por 'P' a la lista cuyo k-ésimo término será
# el valor de p(k).

P = [1]
# Su inicialización obedece al hecho de que se ha definido
# P[0] = 1.

# -------------------------------------------------------------
# Ahora bien, como pretendemos determinar el resto de sus
# elementos en virtud de la relación

#
# P[n] = P[n-1] + P[n-2] - P[n-5] - P[n-7] + P[n-12] + ...
# + P[n-15] - P[n-22] - P[n-26] + ...

#
# debemos conocer primero los valores de las diferencias
# n-1, n-2, n-5, n-7, n-12, n-15, n-22, n-26, ...

#
# Así pues, llamaremos 'argumentos_no_negativos' a una lista
# a su vez conformada por 'n' sublistas, cuyos elementos serán
# las sucesiones de las diferencias entre '1, 2, ..., n' y el
# k-ésimo número pentagonal generalizado, siempre que estas
# sean positivas o, a lo sumo, nulas.

# -------------------------------------------------------------
# Por otro lado, precisamos de un adecuado manejo en la
# alternancia de signos.

# Como los sucesivos valores de la función de partición yacen
# en una lista, bastará multiplicarla por otra cuyos elementos
# sean los de la sucesión 1, 1, -1, -1, 1, 1, -1, -1, ...
# Tal tiene por k-ésimo término a (-1)^(k//2).
# La lista citada, 'signos' será llamada.


argumentos_no_negativos = []
signos = []
for i in range(1, n + 1):
sublista_a = []
sublista_b = []
for j in range(int((1 + math.sqrt(24*i + 1)) / 6) -
int((1 - math.sqrt(24*i + 1)) / 6)):
if j % 2 == 0:
k = (j + 2) // 2
sublista_a.append(i - omega(k))
else:
k = -(j + 1) // 2
sublista_a.append(i - omega(k))
sublista_b.append((-1)**(j // 2))
argumentos_no_negativos.append(sublista_a)
signos.append(sublista_b)

# -------------------------------------------------------------
m = 1
while (m <= n):
# Para poder construir los P[n] en orden creciente,
# conviene invertir el orden de cada una de las sublistas
# que constituyen las listas declaradas fuera del ciclo.
# Evitamos así posibles referencias a valores aún no
# calculados.

args = argumentos_no_negativos[m-1][::-1]
sgns = signos[m-1][::-1]

# ---------------------------------------------------------
# Finalmente, no resta más que hallar para el valor de
# 'm' en cuestión, la suma de todos los productos de la
# forma

# signs[i]*P[args[i], con i = 0, 1, 2, ..., len(args[m]).
# Dichos productos estarán contenidos en la lista
# auxiliar 'elementos_individuales'.


elementos_individuales = []
for i in range(len(args)):
elementos_individuales.append(sgns[i]*P[args[i]])

P.append(sum(elementos_individuales))
m += 1

return P[-1]

Para probar su correcto funcionamiento, mostramos a continuación los primeros 100 valores de p\left(n\right). Puede corroborarse que son los mismos que los de la secuencia A000041 de la OEIS (La Enciclopedia On-Line de las Secuencias de Números Enteros).

A000041 = []

for i in range(100):
A000041.append(p(i))

# Cálculos para especificar el formato de salida.
l = len(str(max(A000041))) + 2
n = 56 // l # número de filas.
m = len(A000041) // n # número de columnas.
if m * n < len(A000041):
m += 1
M = np.zeros((m, n), dtype = int)
k = 0
for i in range(m):
for j in range(n):
if k < len(A000041):
M[i,j] = A000041[k]
k += 1
print(M)
Salida
[[        1         1         2         3         5]
[ 7 11 15 22 30]
[ 42 56 77 101 135]
[ 176 231 297 385 490]
[ 627 792 1002 1255 1575]
[ 1958 2436 3010 3718 4565]
[ 5604 6842 8349 10143 12310]
[ 14883 17977 21637 26015 31185]
[ 37338 44583 53174 63261 75175]
[ 89134 105558 124754 147273 173525]
[ 204226 239943 281589 329931 386155]
[ 451276 526823 614154 715220 831820]
[ 966467 1121505 1300156 1505499 1741630]
[ 2012558 2323520 2679689 3087735 3554345]
[ 4087968 4697205 5392783 6185689 7089500]
[ 8118264 9289091 10619863 12132164 13848650]
[ 15796476 18004327 20506255 23338469 26543660]
[ 30167357 34262962 38887673 44108109 49995925]
[ 56634173 64112359 72533807 82010177 92669720]
[104651419 118114304 133230930 150198136 169229875]]


Naturalmente, aún hemos de ocuparnos de nuestro objetivo. Usaremos con este propósito el siguiente algoritmo exploratorio.


# Algoritmo de exploración
n = 75000
m = n
limite_sup = 3*n
encontrado = False

while(m <= limite_sup and encontrado == False):
i = 0
for elemento in sucesion_de_valores_de_p(n):
if elemento % 10**6 == 0:
print(f'i:{i:>5},\np({{i}}) = {{str(elemento)}}')
encontrado = True
break
i += 1
if m == limite_sup and encontrado == False:
print(f"No hay ningún valor de n para el que "
f"1 000 000 | p(n).\n"
f"Incremente el valor de n o el del límite "
f"superior de búsqueda.")
m += n

Como puede intuirse del bloque condicional que sigue al bucle \texttt{for}, la cota superior de búsqueda para n se eligió de forma empírica.

El ingente resultado es

\small\begin{align*}p(55\;374) = & \; \phantom{0}36\;325\;300\;925\;435\;785\;930\;832\;331\;577\;396\;761\;646\;715\;836\;173 \\& \; 633\;893\;227\;071\;086\;460\;709\;268\;608\;053\;489\;541\;731\;404\;543\;537 \\& \; 668\;438\;991\;170\;680\;745\;272\;159\;154\;493\;740\;615\;385\;823\;202\;158 \\& \; 167\;635\;276\;250\;554\;555\;342\;115\;855\;424\;598\;920\;159\;035\;413\;044 \\& \; 811\;245\;082\;197\;335\;097\;953\;570\;911\;884\;252\;410\;730\;174\;907\;784 \\& \; 762\;924\;663\;654\;000\;000\end{align*}

Al escribirlo en notación científica advertimos mejor sus proporciones

\begin{equation*}p(55\;374) \approx 3.6\times 10^{256}\end{equation*}

Esta es una cantidad superior al cuadrado de un gúgol3.

En suma, la tan ansiada respuesta es

\begin{equation}\fcolorbox{SlateBlue}{AliceBlue}{$\hspace{5mm}n=55\;374\vphantom{\Bigg|_{|}^{|}}\hspace{5mm}$}\end{equation}

Por supuesto, el procedimiento que presentamos no es único. La creatividad puede conducirnos por rumbos bien diversos.

Ofrecemos al lector interesado un método recursivo para descomponer enteros en todas sus particiones no restrictivas posibles.


def mostrar_particiones(l, n, p, v = None, P = None, i = 0):
'''
INPUTS:

- "n" es el número de monedas cuyas particiones deseamos
conocer. Se trata, por lo tanto, de un entero positivo.
- "l", la lista que almacena la sucesión de los enteros
positivos menores o iguales que el valor de "n" en la
primera llamada de la función.
Es, consecuentemente, un objeto inmutable.
- "p" es el valor de p(n); i.e., el número de particiones
no restrictivas de "n".
- "v", el vector que contiene a los escalares a[0], a[1],
a[2],..., a[n-1], que satisfacen la ecuación diofántica

a[0] + 2a[1] + 3a[2]... + n·a[n-1] = n

Inicialmente debe ser una lista vacía.
- "P" es la lista que albergará las posibles
representaciones de "n".
La conformarán todos los vectores "v" para los que se
haya concretado un caso base satisfactorio.
- "i" es el contador auxiliar empleado para recorrer "l".

OUTPUTS:

- Se devuelve un recuadro que contiene todas las
representaciones posibles de "n".

'''

N = len(l)
if v is None: v = []
if P is None: P = []

# CASO BASE SATISFACTORIO:
# Este algoritmo recursivo disminuye sucesivamente el valor
# primero de 'n', restándole múltiplos de los enteros
# contenidos en 'l'.
# Si la diferencia resulta nula, habremos dado con una
# partición de 'n'.

if n == 0:
# Para expresar la representación recién hallada como
# cadena de caracteres (v.g, 5 = 2 + 1 + 1 + 1), debemos
# establecer una correspondencia entre las listas 'v' y
# 'l' .
# A título de ejemplo, si fuese n = 5, tras cierto número
# de llamadas a la función podríamos obtener la
# combinación
# v = [1, 2, 0, 0, 0]
# l = [1, 2, 3, 4, 5]
# Esto supone que, en esta partición, el entero l[0] = 1
# puede aparecer 1 vez, pues v[0] = 1, mientras que
# l[1] = 2 puede aparecer dos veces. Es decir, que
# podemos expresar 5 como 2 + 2 + 1.
# Nos interesa pues conocer los índices (i. e, las
# posiciones) de los elementos no nulos de 'v'.
# A tal efecto, nos serviremos del método 'nonzero' de
# NumPy para identificarlos.
# Una vez hecho esto, construiremos una nueva lista en la
# que aparecerá repetido cada l[i] no nulos tantas veces
# como lo indique v[i]. A tal la llamaremos 'solucion'.
solucion = []
for i in range(len(np.nonzero(v)[0])):
# Llamaremos 'j' al número de veces que aparece el
# elemento no nulo de "l" en la posición
# np.nonzero(v)[0][i]
j = v[np.nonzero(v)[0][i]]
while(j > 0):
# En tanto "j" sea positivo, se añadirán copias
# del correspondiente valor de 'l'.
# Insistimos, una copia por iteración.
solucion.append(l[np.nonzero(v)[0][i]])
# Tras cada adición, la cuenta disminuye en una
# unidad.
j -= 1
# Una vez conformada la nueva solución, la dispondremos
# en orden decreciente y la incorporamos a la lista de
# representaciones, P.
P.append(solucion[::-1])
return

# CASOS BASE PRESCINDIBLES:
# Si las sucesivas sustracciones derivan en un número negativo
# o se han efectuado hasta N sustracciones sin llegar al cero,
# la combinación hallada es inviable.

if n < 0 or i == len(l):
return
# -------------------------------------------------------------

# Llamaremos 'k_max' al máximo número de veces que l[i] puede
# aparecer en una representación de 'n'
k_max = N // l[i]
# Nótese que podríamos haber escrito equivalentemente
# l[-1] // l[i], pues tanto N = len(l) como l[-1] se
# corresponden con el valor de 'n' pasado en la primera
# llamada.

# Si l = [1,2,3,4,5], entonces los posibles valores de 'k_max'
# serán, en virtud del valor del contador 'i' al invocar la
# función: 5//1, 5//2, 5//3, 5//4 y 5//5, que, respectivamente,
# valen, 5, 2, 1, 1, 1.

# ALGORITMO RECURSIVO:
# Las llamadas sucesivas de la función dentro de un ciclo nos
# permiten crear listas de posibles soluciones que
# eventualmente alcanzarán un caso base admisible o uno
# descartable.
# Estas se constituyen incorporando a su estructura al escalar
# 'k', que, según la iteración en la que el ciclo se encuentre,
# multiplica al elemento l[i].
nueva_solucion = []
for k in range(k_max + 1):
nueva_solucion = v + [k] # Adición de nuevos elementos.
mostrar_particiones(l,
n - k*l[i],
p,
nueva_solucion,
P,
i + 1)

# -------------------------------------------------------------

# Construcción de la tabla de salida:
# Este último proceso inicia en cuanto P tiene tantos
# elementos como el valor de p(n).
if len(P) == p:
P = sorted(P)
# Cada sublista_a de P será transformada en una cadena de
# caracteres en la que, a fin de conseguir una mayor
# claridad, se insertarán entre sus elementos signos '+'.
S = []
j = 0
for elemento in P:
s = str(N) + ' = '
for i in range(len(elemento)):
s += str(P[j][i])
if i < len(elemento) - 1:
s += ' + '
S.append(s)
j += 1
tabla = PrettyTable()
tabla.field_names = ['i', 'i-ésima representación']
tabla.align['i-ésima representación'] = "l"
# Finalmente, damos salida a los resultados:
for i in range(p):
tabla.add_row([i + 1, S[p - 1 - i]])
return(tabla)

Para esclarecer su funcionamiento llamaremos a la función reiteradamente mediante un ciclo. Generaremos así las particiones de los enteros comprendidos entre 1 y 10, ambos inclusive.




for n in range(1, 11):
print(mostrar_particiones([i for i in range(1, n + 1)],
n,
p(n),
v = None,
P = None,
i = 0))



Salida

+---+------------------------+
| i | i-ésima representación |
+---+------------------------+
| 1 | 1 = 1 |
+---+------------------------+
+---+------------------------+
| i | i-ésima representación |
+---+------------------------+
| 1 | 2 = 2 |
| 2 | 2 = 1 + 1 |
+---+------------------------+
+---+------------------------+
| i | i-ésima representación |
+---+------------------------+
| 1 | 3 = 3 |
| 2 | 3 = 2 + 1 |
| 3 | 3 = 1 + 1 + 1 |
+---+------------------------+
+---+------------------------+
| i | i-ésima representación |
+---+------------------------+
| 1 | 4 = 4 |
| 2 | 4 = 3 + 1 |
| 3 | 4 = 2 + 2 |
| 4 | 4 = 2 + 1 + 1 |
| 5 | 4 = 1 + 1 + 1 + 1 |
+---+------------------------+
+---+------------------------+
| i | i-ésima representación |
+---+------------------------+
| 1 | 5 = 5 |
| 2 | 5 = 4 + 1 |
| 3 | 5 = 3 + 2 |
| 4 | 5 = 3 + 1 + 1 |
| 5 | 5 = 2 + 2 + 1 |
| 6 | 5 = 2 + 1 + 1 + 1 |
| 7 | 5 = 1 + 1 + 1 + 1 + 1 |
+---+------------------------+
+----+---------------------------+
| i | i-ésima representación |
+----+---------------------------+
| 1 | 6 = 6 |
| 2 | 6 = 5 + 1 |
| 3 | 6 = 4 + 2 |
| 4 | 6 = 4 + 1 + 1 |
| 5 | 6 = 3 + 3 |
| 6 | 6 = 3 + 2 + 1 |
| 7 | 6 = 3 + 1 + 1 + 1 |
| 8 | 6 = 2 + 2 + 2 |
| 9 | 6 = 2 + 2 + 1 + 1 |
| 10 | 6 = 2 + 1 + 1 + 1 + 1 |
| 11 | 6 = 1 + 1 + 1 + 1 + 1 + 1 |
+----+---------------------------+
+----+-------------------------------+
| i | i-ésima representación |
+----+-------------------------------+
| 1 | 7 = 7 |
| 2 | 7 = 6 + 1 |
| 3 | 7 = 5 + 2 |
| 4 | 7 = 5 + 1 + 1 |
| 5 | 7 = 4 + 3 |
| 6 | 7 = 4 + 2 + 1 |
| 7 | 7 = 4 + 1 + 1 + 1 |
| 8 | 7 = 3 + 3 + 1 |
| 9 | 7 = 3 + 2 + 2 |
| 10 | 7 = 3 + 2 + 1 + 1 |
| 11 | 7 = 3 + 1 + 1 + 1 + 1 |
| 12 | 7 = 2 + 2 + 2 + 1 |
| 13 | 7 = 2 + 2 + 1 + 1 + 1 |
| 14 | 7 = 2 + 1 + 1 + 1 + 1 + 1 |
| 15 | 7 = 1 + 1 + 1 + 1 + 1 + 1 + 1 |
+----+-------------------------------+
+----+-----------------------------------+
| i | i-ésima representación |
+----+-----------------------------------+
| 1 | 8 = 8 |
| 2 | 8 = 7 + 1 |
| 3 | 8 = 6 + 2 |
| 4 | 8 = 6 + 1 + 1 |
| 5 | 8 = 5 + 3 |
| 6 | 8 = 5 + 2 + 1 |
| 7 | 8 = 5 + 1 + 1 + 1 |
| 8 | 8 = 4 + 4 |
| 9 | 8 = 4 + 3 + 1 |
| 10 | 8 = 4 + 2 + 2 |
| 11 | 8 = 4 + 2 + 1 + 1 |
| 12 | 8 = 4 + 1 + 1 + 1 + 1 |
| 13 | 8 = 3 + 3 + 2 |
| 14 | 8 = 3 + 3 + 1 + 1 |
| 15 | 8 = 3 + 2 + 2 + 1 |
| 16 | 8 = 3 + 2 + 1 + 1 + 1 |
| 17 | 8 = 3 + 1 + 1 + 1 + 1 + 1 |
| 18 | 8 = 2 + 2 + 2 + 2 |
| 19 | 8 = 2 + 2 + 2 + 1 + 1 |
| 20 | 8 = 2 + 2 + 1 + 1 + 1 + 1 |
| 21 | 8 = 2 + 1 + 1 + 1 + 1 + 1 + 1 |
| 22 | 8 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
+----+-----------------------------------+
+----+---------------------------------------+
| i | i-ésima representación |
+----+---------------------------------------+
| 1 | 9 = 9 |
| 2 | 9 = 8 + 1 |
| 3 | 9 = 7 + 2 |
| 4 | 9 = 7 + 1 + 1 |
| 5 | 9 = 6 + 3 |
| 6 | 9 = 6 + 2 + 1 |
| 7 | 9 = 6 + 1 + 1 + 1 |
| 8 | 9 = 5 + 4 |
| 9 | 9 = 5 + 3 + 1 |
| 10 | 9 = 5 + 2 + 2 |
| 11 | 9 = 5 + 2 + 1 + 1 |
| 12 | 9 = 5 + 1 + 1 + 1 + 1 |
| 13 | 9 = 4 + 4 + 1 |
| 14 | 9 = 4 + 3 + 2 |
| 15 | 9 = 4 + 3 + 1 + 1 |
| 16 | 9 = 4 + 2 + 2 + 1 |
| 17 | 9 = 4 + 2 + 1 + 1 + 1 |
| 18 | 9 = 4 + 1 + 1 + 1 + 1 + 1 |
| 19 | 9 = 3 + 3 + 3 |
| 20 | 9 = 3 + 3 + 2 + 1 |
| 21 | 9 = 3 + 3 + 1 + 1 + 1 |
| 22 | 9 = 3 + 2 + 2 + 2 |
| 23 | 9 = 3 + 2 + 2 + 1 + 1 |
| 24 | 9 = 3 + 2 + 1 + 1 + 1 + 1 |
| 25 | 9 = 3 + 1 + 1 + 1 + 1 + 1 + 1 |
| 26 | 9 = 2 + 2 + 2 + 2 + 1 |
| 27 | 9 = 2 + 2 + 2 + 1 + 1 + 1 |
| 28 | 9 = 2 + 2 + 1 + 1 + 1 + 1 + 1 |
| 29 | 9 = 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
| 30 | 9 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
+----+---------------------------------------+
+----+--------------------------------------------+
| i | i-ésima representación |
+----+--------------------------------------------+
| 1 | 10 = 10 |
| 2 | 10 = 9 + 1 |
| 3 | 10 = 8 + 2 |
| 4 | 10 = 8 + 1 + 1 |
| 5 | 10 = 7 + 3 |
| 6 | 10 = 7 + 2 + 1 |
| 7 | 10 = 7 + 1 + 1 + 1 |
| 8 | 10 = 6 + 4 |
| 9 | 10 = 6 + 3 + 1 |
| 10 | 10 = 6 + 2 + 2 |
| 11 | 10 = 6 + 2 + 1 + 1 |
| 12 | 10 = 6 + 1 + 1 + 1 + 1 |
| 13 | 10 = 5 + 5 |
| 14 | 10 = 5 + 4 + 1 |
| 15 | 10 = 5 + 3 + 2 |
| 16 | 10 = 5 + 3 + 1 + 1 |
| 17 | 10 = 5 + 2 + 2 + 1 |
| 18 | 10 = 5 + 2 + 1 + 1 + 1 |
| 19 | 10 = 5 + 1 + 1 + 1 + 1 + 1 |
| 20 | 10 = 4 + 4 + 2 |
| 21 | 10 = 4 + 4 + 1 + 1 |
| 22 | 10 = 4 + 3 + 3 |
| 23 | 10 = 4 + 3 + 2 + 1 |
| 24 | 10 = 4 + 3 + 1 + 1 + 1 |
| 25 | 10 = 4 + 2 + 2 + 2 |
| 26 | 10 = 4 + 2 + 2 + 1 + 1 |
| 27 | 10 = 4 + 2 + 1 + 1 + 1 + 1 |
| 28 | 10 = 4 + 1 + 1 + 1 + 1 + 1 + 1 |
| 29 | 10 = 3 + 3 + 3 + 1 |
| 30 | 10 = 3 + 3 + 2 + 2 |
| 31 | 10 = 3 + 3 + 2 + 1 + 1 |
| 32 | 10 = 3 + 3 + 1 + 1 + 1 + 1 |
| 33 | 10 = 3 + 2 + 2 + 2 + 1 |
| 34 | 10 = 3 + 2 + 2 + 1 + 1 + 1 |
| 35 | 10 = 3 + 2 + 1 + 1 + 1 + 1 + 1 |
| 36 | 10 = 3 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
| 37 | 10 = 2 + 2 + 2 + 2 + 2 |
| 38 | 10 = 2 + 2 + 2 + 2 + 1 + 1 |
| 39 | 10 = 2 + 2 + 2 + 1 + 1 + 1 + 1 |
| 40 | 10 = 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 |
| 41 | 10 = 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
| 42 | 10 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 |
+----+--------------------------------------------+


  • Rossen, Keneth H. (2011). Elementary number theory and its applications. Pearson.
  • Tattersall, James J. (2005). Elementary Number Theory in Nine Chapters. Cambridge University Press.
  • Project Euler. (s.f.). Problem 78: Coin Partitions. Recuperado el 26 de mayo de 2025, de https://projecteuler.net/problem=78.
  1. Aunque existen distintas convenciones para su trazo, habitualmente se utilizan los traspuestos de los ilustrados aquí; esto es, los que resultan de intercambiar filas por columnas. ↩︎
  2. Con mayor formalidad al no estarnos impedida la repetición de elementos, nos referiremos a p\left(n\right) como una función de partición no restrictiva. ↩︎
  3. Un gúgol (del inglés googol) equivale a 10^{100}. ↩︎

    Related posts

    Japón adopta medidas para combatir adicción hacia smartphones

    Daniel Hernández Carreto

    Sheinbaum asume el peso total del gobierno: resultados, soberanía y el avance de la transformación

    Meme Yamel

    IPMA premia a Dos Bocas como tercer mejor proyecto a nivel mundial

    Daniel Hernández Carreto