Implementation notes The joy of manipulating text. ---------------------------------------------------------------------- 0. Concept The way most these ASCII art code works is that usually there is some anime character I liked, and I try to make an ASCII art code with some functionality that might be related to that character. For IOCCC it's often the opposite, where I start with some functionality that seem specific to the C language, and then match a recent anime character that might be related. For this year's IOCCC, I am taking my more usual approach of giving precedence to character over function. The character chosen for this year is Violet Evergarden from the 2018 anime series named after her, and thus I decided on a utility that would visually scramble letters. ---------------------------------------------------------------------- 1. ANSI escape codes The one standard for setting cursor position is to use ANSI escape codes, which works practically everywhere except on Windows. It's also most familiar to me since I used it not too long ago for this other program: http://uguu.org/src_tina_rb.html Scrambling letters via cursor positions by itself isn't particularly useful, other than to defeat strings(1) utility. But if we scramble a piece of text and distribute the individual pieces separately, we would have implemented visual cryptography: https://en.wikipedia.org/wiki/Visual_cryptography Thus Violet implements the following: - Scramble input text (Fisher-Yates shuffle). - Output the scrambled text at their original positions using ANSI escape code. - If user asks the input to be split into separate layers, the output text will have extra positioning code inserted to park the cursor at the right location after each layer. In order to assemble the layers separately, Violet also implements the unscrambler, which reads ANSI position codes, sort all input characters by position (with MergeSort, because it's stable), and then output the characters at the correct location by inserting the appropriate amount of whitespace, stripping out ANSI codes. If I just stopped here, I would get an utility for stripping out ANSI codes and trailing whitespaces, which is not too bad an accomplishment, but I thought I needed a bit more for IOCCC. ---------------------------------------------------------------------- 2. UTF-8 and Unicode Given the "I" in IOCCC, I thought I should try to support UTF-8. I had a similar thought back in 2006 when I wrote this program: http://uguu.org/src_shindou_c.html The emphasis there was to be able to detect Japanese characters encoded in various encodings (Shift-JIS, EUC-JP, UTF-8, UCS-2LE, UCS-2BE). It didn't win anything. The world wide web has changed since then and almost everything is UTF-8 now, so this time I just focused on getting most of UTF-8, particularly the bit about differentiating full-width and half-width characters. ---------------------------------------------------------------------- 3. Delayed output At this point I have an utility that can process text a character at a time with reasonable accuracy, but all the trouble that went into handling these standards aren't really visible when the output comes out all at once, so I added an extra feature to output characters slowly. And all it took was one line of Ruby, which handles UTF-8 natively. That was rather convenient. ---------------------------------------------------------------------- 4. Compressed layout Because this is an utility for scrambling on-screen text, I really wanted the code to fit in 80x25 terminal. For maximum compatibility against line wrapping and such, it actually fits in 79x23. Since I just wanted things to fit and wasn't going for a particular layout, it was basically just a solid rectangular block of code. Still, I had to apply some code golf techniques to make things fit. Notably, I abbreviated strings via preprocessor arguments. That is, most people use macros like this: #define A long_piece_of_code #define B another_long_piece_of_code But this code used macros like this: #define M(A, B) M(long_piece_of_code, another_long_piece_of_code) This costs extra '\' at the end of each line, but avoids the recurring cost of "#define". This is a lot more efficient for rectangular piece of code. ---------------------------------------------------------------------- 5. Expanded layout The solid rectangle was submitted to IOCCC as the main program, but the ultimate goal is still ASCII art. This part is purely a game of patience, especially more so this time around since I decided to halftone parts of the image to match Violet's light colored hair. This is the second time I have done halftones, the first time was for Koyomi: http://uguu.org/src_koyomi_c.html Unlike the first time, these days I record the process of how these things are made, so you marvel at the 3+ hours spent on doing just text layout. Personally I am fairly happy with how things turned out. ---------------------------------------------------------------------- 6. Testing Violet was tested every step along the way against GCC and Clang, and also ran under Address Sanitizer during parts of the development. The tests were improved over the weeks that I worked on this code, so the final ASCII art actually has fewer bugs than all the easy to read code that came before it. I can't guarantee that there are no bugs though. Especially since Unicode is an evolving standard, I am sure the table discerning full-width versus half-width characters will be outdated in a few years. ---------------------------------------------------------------------- 7. Finally... Violet won the "most in need of transparency" award in the IOCCC, another clever title by the IOCCC judges. I am sure it's the functionality that won, but I am just glad that another anime character made her way into the IOCCC repository for another year. Violet is the second ASCII art inspired by Kyoto Animation to win the IOCCC, first one was Fuuko (http://uguu.org/src_fuuko_c.html ). I got a lot of inspiration from anime in the 20+ years that I have been making ASCII art, and Kyoto Animation in particular was especially influential in how I perceive anime, and the world in general. I never felt a greater sense of loss than what happened on 2019-07-18 when Kyoto Animation became the tragic victim of a mad arsonist. As I look back at Violet again, I am thankful to all the great people that have brought her to life. Kyoto Animation may never be the same again, but I hope that they will continue to be a source of inspiration in the future.