[Heuristic] Bouncers: constant size of tape-extension after some point

The following property seems to be characteristic of bouncers (unilateral and bilateral):

The size by which the tape extends between two bounces is constant.

A more thorough way to describe the above is:

Consider the list of successive events where the head hits an extreme position of the tape, i.e. a position that is the current min/max of all the positions seen before. For instance, on machine 58,329,156 this list looks like:

[TapeExtreme(time=0, side='left', pos=0),
 TapeExtreme(time=0, side='right', pos=0),
 TapeExtreme(time=1, side='right', pos=1),
 TapeExtreme(time=2, side='right', pos=2),
 TapeExtreme(time=3, side='right', pos=3),
 TapeExtreme(time=5, side='right', pos=3),
 TapeExtreme(time=8, side='left', pos=0),
 TapeExtreme(time=9, side='left', pos=-1),
 TapeExtreme(time=13, side='right', pos=3),
 TapeExtreme(time=14, side='right', pos=4),
 TapeExtreme(time=15, side='right', pos=5),
 TapeExtreme(time=16, side='right', pos=6),
 TapeExtreme(time=18, side='right', pos=6),
 TapeExtreme(time=25, side='left', pos=-1),
 TapeExtreme(time=26, side='left', pos=-2),
 TapeExtreme(time=34, side='right', pos=6),
 TapeExtreme(time=35, side='right', pos=7),
 TapeExtreme(time=36, side='right', pos=8),
 TapeExtreme(time=37, side='right', pos=9),
 TapeExtreme(time=39, side='right', pos=9),
 TapeExtreme(time=50, side='left', pos=-2),
 TapeExtreme(time=51, side='left', pos=-3),
 TapeExtreme(time=63, side='right', pos=9),
 TapeExtreme(time=64, side='right', pos=10),
 TapeExtreme(time=65, side='right', pos=11),
 TapeExtreme(time=66, side='right', pos=12),
 TapeExtreme(time=68, side='right', pos=12),
 TapeExtreme(time=83, side='left', pos=-3),
 TapeExtreme(time=84, side='left', pos=-4),
...

Now, remove from this list successive events that are on the same side (always keep the latest one):

[TapeExtreme(time=0, side='left', pos=0),
 TapeExtreme(time=5, side='right', pos=3),
 TapeExtreme(time=9, side='left', pos=-1),
 TapeExtreme(time=18, side='right', pos=6),
 TapeExtreme(time=26, side='left', pos=-2),
 TapeExtreme(time=39, side='right', pos=9),
 TapeExtreme(time=51, side='left', pos=-3),
 TapeExtreme(time=68, side='right', pos=12),
 TapeExtreme(time=84, side='left', pos=-4)
...

In this new list of local extremes, by construction, events on the left and on the right alternate. These remaining, alternating events are outlined in yellow in the following space-time diagram:

We can get successive lengths of the tape at left extreme positions by subtracting successive right extreme positions to the following left extreme positions (and adding 1). Here we get:

[5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, ...

For bouncers, this sequence must eventually grow by an additive constant at each step, i.e. the first difference must eventually be constant (meaning the second difference is eventually null).

Here, we immediately get the property since the sequence of first differences gives:

[4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ...

Turning this procedure into code gives a simple heuristic to recognise bouncers available at this link.