You are currently browsing the category archive for the ‘computing’ category.

Chaos and strange Attractors: Henon’s map

Henon’s map was created in the 1970s to explore chaotic systems.  The general form is created by the iterative formula:

The classic case is when a = 1.4 and b = 0.3 i.e:

To see how points are generated, let’s choose a point near the origin.  If we take (0,0) the next x coordinate is given by:

We would then continue this process over several thousands iterations.  If we do this then we get the very strange graph at the top of the page – the points are attracted to a flow like structure, which they then circulate round.  The graph above was generated when we took our starting coordinate as (0.1,0.1), let’s take a different starting point.  This time let’s have (1.1, 1.1):

  We can see that exactly the same structure appears.  All coordinates close to the origin will get attracted to this strange attractor – except for a couple of fixed points near the origin which remain where they are.  Let’s see why.  First we can rewrite the iterative formula just in terms of x:

Next we use the fact that when we have a fixed point the x coordinate (and y coordinate) will not change.  Therefore we can define the following:

This allows us to then make the following equation:

Which we can then solve using the quadratic formula:

Which also gives y:

So therefore at these 2 fixed points the coordinates do not get drawn to the strange attractor.

Above we can see the not especially interesting graph of the repeated iterations when starting at this point!

But we can also see the chaotic behavior of this system by choosing a point very close to this fixed point.  Let’s choose (0.631354477, 0.631354477) which is correct to 9 decimal places as an approximation for the fixed point.  

We can see our familiar graph is back.  This is an excellent example of chaotic  behavior – a very small change in the initial conditions has created a completely different system.

This idea was suggested by the excellent Doing Maths With Python – which is well worth a read if you are interested in computer programing to solve mathematical problems.

Finding the average distance between 2 points on a hypercube

This is the natural extension from this previous post which looked at the average distance of 2 randomly chosen points in a square – this time let’s explore the average distance in n dimensions.  I’m going to investigate what dimensional hypercube is required to have an average distance of more than one, and then also what happens to the average distance as n approaches infinity.

Monte Carlo method

The Monte Carlo method is a very powerful technique which utilizes computational power.  Basically we use the fact that the average of a very large number of trials will serve as an approximation to an exact result.  In this case I will run a Python program 10 million times – each time it will select 2 coordinate points and then work out the distance between them.  It will then find the average of these 10 million trials.  The code above generates 2 coordinates in 3 dimensional space inside a unit cube.  We can modify this for n-dimensional space by remembering that Pythagoras still works in higher dimensions.  


Running this code helps to generate the above results.  This answers our first question – we need a 7 dimensional unit hypercube until the average distance between two randomly chosen points is greater than 1.  We can also see that the difference between the average distances is reducing – but it’s not clear if this will approach a limit or if it will continue growing to infinity.  So let’s do some more trials.

Further trials

This takes us up to a 22-dimensional hypercube.  At this point it’s probably useful to plot a graph to see the trend.

Reciprocal model


This reciprocal model is of the form:

We can see that this is a pretty good fit (R squared 0.9994).  If this model is accurate then this would suggest that the average distance approaches a limit as n approaches infinity.

Polynomial model

This polynomial model is of the form:

We can see that this is also a very good fit (R squared 0.9997).  If this model is accurate then as b is greater than 0, this would suggest that the average distance approaches infinity as n approaches infinity.


Quite annoyingly we have 2 model which both fit the data very accurately – but predict completely different results!  Logically we could probably say that we would expect the average distance to approach infinity as n approaches infinity – and also we could possibly justify this by the fact that the polynomial model is a slightly better fit.  Given the similarity between the 2 models it probably time to find out the actual results for this.

Average n-dimensional distance bounds

Not surprisingly the mathematics required to work this out is exceptionally difficult – and ends up with non-solvable integrals which require analytic solutions.  The Monte Carlo method with very large numbers of trials is a reasonably good approach to approximating this answer.  There is however a very useful lower and upper bound for the average distance in n dimensional space given by:

This shows immediately that the average distance will approach infinity as n grows large – as the lower bound will grow to infinity.  Quite pleasingly we can see that the polynomial model we derived is similar to the lower bound.  We can plot both upper and lower bound along with our polynomial model to see how these all compare.  We have lower bound (green), polynomial model (black) and upper bound (green):

