Implementation notes

Encode messages in error messages.

----------------------------------------------------------------------
0. Concept

Previously, I won IOCCC with a program that behave differently when
optimization is turned on or off (2014), and another where program
behaves differently when compiled under different C standards (2015).
I have yet to write a program that behaves differently when compiled
with different compilers, which is exactly what I set out to do here.

This is obviously a very fragile thing to attempt because different
compilers are not supposed to produce different output, so the only
thing we can count on are bugs and nonstandard behavior.  Those
differences turned out to be quite reliable, and still persists even
after many years of people having reported them, probably because they
are nonstandard and neither GCC nor Clang are in any rush to come to
an agreement on nonstandard things.

----------------------------------------------------------------------
1. Tabs versus spaces

I know of at least two bugs where GCC and Clang behavior can be
observed by the output executable, both of which has had proposals out
to standardize the behavior, so eventually these tricks wouldn't work.
Although they might work for a time-bounded event like IOCCC, maybe I
will save them for the next one if they are still not fixed.

Instead of those tricks, I went with something that I found purely by
accident -- the fact that GCC (since version 11.1) will expand tabs in
its warning messages, while all known Clang versions always count tabs
as single characters.  Looks like there is no urgency to reconcile
this difference since compiler diagnostics are not standardized, and
most people don't use tabs anyway (many style guides forbid tabs).

Having found this one difference, I chose a common bug that would be
detected by both compilers (division by zero) and devised a way to
encode bits via column numbers in the warning messages.  The encoder
generates the right spaces more or less by brute force, while the
decoder parses the column numbers from warning messages using a DFA.

----------------------------------------------------------------------
2. Bonus features

I embedded a Ruby+Perl polyglot in the decoder to generate diagnostics
that fits the same format used by GCC and Clang, such that it's
possible to recover the original messages with other compilers.  This
was planned from the very start to future-proof the code against
fragile compiler changes.

Since the messages are specified as command line arguments, I thought
about automatically appending newlines at the end (similar to "echo"
behavior), but decided against it in the end.  Instead, I added
support to the command line parser to expand C-like escape sequences
so things like "\n" and "\t" would just work.  These escape sequences
also include the familiar "\x", so I was able to exhaustively test all
byte-pair combinations.

----------------------------------------------------------------------
3. Layout

The encoder+decoder combination comes out to 1345 characters (plus
2751 whitespaces).  I had plenty of space before hitting the IOCCC
size limit, so I opted to make the layout larger than needed so that I
can incorporate halftone pattern in Kurumi's hair.  This would be the
third time I used halftone patterns in ASCII art code, previous two
times were:

https://uguu.org/src_violet_c.html
https://uguu.org/src_koyomi_c.html

Because this code was relatively small, and I ironed out most tooling
updates while working Fern, I was able to finish Kurumi in just over 2
weeks, which is relatively short compared to most my other IOCCC
entries.

----------------------------------------------------------------------
4. Finally...

I worked on Kurumi during most of December 2025, right after
submitting Fern to IOCCC.

For the 8 IOCCC instances that took place from 2012 to 2024, I have
submitted exactly one entry per contest.  This means I got 7 winners
out of 7 submissions up to 2020, but it seems like my confidence was
misplaced for 2024.  So I wasn't fooling around this time, and
submitted Kurumi about a month after the contest started.

Kurumi ends up winning the INABIAF award (INABIAF = it's not a bug it's a
feature).
