The Advent of Code in Ada
This is of necessity long, and may not interest most people —
or really anyone aside from me.
I lurk on a few websites related to computer programming,
and sometimes participate.
Every year, one or more of them will pop up a discussion about
, an annual programming puzzle contest.
It’s like an
where on each day you open a compartment to find a goodie —
only instead of a chocolate treat, you get two programming puzzles.
True to its name, the Advent of Code competitions
start at midnight EST on December 1st, and continue through the 25th.
I doubt most participants intend to win.
Many probably start off thinking they’ll do well,
but before long one realizes that he doesn’t stand a chance against
seasoned, “professional” competitors.
He may even wonder how on earth the professionals manage
to complete many of the puzzles so quickly!
I certainly did.
Many participate as a purely social event,
as an excuse to chat on their favorite programming-related forums.
Some companies have their employees participate as a way of building skills;
and some people do it to learn a programming language.
Last November I joined the latter group, with the intent of learning
the Ada programming language
I first heard of Ada in my youth, probably among the computer books
I read voraciously.
That was the age of the
”, which has since
been replaced by the age of the “Personal Computers”.✝“Impersonal”
would be a better description,
but I suppose that’s a discussion for another day.
My father, an engineer who worked for a NASA contractor,
once said that Ada interested him greatly,
though I don’t think he ever acquired much experience with it.
Quite a few people harbor negative opinions of Ada.
One of my undergaduate professors derided it as a product of the military;
she was much more impressed with C++.
Too many people take one look at it and say, “Nah; I’m more of a
‘curly brackets’ person.”
procedure Test_Out is
package ATIO renames Ada.Text_IO;
Early in its lifetime, Ada picked up a reputation for being
a very complicated language, and this is one of the reasons
it didn’t take off. Some people still say that.
As it happens, I had pretty much no exposure to Ada until about 2017 or 2018,
when I took a course on compiler construction.
We had an end-of-term team assignment to research and present
on several computer languages, and when I saw that Pascal and Ada
were two of the options, I signed my name next to those.
I put a lot of work into studying Ada for that project,
enough that by the end of the semester
I ported the toy compiler we were working on to Ada,
and added multitasking facilities for
that made use of Ada’s
I also learned about the SPARK dialect, which helps produce
“provably formally correct code”.
After decades of struggling with C++’s complexities and inconsistencies,
Ada didn’t seem half bad.
I enjoyed the experience enough to sign up for the
GNAT Academic Program
A toy compiler is OK, but I didn’t have much cause to use Ada again
for a while, and by late 2020 I knew I had forgotten
most of what I’d learned.
The Advent of Code seemed like a good time to re-acquaint myself with Ada.
Advent of Code 2020
The first puzzle opens,
After saving Christmas five years in a row…
Hmm. You must have me confused with someone else.
I pressed on.
I successfully completed
…sadly, not always on my own.
On several occasions I looked at other people’s solutions to obtain ideas.
I generally attributed those participants when I did.
On some occasions I did not: these are instances
where I already had the right idea, but my implementation wasn’t working.
After exhausting my brain, I would visit
read what people were saying, see if someone was following my approach,
and if so, download the code and see if I could run it and see where its
intermediate computations diverged from mine.
These un-attributed people were writing in other languages;
I particularly remember using solutions written in Java and Rust,
the latter of which I’ve never used before,
but I had briefly studied it, and besides it’s essentially
an imperative language like most mainstream languages, so I deciphered enough
to insert print
statements in the right places.
One charming aspect of the 2020 puzzles was the alliterative names:
Report Repair, Toboggan Trajectory, etc.
Only Combo Breaker, the final puzzle, didn’t at least try,
and that’s a shame,
since “Hotel Hacker” would have worked great.
The puzzles themselves range from very easy to insanely difficult.
Even the easiest ones took me at least 45 minutes,
but those occurred on the first few days,
and I console myself that it was due to reacquainting myself with Ada.
Other puzzles took hours. I stayed up all night on more than one occasion,
until I came to grips with reality and accepted that
I might as well get a good night’s sleep and attack the puzzles
with a fresh mind in the morning.
Alas, that’s also round about the insanely hard puzzles’s advent,
which meant I ended up squandering before a screen
much of the holiday time I had meant to spend with family.
Awareness of the tradeoff didn’t help lessen my frustration at those times.
I got the T-shirt! …well, kind of
There was a payoff to completing the competition:
this pleasant animated
that incorporates many of the puzzles.
Flush with the pleasure of having completed the Advent of Code —
many who start do not finish — I decided to buy
It looks cool, and I thought it would be awesome to sport it around.
Sadly, I’m the kind of idiot savant who forgets to select the size,
so I ended up buying the default size (Small) instead of one that fits me (Large).
My elder daughter is very happy with her new T-shirt.
Advent of Code 2019
In an interview somewhere online, Eric Wastl mentions the number of people
who have completed all the puzzles for all the years.
It’s not a big number, as I recall: roughly 400, I think.
Without thinking how much time it had taken to complete
quite a few of the puzzles, I decided to try my hand at Advent of Code 2019,
also in Ada.
I completed that one, too!
…also, alas, not entirely on my own.
In fact, for some reason I found it a much, much bigger challenge.
Two or three of the problems seemed much harder than any of 2020’s problems,
I might even say that they seemed unreasonably
for a “simple” competition.
I’d have kept this opinion to myself, but
a few comments on Reddit also expressed dissatisfaction at the difficulty in 2019,
which I don’t remember from the 2020 competition.
I probably didn’t look hard enough,
and I discuss this disappointment below,
so don’t judge me too harshly yet.
These difficult problems did have something in common:
circumventing algorithmic complexity seemed a much bigger deal
in 2019’s puzzles than it had been in 2020’s.
A couple of puzzles related to this ground me down so much
that after completing them
I would go a couple of weeks or more without even thinking about it.
Because of this, I finished the 2019 competition in April,
despite starting in January.
All that said, it’s Mr. Wastl’s competition,
so what makes it “reasonable” is really up to him.
Unlike me, Mr. Wastl works in the industry,
so he would have a better conception.
One part of the 2019 competition that I really enjoyed were the
That gave me practice building and assembling an Ada package,
which is both something the 2020 competition didn’t quite afford me,
and also one of my favorite activities.
code gives one a sense of satisfaction
that a one-off puzzle doesn’t quite accomplish.
Hands down, I most enjoyed the final puzzle,
a text adventure game in the old style (“old” = 1980s),
programmed in Intcode, which is pretty impressive in itself,
and required a bit of ingenuity to work through the main puzzle.
The game takes its inspiration from the old 1980s games in more than one way
by making reference to at least one creature from Zork.
Not quite the T-shirt
I got my payoff!
Unlike the 2020 animation, there really aren’t any particular puzzle items
visible in this animation.
It “just” depicts the general storyline:
Santa has become stranded at the edge of the Solar System
while delivering presents to other planets!
To accurately calculate his position in space, safely align his warp drive,
and return to Earth in time to save Christmas,
he needs you to bring him measurements from fifty stars.
You’ll notice a dot that moves from Earth to each of the other planets,
innermost first, until it ends up beyond Pluto, then returns to Earth.
Also unlike the 2020 competition, there was no special T-shirt for the occasion.
✣If you’re wondering,
my younger daughter does not seem particularly disappointed.
Was it a good idea?
Yes. I have a decent grasp on Ada, though I’d not be foolish enough
to pretend that I’m an expert.
Is Ada suitable for Advent of Code?
Not unless you come really
To be fair, that applies to just about any programming language.
The top competitors are using whatever tool they have at hand,
which from what I hear includes things like spreadsheets
and prepared programs that work in many situations.
They have a lot of experience at tying their tools together.
That’s impressive, but it means that someone like me,
who comes to each day’s puzzles with a blank slate (more or less)
has little hope of writing an Ada program that solves both puzzles within,
say, 2-3 minutes.
I wanted to learn Ada, and for that purpose it worked well.
There were times that I struggled with the Ada language itself
when I might not have struggled with a different language.
That’s not necessarily a bad thing: I was learning Ada,
and in cases where the struggles were not due to the learning,
the restrictions Ada imposes may well be a guarantee for a good result.
To break a compiler?
Gautier de Montmollin, who maintains
the HAC Ada Compiler
remarked in comp.lang.ada that the Advent of Code helped him test, improve,
and debug HAC.
I likewise discovered several bugs in the GNAT Ada compiler
and reported them to AdaCore.
AdaCore confirmed the bugs and said they would be fixed in the next release.
Alas, they didn’t send me an advance copy of the fixed compiler
as a reward. ;-)
To compare languages?
It’s hard not to look at this Python code, taken from
’s solution to Day 1 of the 2019 competition:
from math import floor
return floor(mass/3) - 2
if __name__ == '__main__':
with open('day01.txt') as f:
mass = [int(x) for x in f.readlines()]
c = 0
for m in mass:
while m > 0:
m = max(0, mass_to_fuel(m))
c += m
…and not feel at least a bit of envy when I have to write this:
procedure Main is
Testing: constant Boolean := False;
Filename: constant String
if Testing then "/Users/user/common/Ada/AoC2019/Day1/example.txt"
function Estimate_Fuel(Mass: Natural) return Natural is
( ( Mass - Mass mod 3 ) / 3 -2 );
Open(F, In_File, Filename);
Value, Partial_Sum, Intermediate_Sum: Natural;
Sum, Total_Sum: Natural := 0;
while not End_Of_File(F) loop
Partial_Sum := Estimate_Fuel(Value);
Sum := Sum + Partial_Sum;
Intermediate_Sum := Partial_Sum;
while Partial_Sum > 8 loop
Partial_Sum := Estimate_Fuel(Partial_Sum);
Intermediate_Sum := Intermediate_Sum + Partial_Sum;
Total_Sum := Total_Sum + Intermediate_Sum;
Put("sum of fuel requirements: "); Put(Sum, 0); New_Line;
Put("total sum of fuel requirements: "); Put(Total_Sum, 0); New_Line;
To be perfectly fair, there may well be a nice,
elegant way of writing this in Ada;
I don’t know that I’d have thought of writing
that style of Python code myself.
I don’t have that much experience with the use of “mappings”,
an admittedly nice technique, but not one I often think of offhand.
As the competition progressed, I did learn more.
However, something simple like this Python code:
with open('day01.txt') as f:
mass = [int(x) for x in f.readlines()]
…will nevertheless require some
clauses in Ada
that come “free” in Python.
Specifications, or the lack thereof
One recurrent frustration I had with the puzzles is that
they often don’t specify parameters that I thought ought to be specified.
One example would be 2019’s Intcode problems.
What size should one set aside for the Intcode programs?
How much data will they need?
What’s the maximum size an Intcode value can take?
The puzzles never say.
Ada’s kind of particular about types, for good reason;
overflow bugs can be pretty hard to track down.
Arguably, this particular example illustrates how a package evolves
as you find more needs for it, and I was quite pleased
at how little restructuring my Intcode package needed.
But on more than one occasion I encountered problems simply because
I didn’t have the right amount of data set aside, the right stack size,
and/or the right type chosen for an Intcode.
Eventually I needed to use Long_Long_Integer
which uses a 64-bit integer,
but shouldn’t that be specified from the start?
Will I do another?
It can be immensely rewarding to complete a puzzle,
especially when you’ve figured it out on your own,
but it takes a lot
of time and energy, and I do have other obligations.
A while back I was thinking I might complete all the old puzzles,
as well as participate in the 2021 competition, but to be honest,
I’d rather spend the time and energy doing something else.
So, I don’t know.
Well, maybe if there’s another custom T-shirt. ;-)