2026-06-28 08:33:33
Here’s a crazy bash one-liner I found via an article by Peter Krumins:
echo {w,t,}h{e{n{,ce{,forth}},re{,in,fore,with{,al}}},ither,at}
This prints 30 English words:
when, whence, whenceforth, where, wherein, wherefore, wherewith, wherewithal, whither, what, then, thence, thenceforth, there, therein, therefore, therewith, therewithal, thither, that, hen, hence, henceforth, here, herein, herefore, herewith, herewithal, hither, hat
This post will explain how the one-liner works.
Bash brace expansion iterates through all possibilities listed within curly braces, with possibilities separated by a comma. Note that the comma is a separator and not a terminator. And so, for example, the expression {w,t,} is effectively {w,t,""}.
When bash sees two brace expressions, these expand to the cartesian product of the two expressions. For example,
echo {A,B}{1,2,3}
produces
A1 A2 A3 B1 B2 B3
In the expression above we have
{w,t,}h{e…,ither,at}
So the expansion will enumerate all possibilities of {w,h,} multiplied by all possibilities of {e…,ither,at} where e… is itself a brace expression.
A diagram will help a lot.

The brace expansion does a depth-first traversal of this tree.
The post Brace expansion tree first appeared on John D. Cook.2026-06-28 02:12:03
The previous post looked at how many digits are in the reduced fraction for the nth harmonic number. I was curious about how long the cycle of digits in a harmonic number might be.
I wrote about the period length for the digits of fractions almost a decade ago. This post includes code so I can apply it to harmonic demoninators.
from sympy import lcm, factorint, n_order
def period(n):
factors = factorint(n)
exp2 = factors.get(2, 0)
exp5 = factors.get(5, 0)
r = max(exp2, exp5)
d = n // (2**exp2 * 5**exp5)
s = 1 if d == 1 else n_order(10, d)
return (r, s)
This function returns two numbers: r is the number of non-repeating digits at the beginning and s is the length of the repeating part.
The following code
from functools import reduce
def lcm_range(n):
return reduce(lcm, range(1, n + 1))
print( period( lcm_range(50) ) )
prints (5, 1275120) meaning that 1/lcm(1, 2, 3, …, 49, 50) has five non-repeating digits following by 1,275,120 digits that repeat ad infinitum. And so the decimals in the expansion of H50 go have a cycle length of 1,275,120.
The post When will the decimals in a/b repeat? first appeared on John D. Cook.2026-06-27 20:51:42
The previous post looked at writing the harmonic numbers as reduced fractions and estimating the number of digits in the numerator and denominator based on asymptotics. This is a follow up post with plots.
We’ll choose our base b to be 2. And we’ll look at the total number of bits in both the numerator and denominator, which we will use as the height of the fractions.
First, let’s look at the actual and estimated heights, using the estimates from the previous post.

Next let’s look at the difference between the actual and estimated heights.

In the previous post I looked at n = 50, which was kind of a lucky choice, the error being smaller than usual. I had also looked at, but didn’t publish, n = 100, which would be an unlucky choice.
Finally, let’s look at the relative error in the estimates, and plot over a larger range of n.

The error goes to zero, as predicted by the asymptotic estimates. And it goes noisily, which you’d expect since the heights are related to the distribution of primes.
The post Height of harmonic numbers first appeared on John D. Cook.2026-06-27 09:51:03
The nth harmonic number is the sum of the reciprocals of the first n positive integers.
Hn = 1 + 1/2 + 1/3 + 1/4 + … + 1/n
The product of all the denominators is n!, so you could write Hn as a fraction
Hn = p/q
where p = n! Hn is an integer and q = n!.
While p/q is a way to write Hn as a fraction, it’s not the most efficient because p and n! will have common factors.
If we write Hn as a reduced fraction, the denominator will be the least common multiple of the integers 1 through n. That number is asymptotically exp(n). That estimate follows from the prime number theorem.
So for large n the denominator will be roughly exp(n), and in base b it would have around
n/log(b)
digits.
The numerator will be exp(n) Hn, and since Hn is asymptotically log(n) + γ, the numerator for large n will be roughly
exp(n) (log(n) + γ)
and will have around
(n + log log(n) ) / log(b)
digits.
Let’s see how well our asymptotic estimates work for n = 50. The 50th harmonic number is
H50 = 13943237577224054960759 / 3099044504245996706400.
This fraction has 23 digits in the numerator and 22 in the denominator. We would have predicted around
(50 + log(log(50)))/log(10) = 22.3
digits in the numerator and
50/log(10) = 21.7
digits in the denominator.
Let’s try a larger example, looking at the 1000th harmonic number in binary. We’ll use the following Python code.
from fractions import Fraction
def bits(n):
H = sum(Fraction(i, i+1) for i in range(1, n+1))
p, q = H.numerator, H.denominator
# subtract 2 because bin returns a string starting with 0b.
return len(bin(p)) - 2, len(bin(q)) - 2
print(bits(1000))
This returns 1448 and 1438. We would have estimated
(1000 + log(log(1000)))/log(2) = 1445.4
bits in the numerator and
1000/log(2) = 1442.7
bits in the denominator.
Update: See the next post for plots as a function of n.
2026-06-26 03:20:09
Hart’s theorem says
If a triangle be formed by the arcs of three circles, the inscribed and the three escribed circles are all tangent to a new circle or line.
Here “triangle” means a three-sided figure whose sides are portions of a circle. The inscribed circle is the largest circle that can fit inside the three-sided figure.
The “escribed” circles are analogous to the excircles in the previous post: you extend two sides and find a circle that is tangent to the triangle side and the extended side. The difference here being that the side extensions are now circles.