We can see that our polynomial model very closely follows the upper bound in our domain.  As we extend the domain this polynomial approximation remains above the lower and tracks the upper bounds before gradually growing less accurate.  When n is 50 our model predicts a distance of 2.94, whereas the upper bound is 2.88.  This is quite a nice result – we have used the Monte Carlo method to derive a polynomial approximation to the average distance in n-dimensional hypercubes and it both closely follows the upper bound over a reasonable domain and also is of a very similar form to the lower bound.  We can use this lower bound to see that a 36 dimensional hypercube (and higher) would be guaranteed to have an average distance of more than 2.


This was a nice example of the power of the Monte Carlo method in these kind of problems – we were able to use it quite successfully to get a polynomial approximation which turned out to be reasonably accurate.  We could have significantly improved this accuracy by running 100 million (or 1 billion etc) trials each time – though this would have probably required a more powerful computer!

Generating e through probability and hypercubes

This is a really beautiful solution to an interesting probability problem posed by fellow IB teacher Daniel Hwang, for which I’ve outlined a method for solving suggested by Ferenc Beleznay.  The problem is as follows:

On average, how many random real numbers from 0 to 1 (inclusive) are required for the sum to exceed 1?

1 number

Clearly if we choose only 1 number then we can’t exceed 1.

2 numbers

Here we imagine the 2 numbers we pick as x and y and therefore we can represent them as a coordinate pair.  The smallest pair (0,0) and the largest pair (1,1).  This means that the possible coordinates fit inside the unit square shown above.  We want to know for what coordinate pairs we have the inequality x + y > 1.  This can be rearrange to give y > 1-x.  The line y = 1-x is plotted and we can see that any coordinate points in the triangle BCD satisfy this inequality.  Therefore the probability of a random coordinate pair being in this triangle is 1/2.

3 numbers

This time we want to find the probability that we exceed 1 with our third number.  We can consider the numbers as x, y, z and therefore as 3D coordinates (x,y,z).  From the fact that we are choosing a third number we must already have x +y <1. We draw the line x+y = 1, which in 3D gives us a plane.  The volume in which our coordinate point must lie is the prism ABDEFG.

We now also add the constraint x+y+z >1.  This creates the plane as shown.  If our coordinate lies inside the pyramid ABDE then our coordinates will add to less than 1, outside this they will add to more than 1.

The volume of the pyramid ABDE = 1/3 (base area)(perpendicular height).

The volume of the prism ABDEFG =  (base area)(perpendicular height).

Given that they share the same perpendicular height and base area then precisely 1/3 of the available volume would give a coordinate point that adds to less than 1, and 2/3 of the available volume would give a coordinate point that adds to more than 1.

Therefore we have the following tree diagram:

Exceeds 1 with 2 numbers = 1/2

Does not exceed 1 with 2 numbers, exceeds 1 with 3 numbers = 1/2 x 2/3 = 1/3.

Does not exceed 1 with 2 numbers, does not exceed 1 with 3 numbers = 1/2 x 1/3 = 1/6.

4 numbers

If you been following so far this is where things get interesting!  We can now imagine a 4 dimensional unit cube (image above from Wikipedia) and a 4D coordinate point (x,y,z,a).

Luckily all we care about is the ratio of the 4-D pyramid and the 4-D prim formed by our constraints x+y+z <1 and x+y+z+a >1.

We have the following formula to help:

The n-D volume of a n-D pyramid = 1/n (base)(perpendicular height).


The 4-D volume of a 4-D pyramid = 1/4 (base 3D volume)(perpendicular height).

The 4-D volume of the prism ABDEFG = (base 3D volume)(perpendicular height).

Given that the 2 shapes share the same base and perpendicular height,  the hyper-pyramid occupies exactly 1/4 of the 4-D space of the hyper-prism.  So the probability of being in this space is 1/4 and 3/4 of being outside this space.

We can now extend our tree diagram:

Does not exceed 1 with 2 numbers, does not exceed 1 with 3 numbers, exceeds with 4 numbers = 1/2 x 1/3 x 3/4 = 1/8

Does not exceed 1 with 2 numbers, does not exceed 1 with 3 numbers, does not exceed with 4 numbers = 1/2 x 1/3 x 1/4 = 1/24.

In general a hyper-pyramid in n dimensional space occupies exactly 1/n of the space of the hyper-prism – so we can now continue this tree diagram.

