Notes After Finishing Advent of Code 2016

I finished this year's Advent of Code. I'd love to go back and clean up my code and write notes about each problem and the process I went through and the things I learned. Maybe I'll get around to that, maybe not.

Here are some ways of doing things that I found useful.

  • Write code to help visualize the problem. Helps me; YMMV.

    • Write code that draws pictures of the data. Take a hint from the problem descriptions — generate pictures similar to theirs. I found this helpful for the maze problems, among others. And sometimes it just makes things more fun.

    • For one problem I found that simply writing code to generate the following from the input helped me feel less confused about what had to be what mod what:

      we want t % 13 == 11
      we want t % 19 == 7
      we want t % 3 == 1
      we want t % 7 == 2
      we want t % 5 == 2
      we want t % 17 == 6
      
    • Another textual "visualization" aid: I used comments and indentation to mark up the "assembunny" code so that I could understand better what it was doing (here's what I did).

    • I didn't do much analog drawing (on paper or whiteboard), only a little during the later exercises. I used to be a compulsive whiteboarder — I'd like to recultivate that instinct.

  • If something feels like a hint it probably is, at least for AoC.

    • Example: for some reason Day 22 (moving data from disk to disk) was by far the hardest for me. I'm not sure how much or or how little that was due to inherent difficulty of the problem. But I do know I kept sabotaging myself by not letting the hints sink in, even when I was vaguely aware that the author of the problem was trying to tell me something.
  • Study the data — look for simplifying assumptions you can make that might help you get the answer by solving a less general case than the problem description alone might lead you to believe.

    • Day 22 is an example where this made all the difference in the world. Another that comes to mind is the "assembunny" problems.
  • If something is taking crazy long to execute, you may either have misunderstood or misread the problem, or you may be overlooking a hint.

  • Instrument your code with printf's that periodically show things like the size of your cache. This can provide clues to where there are leaks or inefficiencies in your code. For example, I realized my A* implementation was not properly putting nodes in the closed set, which led to an explosion of the open set — no wonder it was taking so long!

  • Testing. Do regression tests. Test the example data, which should run almost instantaneously, before trying your solution on Part 1. If Part 2 requires a lot of additional work, see if you can do sanity checks along the way to see if your code still solves Part 1. Sometimes your work on Parts 1 and 2 will be different enough that you can't really do this.

Swift vs Python for Advent of Code

Lately my daily addiction has been Advent of Code. It's a two-part programming challenge posted every day at midnight from Dec 1 to Dec 25. As long as you submit the right answer, you can use any language you like, or pencil and paper for that matter. It's not like some programming-challenge websites where they validate your solution by executing code that you submit.

I've been going back and forth between Swift and Python, both languages I'm new at. It's been a useful learning experience, both at the nitty-gritty level of language details and a more meta level about how I could maybe solve problems better. Sometimes I port my solutions from one language to the other, either to compare how the languages feel, to compare how the code performs, or simply for practice.

Lately I've been strongly preferring Python as my go-to language for these exercises. I have three main reasons.

Reason One: my Python code launches quicker without needing a moment to compile like Swift does, which means I can test and iterate faster, which means more immediate gratification.

Reason Two: simple string manipulation and array slicing are much quicker to code in Python, which means I do less typing and my simple intentions aren't buried in syntax. I wonder how daunting the learning curve seems regarding Swift strings, whether for new programmers or programmers coming to Swift from other languages. I wonder if there are some simplifications I'm missing.

Reason Three: it's trivial in Python to get an MD5 hash, which a few of this year's exercises have been requiring. People have written Swift wrapper code that does MD5 hashes, but every time I start to explore my options I think, "I'd rather work on solving the puzzle I wanted to solve, and I can do that right now in Python." Again, immediate gratification. Also, the Swift wrappers I've seen all require using an Objective-C bridge, which as far as I know requires using an Xcode project, which makes things heavier than I'd like.

One thing I'd like to revisit and get better at is using Swift playgrounds (with a lowercase "p" as in Xcode, not an uppercase "P" as in iPad; it drives me curse-out-loud nuts when I try to Google for the former and only get results for the latter). I tried using playgrounds for the early Advent of Code exercises, but I felt too attached to using breakpoints and lldb, which aren't available in playgrounds. Instead I've been using CodeRunner, which conveniently integrates debuggers for both Swift and Python. It's just right for this kind of lightweight coding and experimenting.

Here's my code. Note that this is not production-quality code. It's often sloppy, it often misses opportunities to solve the problem in a smarter way, it almost always assumes valid input, it's under-commented, and in at least one case it's way over-engineered.

Some Ways I Use Keyboard Maestro

Today, thanks to Michael Tsai, I found out there's a major new release of Keyboard Maestro. I use Keyboard Maestro all day long, and look forward to checking out the upgrade when I have time.

Here are some ways Keyboard Maestro makes my day go much more smoothly:

  • I use the palette feature to navigate to frequently used apps and documents in exactly two keystrokes.

  • I have a "Preferred Window Frame" macro that sets the active window's size and position. My preferred frame varies from app to app, and the macro does the right thing depending on which app is active. Just one keystroke to remember. The macro invokes keyboard shortcuts I've configured in Divvy, but I could also have entered window coordinates directly into Keyboard Maestro.

  • I map ^P/^N to UpArrow/DownArrow so I can use those emacs keys to go up and down in lists, menus, and other places outside of text editing. The ^P/^N keys already work in many apps, but not all, and not in all places within the same app. By setting up this global mapping, I don't have to remember where they work and where they don't.

  • You can create text expansion macros. I have macros for inserting date and time, for a few phrases I type on a regular basis, and for emoji characters. I was happy using Keyboard Maestro for all this but recently moved my text expansion macros to aText, a very nice app at a very reasonable price. My reasons for switching were minor and arguably not worth the time when I had a perfectly good solution. I wouldn't and perhaps shouldn't have bothered, except I am such an obsessive yak shaver.

  • I sometimes use Keyboard Maestro instead of System Preferences to provide alternate menu shortcuts. I do this because Keyboard Maestro syncs my macro definitions on Dropbox, which means that when I make a change, all my Macs automatically get it.

  • I open Xcode's Recent Files menu with one keystroke (I use ^R) instead of three (^1, DownArrow, RightArrow).

  • I have a scratch macro named "Pipe Text" that replaces the currently selected text by piping it through a shell script and pasting the result. The macro has an "Execute Shell Script" action that I edit to do what I have in mind, typically a grep.

  • I keep a personal log in the form of daily text files. I have a macro that opens today's log file in BBEdit, after creating the file if necessary. I use this throughout the day whenever I think of something to add to the file.

I'm happy to share how I do any of the above.

I'm Fine With the Accents on "Fresh Off the Boat"

Yesterday I watched the first two episodes of Fresh Off the Boat, a sitcom loosely based on the childhood of Eddie Huang. It's the first network show in 20 years starring an Asian-American family. The previous one, Margaret Cho's All-American Girl, didn't do too well, so anticipation and expectations were high for Fresh Off the Boat.

Last year when the first teasers came out for the show, viewers' reactions included some concern about the accents of the parents, played by Constance Wu and Randall Park. To me, the accents did indeed sound off-key, but based on everything else I saw, I reserved judgment. I figured maybe I wasn't familiar enough with Taiwanese accents, since I'm more used to the Hong Kong accents in my own family.

Mainly I wanted to take the attitude that I take with Apple product announcements. Whatever optimism or doubts I may have, I always reserve final judgment until I've had hands-on experience. I learned my lesson about that in 2007, when Apple shipped the first iPhone. I was excited about it but thought I could hold off on getting one. I figured I'd wait for other people to find the bugs and for Apple to work out any manufacturing glitches. But then a friend let me play with his iPhone, and I was immediately hooked. The hands-on experience far exceeded my expectations. Minutes later, my friend walked me to the Apple Store and I bought my own iPhone.

This week ABC "shipped" the first two episodes of Fresh Off the Boat and I finally got to go "hands-on". And you know what? I loved the show so much I watched both episodes twice. The show is honest about race — there's a scene in the pilot episode that I think people will be talking about for a long time — but at heart it's a funny show with some poignant moments and some moments of dark humor (though not too dark; remember, this is ABC, not HBO). The narration by the real Eddie Huang adds great depth to the flavor of the show.

I found that the more I watched, the less I cared about the accents. They might be pitch-perfect, or they might be as questionable as James Doohan's impression of a Scot. I'm still not sure, but I don't care any more because I like the characters, and I like them just as they are. I doubt most of non-Asian America will care either.

Put it this way: I find Jackie Chan's genuine accent way more distracting than I ever found Wu's and Park's simulated ones, and I still love Jackie Chan movies.