2026-06-25 22:35:52
This post will reveal the connection between my two previous posts: one on the Star Trek lemma and one on Pythagorean triples.
In the process of writing the latter, I looked at the Wikipedia article on Pythagorean triples and noticed this curious paragraph.
In every Pythagorean triangle, the radius of the incircle and the radii of the three excircles are positive integers. Specifically, for a primitive triple the radius of the incircle is r = n(m − n), and the radii of the excircles opposite the sides m2 − n2, 2mn, and the hypotenuse m2 + n2 are respectively m(m − n), n(m + n), and m(m + n).
The citation for the paragraph above was the book by my former officemate, which led to the post on the Star Trek lemma. The passage in Arthur Baragar’s book that Wikipedia cites is Exercise 15.3.
Let ΔABC be a right angle triangle with sides of integer length. Prove that the inradius r and the exradii ra, rb, and rc are all integers.
I don’t know whether Arthur discovered this theorem, but I’ll call it Baragar’s theorem for this post.
To unpack Baragar’s theorem, let’s start by saying what incircles and excircles are. Incircles are more familiar. The incircle of a triangle is the largest circle that can be inscribed inside the triangle, and the radius of this circle is the inradius.
Since an incircle is an inscribed circle, you might expect an excircle to be a circumscribed circle, but that’s not it. There are three excircles, one for each side. To find the excircle for a side, extend the other two sides and find the circle tangent to the side and the two extensions. The radius of an excircle is its exradius.
Baragar’s theorem follows directly from Euclid’s formula for Pythagorean triples mentioned in the previous post
and formulas for the inradius r and the exradii ra, rb, and rc.
Here K is the area of the triangle, which in our case is ab/2, and s is the semiperimeter, half the perimeter.
Expressing the radii in terms of m and n gives the values cited by Wikipedia above.
I’d like to write a Python script to illustrate the theorem, and knowing the radii of the circles help, but we also need to know the centers of the circles.
The center of the incircle is the weighted average of the vertices, with weights given by the lengths of the opposite sides. That is, if the vertices are A, B, and C, and the sides opposite these vertices are a, b, and c, the the incenter is
The centers for the excircles have remarkably similar expressions. For the incenter of the circle opposite a vertex, flip the sign of the corresponding side.
Putting it all together, here’s an illustrate the theorem.

And here’s the code that produced it. Note that everything in this section works for right triangles in general, not just Pythagorean triangles.
import numpy as np
import matplotlib.pyplot as plt
def connect(A, B):
plt.plot([A[0], B[0]], [A[1], B[1]], "C0")
def draw_circle(c, r, color):
t = np.linspace(0, 2*np.pi)
plt.plot(r*np.cos(t) + c[0], r*np.sin(t) + c[1], color=color)
a, b, c, = 3, 4, 5
A = np.array([0, b])
B = np.array([-a, 0])
C = np.array([0, 0])
s = (a + b + c)/2
K = a*b/2
r = K/s
ra = K/(s - a)
rb = K/(s - b)
rc = K/(s - c)
I = (a*A + b*B + c*C)/(a + b + c)
Ia = (-a*A + b*B + c*C)/(-a + b + c)
Ib = (a*A - b*B + c*C)/(a - b + c)
Ic = (a*A + b*B - c*C)/(a + b - c)
draw_circle(I, r, "C1")
draw_circle(Ia, ra, "C2")
draw_circle(Ib, rb, "C3")
draw_circle(Ic, rc, "C4")
plt.plot([-2*rc, 2*rb], [0, 0], "C0")
plt.plot([0, 0], [-2*ra, 2*rc], "C0")
plt.plot([(-2*ra - b)*a/b, 2*rb], [-2*ra, 2*rb*b/a + b], "C0")
plt.gca().set_aspect("equal")
plt.show()
The post Incircles and Excircles of Pythagorean triangles first appeared on John D. Cook.