Expected value

We can make a table of probabilities to find how many numbers we expect to use in order to exceed one.

Which gives us the following expected value calculation:

Which we can rewrite as:

But we have:

Therefore this gives:

So on average we would need to pick numbers for the sum to exceed one! This is quite a remarkable result – e, one of the fundamental mathematical constants has appeared as if by magic on a probability question utilizing hyper-dimensional shapes.

Demonstrating this with Python

Running the Python code shown above will simulate doing this experiment.  The computer generates a “random” number, then another and carries on until the sum is greater than 1.  It then records how many numbers were required.  It then does this again 1 million times and finds the average from all the trials.

1 million simulations gives 2.7177797177797176.  When we compare this with the real answer for e, 2.7182818284590452353602874713527, we can see it has taken 1 million simulations to only be correct to 4sf.

Even 5 million simulations only gives 2.7182589436517888, so whilst we can clearly see that we will eventually get e, it’s converging very slowly.  This may be because we are reliant on a random number generator which is not truly random (and only chooses numbers to a maximum number of decimal places rather than choosing from all values between 0 and 1).

I think this is a beautiful example of the unexpected nature of mathematics – we started out with a probability problem and ended up with e, via a detour into higher dimensional space!  We can also see the power of computers in doing these kinds of brute force calculations.


Screen Shot 2020-08-29 at 6.57.23 PM

Have you got a Super Brain?

Adapting and exploring maths challenge problems is an excellent way of finding ideas for IB maths explorations and extended essays.  This problem is taken from the book: The first 25 years of the Superbrain challenges.  I’m going to see how many different ways I can solve it.

Screen Shot 2020-08-29 at 7.03.13 PM

The problem is to find all the integer solutions to the equation above.  Finding only integer solutions is a fundamental part of number theory – a branch of mathematics that only deals with integers.  

Method number 1: Brute force

Screen Shot 2020-08-29 at 7.05.45 PM

This is a problem that computers can make short work of.  Above I wrote a very simple Python program which checked all values of x and y between -99 and 99.  This returned the only solution pairs as:

Screen Shot 2020-08-29 at 7.07.41 PM

Clearly we have not proved these are the only solutions – but even by modifying the code to check more numbers, no more pairs were found.

Method number 2: Solving a linear equation

We can notice that the equation is linear in terms of y, and so rearrange to make y the subject.

Screen Shot 2020-08-29 at 7.43.24 PM

We can then use either polynomial long division or the method of partial fractions to rewrite this.  I’ll use partial fractions.  The general form for this fraction can be written as follows:

Screen Shot 2020-08-29 at 7.43.33 PM

Next I multiply by the denominator and the compare coefficients of terms.

Screen Shot 2020-08-29 at 7.43.40 PM

This therefore gives:

Screen Shot 2020-08-29 at 7.43.48 PM

I can now see that there will only be an integer solution for y when the denominator of the fraction is a factor of 6.  This then gives (ignoring non integer solutions):

Screen Shot 2020-08-29 at 7.43.53 PM

I can then substitute these back to find my y values, which give me the same 4 coordinate pairs as before:

Screen Shot 2020-08-29 at 7.07.41 PM

Method number 3: Solving a quadratic equation

I start by making a quadratic in x:

Screen Shot 2020-08-29 at 7.51.35 PM

I can then use the quadratic formula to find solutions:

Screen Shot 2020-08-29 at 7.51.41 PM

Which I can simplify to give:

Screen Shot 2020-08-29 at 7.51.46 PM

Next I can note that x will only be an integer solution if the expression inside the square root is a square number.  Therefore I have:

Screen Shot 2020-08-29 at 7.51.54 PM

Next I can solve a new quadratic as follows:

Screen Shot 2020-08-29 at 7.51.59 PM

Screen Shot 2020-08-29 at 7.52.05 PM

As before I notice that the expression inside my square root must be a square number.  Now I can see that I need to find m and n such that I have 2 square numbers with a difference of 24.  I can look at the first 13 square numbers to see that from the 12th and 13th square numbers onwards there will also be a difference of more than 24.  Checking this list I can find that m = 1 and m = 5 will satisfy this equation.

Screen Shot 2020-08-29 at 7.52.12 PM

This then gives:

Screen Shot 2020-08-29 at 7.52.18 PM

which when I solve for integer solutions and then sub back into find x gives the same four solutions:

