Sharedcannonballs.ipynbOpen in CoCalc
Author: Peter Francis
Views : 44

${\Huge \text{Cannonball Numbers}}$

An $n$-gon number is a type of figurate number that is a generalization of triangular, square, etc., to an $n$-gon for n an arbitrary positive integer. The $m$th $n$-gon numbers is the number of cannonballs that can be arranged to form a filled in regular $n$-gon of side length $m$. For example, the first few hexagon numbers are $1,6,15,28$, and $45$.

The $m$th $n$-gon pyramidal number is the sum of the first $m$ $n$-gon numbers and correspond to the number of cannonballs needed to construct a solid pyramid with $m$ filled-in $n$-gon layers. For example, the first few hexagon pyramidal numbers are $1,7,22,50,95$, and $161$.

We want to ask: For a given $n$, what number of cannonballs can be arranged in a solid $n$-gon based pyramid and rearranged to make a flat, filled-in $n$-gon? Equivalently, which $n$-gon numbers are also $n$-gon pyramidal numbers?

This (when $n=4$) is commonly known as the Cannonball Problem. If a number satisfies this condition, it is known as a cannonball number.

Below, we will investigate this idea for $n=5$ and $n=6$ and extend the cannonball number to $n\neq 4$.

E = EllipticCurve([1,12,4,1])
print(E)
E.integral_points()
# [(1 : 2 : 1)]
# E.S_integral_points([2])
# [(-103/64 : -233/512 : 1), (1 : 2 : 1)]


$\Large \text{Existence of Cannonball Numbers}$

Recall that the $m$th $n$-gon number is given by $N^{(m)}_n=\frac{m[(m-1)n-2(m-2)]}{2},$ and the $m$th $n$-gon pyramidal number is given by $P^{(m)}_n=\frac{m(m+1)[(n-2)m+(5-n)]}{6}.$

A number $c$ is an $n$-gon cannonball number if and only if it is the $a$th $n$-gon number and the $b$th $n$-gon pyramidal number, for some integers $a$ and $b$, greater than 1. Equivalently,

$\frac{a[(a-1)n-2(a-2)]}{2}=N_n^{(a)}=c=P_n^{(b)}=\frac{b(b+1)[(n-2)b+(5-n)]}{6}$ $\Updownarrow$ $3a[(a-1)n-2(a-2)]=b(b+1)[(n-2)b+(5-n)]$

must have a solution $(a,b)$, with $a,b\in\mathbb{N}\setminus\{1\}$.

$\large \text{Diophantine Equations}$

For each of the following equations, for each solution $(a,b)$, with $a,b\in\mathbb{N}\setminus\{1\}$, there exists a cannonball number $c=N^{(a)}_n=P^{(b)}_n$.

For $n=3$: $3a^2+3a= b^3+3b^2 +2b$ For $n=4$: $6a^2=2b^3+3b^2+b$ For $n=5$: $3a^2-a=b^3+b^2$ For $n=6$: $12a^2-6a=4b^3+3b^2-b$ For $n=7$: $15a^2-9a=5b^3+3b^2-2b$

$\large \text{There is no Cannonball Number for } n=5.$

If there exists a pentagon cannonball number, $1 < c\in\mathbb{N}$. Then there would exist $a,b\in\mathbb{N}$ for which the $a$th pentagon number is the $b$th pentagon pyramidal number. Equivalently, there must exist an $a,b\in\mathbb{N}\setminus\{1\}$ for which.

${\Large \text{Python Investigation}}$

Using the quadradic formula for $N_n^{(m)}=\frac{m[(m-1)n-2(m-2)]}{2}$ to solve for $m$, we have that $r$ is an $n$-gon number if and only if $\frac{\frac{n-4}{2}\pm\sqrt{\left(\frac{4-n}{2}\right)^2+2r\left(n-2\right)}}{n-2}\in \mathbb{N}.$ I use this fact for the isPN function.

In [4]:
import numpy as np
from numba import njit

In [3]:
def N(m,n):                   # returns the mth n-gon number
return  m*((m-1)*n-2*(m-2))//2     # integer division is ok

def PN(m,n):                  # returns the mth n-gon pyramidal number
if n < 3: return -1
else: return  (m*(m+1)*((n-2)*m+(5-n)))//6     # integer division is ok

def isN(r,n):                 # verifies if r is a n-gon number
i = (((n-4)/(2)) + np.sqrt(((4-n)/(2))**2+2*r*(n-2)))/(n-2)
j = (((n-4)/(2)) - np.sqrt(((4-n)/(2))**2+2*r*(n-2)))/(n-2)
if (i % 1 == 0) and i > 0:
return (True, int(i))
if (j % 1 == 0) and j > 0:
return (True, int(j))
return (False, -1)

def isPN(r,n):                # verifies if r is a n-gon pyramidal number
bool = False
i = 1
while not bool and i <= r:
if PN(i,n) == r:
return (True, i)
i = i + 1
return (False, -1)

def check_for_cannonballs(lowerbound, upperbound, n, breakIfFound):
for i in range(lowerbound,upperbound+1):
test = isN(PN(i,n),n)
if test[0] and (N(test[1],n)==PN(i,n)):  # the second condition is a dummy check to make sure there are no rounding errors
print(f'{PN(i,n)} is an {n}-gon cannonball number: {PN(i,n)} is the {test[1]} {n}-gon number and the {i} {n}-gon pyramidal number.')
if breakIfFound:
break
if not breakIfFound:
print(f'No others found.')

In [14]:
check_for_cannonballs(2,100,3,False)

10 is an 3-gon cannonball number: 10 is the 4 3-gon number and the 3 3-gon pyramidal number. 120 is an 3-gon cannonball number: 120 is the 15 3-gon number and the 8 3-gon pyramidal number. 1540 is an 3-gon cannonball number: 1540 is the 55 3-gon number and the 20 3-gon pyramidal number. 7140 is an 3-gon cannonball number: 7140 is the 119 3-gon number and the 34 3-gon pyramidal number. No others found.