The Problem
So Project Euler #786 gives you a billiard table. It's a nice kite with angles , , , at corners , , , .
Really simple problem statement honestly; You shoot a ball from corner , it bounces around with perfect physics and you want it to come back to . How many distinct paths can the ball take if it bounces at most times?
To sanity check your work: with up to bounces, there are only valid paths. With , there's . A thousand gives you .
Y'all just need to find the number of valid paths when . Yeah. .

Why This One?
The first Euler problem I ever solved was #785 (I think it was February 2022?), the one right before this. It was a Diophantine equation problem; took me about - hours. The high was insane when my name appeared on the leaderboard (< solves in a week!) and naturally I looked at the next one.
#786 was a completely different beast. I stared at it for a while and genuinely didn't know where to start.
I eventually found a similar older problem after lots of digging on periodic trajectories (pre-ChatGPT and google was ass), #202 (Laserbeam), which is also about counting reflections inside a geometric shape and I ended up solving that one first (you'll soon know why)
In short, it's just me documenting the approach / solution to my favorite problem which I solved back in February 2022 lol.
First Instinct
My honest first thought was to simulate it. Just trace the ball and count the bounces, see if I could find any patterns for small (hoping to find some obscure pattern on OEIS to cheat my way onto the leaderboard)
I wrote a quick script that does exactly that and check this out; drag the slider to the projected paths as you allow more bounces:
All I got were beautiful patterns instead lol (surely I'm missing something; check how circles form beautifully with increasing !)
What if we stop watching the ball?
Try setting the slider to . Look at the simplest path: it leaves , hits two edges, and comes back.
Now what if I were to trace each edge of trajectory in a mirror fashion? Take a look at the video below to understand.
A straight line. Every bouncing path is a straight line if you unfold the billiard table enough times. Mind map the above with a larger billiard trajectory and you'd find that the setting is a infinitesimal hexagonal lattice when you keep reflecting the trajectory edges.
The question now sounds different; we no longer care where the ball bounces. Stare at it a bit and it turns into "how many straight lines from the origin to lattice points cross at most cell boundaries?"
A number theory problem in disguise. Heh.
Where It Gets Hard
We've narrowed it down to the right problem statement - a bit of observation leads us to three inferences:
1. Not every lattice point is corner : When you map out the plane with reflections, some points correspond to , some to , some to , some to . We've started at A so we only want the ones where the ball actually returns to .
2. The path has to be "direct": If a straight line passes through another copy of on its way to the target, that means it's a shorter path; Think about it: the ball would've returned to earlier. So we need some way to filter these cases out.
3. Counting bounces from coordinates: Playing around with the simulations a bit led me to an unproven hunch that the bounce count for a path to some target in the lattice kept matching with the number of edges the straight line intersects in the lattice.
Piecing It Together
The first useful thing I found was Baxter & Umble's paper on periodic billiard orbits in triangles along with a couple more similar papers on connectedpapers.com. It kinda unfolds what we're trying to do but for equilateral triangles instead (which problem #202 was about). I tried to adapt their approach to our hexagonal lattice but it didn't really line up with what I was thinking.
The paper focused on developing a coordinate system for equilateral triangle lattice structure but you just tweak it a bit with some vector arithmetic and we have our own thing now.
For Inference 1, Say we represent each target as a point using two basis vectors and . It is straightforward that not every gets us back to . the tiling has 3 types of vertices (, midpoints, centroid).
Revisiting our simulation of small cases, we find a nice and clean pattern (phew it wasn't a waste of effort): lands on when . The rest land on midpoints () or on ().
Inference 2 is straightforward honestly; Coprime pairs. Basically and are coprime if the only positive integer that is a divisor of both of them is . Straight from wikipedia.
Inference 3 feels the hardest; and it is. We'll see why soon.
Counting edge crossings
We've been dangling on inference 3 for a while; lets do it.
Lemma 1 (Crossing Lemma). Let be a family of parallel lines with spacing . A segment whose projection onto the perpendicular direction has length crosses lines of .
In plain terms, a segment from the origin to crosses vertical grid lines because its -coordinate goes from to and the grid spacing is . We'll use this lemma repeatedly to get to our theorem.
Two kinds of edges
When we unfold the billiard table, the tiling has two kinds of edges:

The purple hexagon edges are copies of sides and from our original table. The teal internal edges are copies of sides and . A straight line from the origin to crosses both kinds, and we count them separately.
But why two kinds? If you observe closely, each equilateral triangle in the underlying triangular lattice is subdivided into copies of our quadrilateral . The vertex sits at a triangle vertex, at the centroid and , at edge midpoints. The edges and (centroid to midpoint) lie along the triangular lattice lines. The edges and (vertex to midpoint) form the hexagonal boundaries around each -vertex.
Part 1: Internal (triangle-grid) edges
Let's take a look at the tiling diagram again. The internal edges (teal) lie along three directions; and segments connecting centroids to edge midpoints.
Definition 1. Let and , which sit at to each other (the angle at ). The target point for lattice coordinates is:
We need actual numbers to work with so we drop our basis vectors into Cartesian coordinates. The angle between and gives us 's components.
Proposition 1. The projections of onto the three perpendicular directions are:
Proof. Projection onto : trivially . Onto :
Onto :
We’ve got three numbers: , , and . Each one is basically “how far” our line from the origin to goes in one of the three perpendicular directions to the internal edges. These are exactly the ’s we need for the crossing lemma which are one for each edge direction.
Lemma 2. The internal edges are spaced units apart in coordinates.
Take another look at the tiling diagram. Pick any -vertex of your choice. The nearest other -vertex is not the next cell over because there are 2 other cells (a -type and a -type) between them. So to reach from one to the next in any direction, you'll always cross exactly 3 cells. That's why the edge spacing is 3 in our coordinates.
Corollary 1. By Lemma 1 (projection spacing), the number of internal edge crossings is:
Corollary 2 (Integrality). These are integers whenever , since and are both divisible by .
Part 2: Hexagon edges
The hexagon edges (purple in the diagram) are the and segments. Same deal as the above; you've got three families, one per direction. But this is a bit tricky because unlike the internal edges which run across the entire plane as continuous lines, hexagon edges are short segments that only show up at certain spots.
Lemma 3. Hexagon edges parallel to repeat with period in the -coordinate. Similarly, those parallel to repeat with period in the -coordinate, and those parallel to repeat with period in .
Part 1's internal edges were continuous lines running across the entire plane so dividing the projection by the spacing give us clean integer counts. But the hexagon edges are different since they're short segments that only exist around -vertices. Since -vertices sit cells apart, these segments show up every rows. But whether our line actually hits one depends on where exactly it crosses that row. Some rows it hits a hexagon edge, some rows it slips through the gap.
Corollary 3. By Lemma 1, the number of hexagon edge crossings is:
The floor functions (instead of clean division like Part 1) are because not every row has a hexagon edge; they're discrete segments and aren't continuous lines.
Total bounce count
Theorem 1. The total number of bounces for a path to lattice point is:
What's Next?
Honestly I'd like to take a jab at other polygons. This problem is kinda well researched for Triangles and their derivatives (our quadrilateral was just 2 equilateral triangles stuck together) but I'm not entirely sure how it's going to work out with other stuff.
Squares and Rectangles feel straightforward, maybe there's some generalization to n-gon's since there's some lattice repeatability? Maybe I'll stop at this; hopefully there's a part 2 where I get to extend this.
Props to Axiom Math's APIs for verifying this!
References
[1] A. Baxter, R. Umble. "Periodic orbits of billiards on an equilateral triangle." The American Mathematical Monthly, 2008. https://arxiv.org/abs/math/0509292
[2] "Euclid's orchard." Wikipedia. https://en.wikipedia.org/wiki/Euclid%27s_orchard
[3] Project Euler. "Problem 786: Billiard." https://projecteuler.net/problem=786
[4] Project Euler. "Problem 202: Laserbeam." https://projecteuler.net/problem=202
Additional reading
[5] R. Becker. "Periodic billiard trajectories in isosceles right-angled triangles." 2013. https://arxiv.org/abs/1306.6702
[6] R. Becker. "On the local theory of billiards in polygons." 2014. https://arxiv.org/abs/1405.1150
[7] Connected papers graph for [1]. https://www.connectedpapers.com/main/34f03b3e8a4ec20176678be6a596f043daffac99/Periodic-Orbits-for-Billiards-on-an-Equilateral-Triangle/graph