Screen Shot 2020-08-29 at 7.07.41 PM

Method number 4: Graphical understanding

Without rearranging I could imagine this as a 3D problem by plotting the 2 equations:

Screen Shot 2020-08-29 at 8.01.31 PM

This gives the following graph:

Screen Shot 2020-08-29 at 6.57.23 PM

We can see that the plane intersects the curve in infinite places.  I’ve marked A, B on the graph to illustrate 2 of the coordinate pairs which we have found.  This is a nice visualization but doesn’t help find our coordinates, so lets switch to 2D.

In 2D we can use our rearranged equation:

Screen Shot 2020-08-29 at 8.03.50 PM

This gives the following graph:

Screen Shot 2020-08-29 at 8.04.47 PM

Here I have marked on the solution pairs that we found.   The oblique asymptote (red) is y = 2x-1 because as x gets large the fraction gets very small and so the graph gets closer and closer to y = 2x -1. 

All points on this curve are solutions to the equation – but we can see that the only integer solution pairs will be when x is small.  When x is a large integer then the curve will be close to the asymptote and hence will return a number slightly bigger than an integer.

So, using this approach we would check all possible integer solutions when x is small, and again should be able to arrive at our coordinate pairs.

So, 4 different approaches that would be able to solve this problem.  Can you find any others?


Sierpinski Triangle: A picture of infinity

This pattern of a Sierpinski triangle pictured above was generated by a simple iterative program.  I made it by modifying the code previously used to plot the Barnsley Fern. You can run the code I used on  What we are seeing is the result of 30,000 iterations of a simple algorithm.  The algorithm is as follows:

Transformation 1:

xi+1 = 0.5xi

yi+1= 0.5yi

Transformation 2:

xi+1 = 0.5xi + 0.5

yi+1= 0.5yi+0.5

Transformation 3:

xi+1 = 0.5xi +1

yi+1= 0.5yi

So, I start with (0,0) and then use a random number generator to decide which transformation to use.  I can run a generator from 1-3 and assign 1 for transformation 1, 2 for transformation 2, and 3 for transformation 3.   Say I generate the number 2 – therefore I will apply transformation 2.

xi+1 = 0.5(0) + 0.5

yi+1= 0.5(0)+0.5

and my new coordinate is (0.5,0.5).  I mark this on my graph.

I then repeat this process – say this time I generate the number 3.  This tells me to do transformation 3.  So:

xi+1 = 0.5(0.5) +1

yi+1= 0.5(0.5)

and my new coordinate is (1.25, 0.25).  I mark this on my graph and carry on again.  The graph above was generated with 30,000 iterations.

Altering the algorithm

We can alter the algorithm so that we replace all the 0.5 coefficients of x and y with another number, a.

a = 0.3 has disconnected triangles:

When a = 0.7 we still have a triangle:

By a = 0.9 the triangle is starting to degenerate

By a = 0.99 we start to see the emergence of a line “tail”

By a = 0.999 we see the line dominate.

And when a = 1 we then get a straight line:

When a is greater than 1 the coordinates quickly become extremely large and so the scale required to plot points means the disconnected points are not visible.

If I alternatively alter transformations 2 and 3 so that I add b for transformation 2 and 2b for transformation 3 (rather than 0.5 and 1 respectively) then we can see we simply change the scale of the triangle.

When b = 10 we can see the triangle width is now 40 (we changed b from 0.5 to 10 and so made the triangle 20 times bigger in length):

Fractal mathematics

This triangle is an example of a self-similar pattern – i.e one which will look the same at different scales.  You could zoom into a detailed picture and see the same patterns repeating.  Amazingly fractal patterns don’t fit into our usual understanding of 1 dimensional, 2 dimensional, 3 dimensional space.  Fractals can instead be thought of as having fractional dimensions.

The Hausdorff dimension is a measure of the “roughness” or “crinkley-ness” of a fractal.  It’s given by the formula:

D = log(N)/log(S)

For the Sierpinski triangle, doubling the size (i.e S = 2), creates 3 copies of itself (i.e N =3)

This gives:

D = log(3)/log(2)

Which gives a fractal dimension of about 1.59.  This means it has a higher dimension than a line, but a lower dimension than a 2 dimensional shape.


Sphere packing problem: Pyramid design

