Implementation notes Puzzle box ---------------------------------------------------------------------- 0. Concept With the advent of // comments in C99, writing code that compiles after some rotation is fairly easy, yet I can't seem to find an entry that did it for IOCCC, so I figured I would just make one myself. But just a program that rotates 4 ways is kind of boring. Then I remembered those Japanese puzzle boxes where you have to slide various bits along nearly invisible seams to open the box. I thought trying to recreate that experience in C would be kind of fun, and set out with this plan: - Initial code will produce a tool that can rotate a piece of text. - One of the rotated output will be another tool that removes leading whitespaces from a piece of text. This is equivalent to the "shift" action in solving those puzzles. - It must be possible to compile all rotated and shifted variations of the original code. ---------------------------------------------------------------------- 1. Text tools Writing a tool that rotates text is easy, so easy that I did it two ways for Nuko. The only subtle part was determining whether to rotate clockwise or counterclockwise, but since I am doing both in two separate tools, it didn't matter. The motivation for two rotation tools was to simplify the puzzle solving bits later, since it would be inconvenient to having to rotate 3 times in one direction when you really wanted to just rotate the other way. Also, I really wanted a simple tool to fit under the size constraints, and a more full-featured tool that will be hidden inside comments. In the end, I didn't really need to worry about it since the code comfortably fits with less than 2k of non-whitespace characters. ---------------------------------------------------------------------- 2. Rotations Writing a code that compiles after rotation basically involves writing different pieces of code and then merging them into the same space. Mostly it's just lots of patience, and the really hard part is to assess the amount of space needed beforehand to reduce wasted space. Actually the size estimation part was easy: write the code once, count how much space is wasted, throw it away and rewrite the same code from scratch. It's the same technique they use to calculate load limit of bridges according to Calvin and Hobbes. The coding process was tedious but fairly straightforward: write the sub-programs normally and then golf them for size, then start with the largest program and fill them into the template in counter-clockwise order. It's counter-clockwise order so that the vertical size limits of each sub-program is determined by the previous sub-program. replay.html captured all these except the bit where I wrote the program for the first time to measure final template size. Instead, if you skip forward to around the 46:30 mark, you will notice the template being adjusted to account for the unnecessary waste. For this program, I have decided on using Nuko (from "Girls' Last Tour") as the template fairly early. I didn't want the anime faces I typically use since they tend to not look so well when rotated with a non-square font. In comparison, Nuko looks like Nuko regardless of orientation or aspect ratio. ---------------------------------------------------------------------- 3. Shifts Writing code that will compile with one column shifted takes a bit more patience than just rotatable code. Basically it involves typing carefully while being more aware of the vertical column, and VIM's 'cursorcolumn' option was perfect for this purpose. By adding notches on two of the sides, we would double the program behavior because each face gains an extra mode depending on whether they have the shifted column or not. But actually we got a bit more than 4 extra programs, by making use of the concept common to sliding puzzles: 1 1 5 5 2 2 21 -> 25 -> 25 -> 15 -> 15 -> 12 -> 12 -> 52 -> 52 -> 51 -> 51 -> 21 5 2 2 1 1 5 Notice how we can form a cycle with 12 steps by allowing a space to shift around a 2x2 area. Nuko uses the middle 2 digits to encode six different states for the face that is rotated 180 degrees. For the other 3 rotations, one extra state is used depending on column shift, so 9 states here. In theory, I could have implemented 12*4 = 48 different states, but I would probably run out of time and space. Mostly time. ---------------------------------------------------------------------- 4. Unbalanced brackets After implementing all the rotations and shifts, I still have some space left over, so I removed one of the shifted messages and replaced it with C code, which can then be used to extract one final message from nuko.c. I thought having a final step as an "ending" to solving the puzzle would be interesting. It had to be C code, as opposed to an embedded program in some other language like I usually do. The idea is that similar to those wooden puzzle boxes, you already have all the tools needed to solve the box, and it would be shame if you have to look for a screwdriver for the final step or something like that. For Nuko, the only thing you need is a C compiler, and all the extra tools are built into Nuko itself. This final tool works by printing messages between unbalanced brackets. Initially, I wanted a generalized tool that doesn't do any processing to the unbracketed content, but that would mean storing the final message in plain text, which kind of defeats the puzzle. Also, it means I won't be able to encode newlines. This is why the final tool is specialized with some add+xor+mod logic. ---------------------------------------------------------------------- 5. Testing Some testing was done to ensure that Nuko works with generic text, to verify that Nuko can function normally as a general tool in addition to being a puzzle box. But for the most part, I just verified that the puzzle box bits was fully functional, and did not carefully test all edge cases of text rotation. They should work, though. Most of the testing was actually in verify that Nuko compiles without warnings against different versions of GCC and Clang, and fixing some overzealous compiler warnings in the process. ---------------------------------------------------------------------- 6. Finally... I look in recent anime series for IOCCC inspiration, as usual. I thought it was important to maintain an anime slot in this contest. The most memorable series of 2017 that I considered for this purpose was "Made in Abyss", and then I realized that it was memorable because it was practically traumatic. I am not sure I want to endorse that particular series, it's easy to bait someone into watching it since the first few episodes look mostly harmless and cute, but it gets more and more disturbing as it goes on, and by episode 10 it's too late to turn back. That was real trauma. The next one in line was "Girls' Last Tour", where the random spirals in the opening sequence has inspired this entry. The manga series ended recently and it's hard to say whether that's a happy ending or not, I am glad I completed this entry before reading the ending to the manga. Nuko would go on to win the "Most shifty" award for IOCCC 2018. I wanted to say that this was exactly as planned except I couldn't predict the award name. Just like 2015, really. I only had time for one submission and Nuko has performed well.