Day 6-7
Thinking more about circles of equal altitude I figured out how to calculate the geographical position (GP) of a star, which is the center of such a circle. The geographical position of a star is the place on earth where the star is exactly in your zenith. This position obviously moves with the earth's rotation. But having the sidereal time at Greenwich and the right ascension of the star, you can get both its Greenwich hour angle and its geographical longitude:
GHA = GST - RA Longitude = RA - GST
The latitude of a star always being equal to its declination, this means that it's possible to calculate the GP of a star with a star catalogue and the current time.
So I wrote gha.c that describes this formula.
If the star's GP is the center of its circle of equal altitude, the observed altitude of the star is the circle's size. This is proportional to the angular distance between you and the star's GP. So with the center and the size of the circle, we have all we need to (approximately) describe every position on earth where the star could appear at the observed altitude at the time of observation. What we're now missing is a way to determine where on the circle we are located.
Time sight reduction is also sometimes called "solving the spherical triangle". The idea is that you can draw a spherical triangle between you, the star, and one of the poles. This triangle contains all the angles of interest, and with the help of trigonometry and linear algebra you can solve one angle in terms of some of the other angles.
The publically available paper Mathematics for Celestial Navigation by Richard Lao (2018) contains a very thorough collection of various formulas that can be derived from the spherical triangle. One of these formulas was especially interesting since it isolates the azimuth in terms of altitude, declination and latitude.
So I wrote azimuth.c that describes this formula as well.
The most difficult input to determine out of the three is the latitude. But at the very least, an instrument for measuring altitude is now all I need to obtain the required values.
The program still has a flaw, which is that it doesn't really care which quadrant the azimuth angle is in. It only outputs an azimuth between 0 to 180 degrees. In other words, it selects one of the two intersections in the circle of equal altitude, and you have to correct it by flipping the sign of the answer if the azimuth angle doesn't make sense.