Sphere packing problems are a maths problems which have been considered over many centuries – they concern the optimal way of packing spheres so that the wasted space is minimised.  You can achieve an average packing density of around 74% when you stack many spheres together, but today I want to explore the packing density of 4 spheres (pictured above) enclosed in a pyramid.

Considering 2 dimensions


First I’m going to consider the 2D cross section of the base 3 spheres.  Each sphere will have a radius of 1.  I will choose A so that it is at the origin.  Using some basic Pythagoras this will give the following coordinates:

Finding the centre


Next I will stack my single sphere on top of these 3, with the centre of this sphere directly in the middle.  Therefore I need to find the coordinate of D.  I can use the fact that ABC is an equilateral triangle and so:

3D coordinates

Next I can convert my 2D coordinates into 3D coordinates.  I define the centre of the 3 base circles to have 0 height, therefore I can add z coordinates of 0.  E will be the coordinate point with the same x and y coordinates as D, but with a height, a, which I don’t yet know:

In order to find I do a quick sketch, seen below:

Here I can see that I can find the length AD using trig, and then the height DE (which is my a value) using Pythagoras:

Drawing spheres

The general equation for spheres with centre coordinate (a,b,c) and radius 1 is:

Therefore the equation of my spheres are:

Plotting these on Geogebra gives:



Drawing a pyramid

Next I want to try to draw a pyramid such that it encloses the spheres.  This is quite difficult to do algebraically – so I’ll use some technology and a bit of trial and error.

First I look at creating a base for my pyramid.  I’ll try and construct an equilateral triangle which is a tangent to the spheres:

This gives me an equilateral triangle with lengths 5.54. I can then find the coordinate points of F,G,H and plot them in 3D.  I’ll choose point E so that it remains in the middle of the shape, and also has a height of 5.54 from the base. This gives the following:

As we can see, this pyramid does not enclose the spheres fully.  So, let’s try again, this time making the base a little bit larger than the 3 spheres:



This gives me an equilateral triangle with lengths 6.6.  Taking the height of the pyramid to also be 6.6 gives the following shape:


This time we can see that it fully encloses the spheres.  So, let’s find the density of this packing.  We have:

Therefore this gives:

and we also have:

Therefore the density of our packaging is:

Given our diagram this looks about right – we are only filling less than half of the available volume with our spheres.

Comparison with real data


[Source: Minimizing the object dimensions in circle and sphere packing problems]

We can see that this task has been attempted before using computational power – the table above shows the average density for a variety of 2D and 3D shapes.  The pyramid here was found to have a density of 46% – so our result of 44% looks pretty close to what we should be able to achieve.  We could tweak our measurements to see if we could improve this density.

So, a nice mixture of geometry, graphical software, and trial and error gives us a nice result.  You could explore the densities for other 2D and 3D shapes and see how close you get to the results in the table.

Square Triangular Numbers

Square triangular numbers are numbers which are both square numbers and also triangular numbers – i.e they can be arranged in a square or a triangle.  The picture above (source: wikipedia) shows that 36 is both a square number and also a triangular number.  The question is how many other square triangular numbers we can find?

The equation we are trying to solve is:

a2 = 0.5(b2+b)

for some a, b as positive integers. The LHS is the formula to generate square numbers and the RHS is the formula to generate the triangular numbers.

We can start with some simple Python code (which you can run here):

for c in range(1,10001):
 for d in range(1,10001):
  if c**2 == (d**2+d)/2:
   print(c**2, c,d)

This checks the first 10000 square numbers and the first 10000 triangular numbers and returns the following:

1 1 1
36 6 8
1225 35 49
41616 204 288
1413721 1189 1681
48024900 6930 9800

i.e 1225 is the next square triangular number after 36, and can be formed as 352 or as 0.5(492+49). We can see that there are very few square triangular numbers to be found in the first 50 million numbers. The largest we found was 48,024,900 which is made by 69302 or as 0.5(98002+9800).

We can notice that the ratio between each consecutive pair of square triangular numbers looks like it converges as it gives:

36/1 = 36
1225/36 = 34.027778
41616/1225 = 33.972245
1413721/41616 = 33.970612
48024900/1413721 = 33.970564

So, let’s use this to predict that the next square triangular number will be around

48024900 x 33.9706 = 1,631,434,668.

If we square root this answer we get approximately 40391
If we solve 0.5(b2+b) = 1,631,434,668 using Wolfram we get approximately 57120.

