A puzzle addressed during a MathsJam session (January 2016).

Three equilateral triangles. Which fraction is shaded?

Found on Twitter, posted by @math8_teacher

Well, time for some geometry then. Hmm what about being lazy instead and let Python do the calculations? :)

In [1]:

```
from sympy.geometry import Point, Segment, Triangle, intersection
from sympy import sqrt
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
```

In [2]:

```
def ratio(side):
# Height of an equilateral triangle
height = side * sqrt(3) / 2
# Points of the triangles on the base line
p0 = Point(0, 0)
p1 = Point(side, 0)
p2 = Point(2 * side, 0)
p3 = Point(3 * side, 0)
# Points of the triangles on the "top" line
p4 = Point(0.5 * (p1.x + p0.x), height)
p5 = Point(0.5 * (p2.x + p1.x), height)
p6 = Point(0.5 * (p3.x + p2.x), height)
# The 3 segments we are only interested in
# (that will intersect the last one)
s1 = Segment(p1, p4)
s2 = Segment(p1, p5)
s3 = Segment(p2, p5)
# The "big" segment that intersects everything
s4 = Segment(p0, p6)
# Intersections of the "big" segment with the others
i1 = intersection(s1, s4)[0]
i2 = intersection(s2, s4)[0]
i3 = intersection(s3, s4)[0]
# The normal triangles
tri1 = Triangle(p0, p1, p4)
tri2 = Triangle(p1, p2, p5)
tri3 = Triangle(p2, p3, p6)
# The triangles constructed with the intersection points
tri4 = Triangle(p0, i1, p4)
tri5 = Triangle(i2, i3, p5)
res = (tri4.area + tri5.area) / (tri1.area + tri2.area + tri3.area)
return res
```

In [9]:

```
# Calculate for 3 triangles of side 1
print('Ratio:', ratio(1))
```

In [4]:

```
# The ratio should not depend on the side of the triangles
for i in range(2, 10):
assert ratio(i) == ratio(1)
print('All good!')
```

The figure only shows 3 triangles. And for now the code does the calculation in a very manual way, defining the points, segments, triangles one by one.

Is it possible to rewrite the `ratio`

function to be generic and handle the case for more triangles?

In [5]:

```
def ratio_n(n, side):
# Height of an equilateral triangle
height = side * sqrt(3) / 2
ps = []
# Points of the triangles on the base line
for k in range(n + 1):
ps.append(Point(side * k, 0))
# Points of the triangles on the "top" line
for k in range(n):
ps.append(Point(0.5 * (ps[k+1].x + ps[k].x), height))
# The segments we are only interested in
segs = []
for k in range(1, n):
segs.append(Segment(ps[k], ps[k+n]))
segs.append(Segment(ps[k], ps[k+n+1]))
# The "big" segment that intersects everything
big = Segment(ps[0], ps[-1])
# The normal triangles
tris = []
for k in range(n):
tris.append(Triangle(ps[k], ps[k+1], ps[k+1+n]))
# The triangles constructed with the intersection points
shaded = []
for k in range(n-1):
if k == 0:
it = intersection(segs[0], big)[0]
shaded.append(Triangle(ps[k], it, ps[k+1+n]))
else:
kk = 2 * k
it1 = intersection(segs[kk], big)[0]
it2 = intersection(segs[kk-1], big)[0]
shaded.append(Triangle(it1, it2, ps[k+1+n]))
area_shaded = sum([abs(tri.area) for tri in shaded])
area_total = sum([abs(tri.area) for tri in tris])
res = area_shaded / area_total
return res
```

Let's first verify the function calcultes the same result found above for 3 triangles.

In [6]:

```
print('Ratio for 3 triangles with the generic function:', ratio_n(3, 1))
```

Good. Now what happens when there are more triangles?

In [7]:

```
SIDE = 10
LIMIT = 31 # Up to 30 triangles
ratios = []
xs = list(range(3, LIMIT))
for i in xs:
ratio_i = ratio_n(i, SIDE)
ratios.append(ratio_i)
print('Ratio for', i, 'triangles:', ratio_i, '~=', ratio_i.evalf())
```

In [8]:

```
plt.figure(figsize=(20,20), dpi=80)
plt.plot(xs, ratios, 'o-')
plt.xlabel('Number of equilateral triangles')
plt.ylabel('Percentage of the shaded area')
plt.title('Percentage of shaded area per number of equilateral triangles')
```

Out[8]:

That's quite interesting! With some optimizations in the `ratio_n`

function, we could calculate the ratio for more triangles.

But looking at the graph, we can ask at least two questions:

- Does the ratio converge to 1/3? (0.333333...)
- If yes, how to prove it?

I will let these two questions as an open challenge :)