Therefore let’s amend our code to look in this region:

for c in range(40380,40400):
 for d in range(57100,57130):
  if c**2 == (d**2+d)/2:
   print(c**2, c,d)

This very quickly finds the next solution as:

1631432881 40391 57121

This is indeed 403912 – so our approximation was very accurate. We can see that this also gives a ratio of 1631432881/48024900 = 33.97056279 which we can then use to predict that the next term will be 33.970563 x 1631432881 = 55,420,693,460. Square rooting this gives a prediction that we will use the 235,416 square number. 235,4162 gives 55,420,693,056 (using Wolfram Alpha) and this is indeed the next square triangular number.

So, using a mixture of computer code and some pattern exploration we have found a method for finding the next square triangular numbers. Clearly we will quickly get some very large numbers – but as long as we have the computational power, this method should continue to work.

Using number theory

The ever industrious Euler actually found a formula for square triangular numbers in 1778 – a very long time before computers and calculators, so let’s have a look at his method:

We start with the initial problem, and our initial goal is to rearrange it into the following form:

Next we make a substitution:

Here, when we get to the equation 1 = x2 – 2y2 we have arrived at a Pell Equation (hence the rearrangement to get to this point).  This particular Pell Equation has the solution quoted above where we can define Pk  as


Therefore we have

Therefore for any given k we can find the kth square triangular number.  The a value will give us the square number required and the b value will give us the triangular number required.  For example with k = 3:

This tells us the 3rd square triangular number is the 35th square number or the 49th triangular number.  Both these give us an answer of 1225 – which checking back from our table is the correct answer.

So, we have arrived at 2 possible methods for finding the square triangular numbers – one using modern computational power, and one using the skills of 18th century number theory.

When do 2 squares equal 2 cubes?

Following on from the hollow square investigation this time I will investigate what numbers can be written as both the sum of 2 squares, 2 cubes and 2 powers of 4. i.e a2+b2 = c3+d3 = e4+f4.

Geometrically we can think of this as trying to find an array of balls such that we can arrange them into 2 squares, or we can rearrange them and stack them to form 2 cubes, or indeed we can arrange them into 2 4-dimensional cubes. I’ll add the constraints that all of a,b,c,d,e,f should be greater than 1 and that the pair of squares or cubes (etc) must be distinct. Therefore we can’t for example have 2 squares the same size.

Infinite solutions

Let’s look at why we can easily find infinite solutions if the squares or cubes (etc) can be the same size.

We want to find solutions to:
a2+b2 = c3+d3 = e4+f4.

so we look at the powers 2,3,4 which have LCM of 12. Therefore if we choose powers with the same base we can find a solution. For example we chose to work with base 2. Therefore we choose

a = 26, b = 26, which gives 212+212
c = 24, d = 24, which gives 212+212
e = 23, f = 23, which gives 212+212

Clearly these will be the same. So we can choose any base we wish, and make the powers into the same multiples of 12 to find infinite solutions.

Writing some code

Here is some code that will find some other solutions:

for a in range(2, 200):
 for b in range(2,200):

for j in list1:
 for c in range(2,200):
  for d in range(2,200):
   if c**3+d**3 == j:

for k in list2:
 for e in range(2,200):
  for f in range(2,200):
   if k == e**4+f**4:

This returns the following solutions: 8192, 18737, 76832. Of these we reject the first as this is the solution 212+212 which we found earlier and which uses repeated values for the squares, cubes and powers of 4. The 3rd solution we also reject as this is formed by 14 4 + 14 4. Therefore the only solution up to 79202 (we checked every value up to and including 1992 + 1992) is:

18737 = 642+1212 = 173+243 = 114+84.

Therefore if we had 18,737 balls we could arrange them into 2 squares, a 64×64 square and a 121×121 square. Alternatively we could rearrange them into 2 cubes, one 17x17x17 and one 24x24x24. Or we could enter a higher dimensional space and create 2 tesseracts one with sides 11x11x11x11 and the other with 14x14x14x14.

With only 1 solution for around the first 80,000 numbers it looks like these numbers are quite rare – could you find another one? And could you find one that also satisfies g5+h5?

Hollow Cubes investigation

Hollow cubes like the picture above [reference] are an extension of the hollow squares investigation done previously.  This time we can imagine a 3 dimensional stack of soldiers, and so try to work out which numbers of soldiers can be arranged into hollow cubes.

Therefore what we need to find is what numbers can be formed from a3-b3

Python code

We can write some Python3 code to find this out (this can be run here):

for k in range(1,200):

 for a in range(0, 100):
  for b in range(0,100):
   if a**3-b**3 == k :

This gives the following: (the first number is the number of soldiers and the 2 subsequent numbers are the 2 cubes).

1 1 0
7 2 1
8 2 0
19 3 2
26 3 1
27 3 0
37 4 3
56 4 2
61 5 4
63 4 1
64 4 0
91 6 5
98 5 3
117 5 2
124 5 1
125 5 0
127 7 6
152 6 4
169 8 7
189 6 3

We could perhaps investigate any patterns in these numbers, or explore how we can predict when a hollow cube has more than one solution. I’ll investigate which numbers can be written as both a hollow square and also a hollow cube.

Hollow squares and hollow cubes

for a in range(2, 50):
 for b in range(2,50):
  if a**2-b**2 !=0:
   if a**2-b**2 > 0:

for j in list1:
 for c in range(2,50):
  for d in range(2,50):
   if c**3-d**3 == j:

This returns the following numbers which can all be written as both hollow squares and hollow cubes.

[56, 91, 19, 117, 189, 56, 208, 189, 217, 37, 279, 152, 117, 448, 513, 504, 448, 504, 387, 665, 504, 208, 875, 819, 936, 817, 61, 999, 988, 448, 728, 513, 189, 1216, 936, 784, 335, 469, 1323, 819, 1512, 1352, 1197, 992, 296, 152, 1519, 1512, 1197, 657, 1664, 1323, 1647, 1736, 1701, 1664, 936, 504, 2107, 1387, 1216, 1027, 91, 2015, 279, 2232]

Hollow squares, cubes and hypercubes

Taking this further, can we find any number which can be written as a hollow square, hollow cube and hollow hypercube (4 dimensional cube)? This would require our soldiers to be able to be stretch out into a 4th dimensional space – but let’s see if it’s theoretically possible.

Here’s the extra code to type:

for a in range(2, 200):
 for b in range(2,200):
  if a**2-b**2 !=0:
   if a**2-b**2 > 0:

for j in list1:
 for c in range(2,200):
  for d in range(2,200):
   if c**3-d**3 == j:

for k in list2:
 for e in range(2,200):
  for f in range(2,200):
   if k == e**4-f**4:

Very pleasingly this does indeed find some solutions:

9919: Which can be formed as either 1002-92 or 223-93 or 104-34.

14625: Which can be formed as either 1212-42 or 253-103 or 114-24.

Given that these took some time to find, I think it’ll require a lot of computer power (or a better designed code) to find any number which is a hollow square, hollow cube, hollow hypercube and hollow 5-dimensional cube, but I would expect that there is a number out there that satisfies all criteria. Maybe you can find it?


The Van Eck Sequence

This is a nice sequence as discussed in the Numberphile video above.  There are only 2 rules:

  1. If you have not seen the number in the sequence before, add a 0 to the sequence.
  2. If you have seen the number in the sequence before, count how long since you last saw it.

You start with a 0.


You have never seen a 0 before, so the next number is 0.


You have seen a 0 before, and it was 1 step ago, so the next number is 1.


You have never seen a 1 before, so the next number is 0.


You have seen a 0 before, it was 2 steps ago, so the next number is 2.



I can run a quick Python program (adapted from the entry in the Online Encyclopedia of Integer Sequences here) to find the first 100 terms.

A181391 = [0, 0]
for n in range(1, 10**2):
 for m in range(n-1, -1, -1):
  if A181391[m] == A181391[n]:

This returns:

[0, 0, 1, 0, 2, 0, 2, 2, 1, 6, 0, 5, 0, 2, 6, 5, 4, 0, 5, 3, 0, 3, 2, 9, 0, 4, 9, 3, 6, 14, 0, 6, 3, 5, 15, 0, 5, 3, 5, 2, 17, 0, 6, 11, 0, 3, 8, 0, 3, 3, 1, 42, 0, 5, 15, 20, 0, 4, 32, 0, 3, 11, 18, 0, 4, 7, 0, 3, 7, 3, 2, 31, 0, 6, 31, 3, 6, 3, 2, 8, 33, 0, 9, 56, 0, 3, 8, 7, 19, 0, 5, 37, 0, 3, 8, 8, 1, 46, 0, 6, 23]

I then assigned each term an x coordinate value, i.e.:

0 , 0
1 , 0
2 , 1
3 , 0
4 , 2
5 , 0
6 , 2
7 , 2
8 , 1
9 , 6
10 , 0
11 , 5
12 , 0
13 , 2
14 , 6
15 , 5
16 , 4
17 , 0
18 , 5
19 , 3
20 , 0


This means that you can then plot the sequence as a line graph, with the y values corresponding to the sequence terms.  As you can see, every time we hit a new peak the following value is 0, leading to the peaks and troughs seen below:

Let’s extend the sequence to the first 1000 terms:


We can see that the line y = x provides a reasonably good upper bound for this data:



But it is not known if every number would actually appear in the sequence somewhere – so this bound may not hold for larger values.

Length of steps before new numbers appear.

We can also investigate how long we have to wait to see each number for the first time by running the following Python code:

A181391 = [0, 0]
for n in range(1, 10**3):
 for m in range(n-1, -1, -1):
  if A181391[m] == A181391[n]:

  for m in range(1,50):
   if A181391[n]==m:
    print(m, ",", n+1)

This returns the following data:

1 , 3
2 , 5
6 , 10
5 , 12
4 , 17
3 , 20
9 , 24
14 , 30
15 , 35
17 , 41
11 , 44
8 , 47
42 , 52
20 , 56
32 , 59
18 , 63
7 , 66
31 , 72
33 , 81
19 , 89


The first coordinate tells us the number we are interested in, and the second number tells us how long we have to wait in the sequence until it appears.  So (1 , 3) means that we have to wait until 3 terms in the sequence to see the number 1 for the first time.

Plotting this for numbers 1-50 on a graph returns the following:

So, we can see (for example that we wait 66 terms to first see a 7, and 173 terms to first see a 12.  There seems to be a general trend that as the numbers get larger we have to wait longer to see them.  Testing this with a linear regression we can see a weak to moderate correlation:


Checking for the numbers up to 300 we get the following:

For example this shows that we have to wait 9700 terms until we see the number 254 for the first time.  Testing this with a linear correlation we have a weaker positive correlation than previously.

So, a nice and quick investigation using a combination of sequences, coding, graphing and regression, with lots of areas this could be developed further.


Website Stats


IB Maths Exploration Guide

IB Maths Exploration Guide

A comprehensive 63 page pdf guide to help you get excellent marks on your maths investigation. Includes:

  1. Investigation essentials,
  2. Marking criteria guidance,
  3. 70 hand picked interesting topics
  4. Useful websites for use in the exploration,
  5. A student checklist for top marks
  6. Avoiding common student mistakes
  7. A selection of detailed exploration ideas
  8. Advice on using Geogebra, Desmos and Tracker.

Available to download here.

IB Revision Notes

IB Revision Notes

Full revision notes for SL Analysis (60 pages), HL Analysis (112 pages) and SL Applications (53 pages).  Beautifully written by an experienced IB Mathematics teacher, and of an exceptionally high quality.  Fully updated for the new syllabus.  A must for all Analysis and Applications students!

Available to download here.

IB HL Paper 3 Practice Questions (120 page pdf)

IB HL Paper 3 Practice Questions 

Seventeen full investigation questions – each one designed to last around 1 hour, and totaling around 40 pages and 600 marks worth of content.  There is also a fully typed up mark scheme.  Together this is around 120 pages of content.

Available to download here.

IB Exploration Modelling and Statistics Guide

IB Exploration Modelling and Statistics Guide

A 60 page pdf guide full of advice to help with modelling and statistics explorations – focusing in on non-calculator methods in order to show good understanding. Includes:

  1. Pearson’s Product: Height and arm span
  2. How to calculate standard deviation by hand
  3. Binomial investigation: ESP powers
  4. Paired t tests and 2 sample t tests: Reaction times
  5. Chi Squared: Efficiency of vaccines
  6. Spearman’s rank: Taste preference of cola
  7. Linear regression and log linearization.
  8. Quadratic regression and cubic regression.
  9. Exponential and trigonometric regression.

Available to download here.

Recent Posts

Follow IB Maths Resources from British International School Phuket on