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.

Notes After 8 Weeks at the Recurse Center

I just finished week 8 of a 12-week "batch" at the Recurse Center, which is a diverse community of people who come together to help each other become better programmers. The community includes both current attendees and "alums" who stay connected in various ways.

Each week I've been here has been better than the last. Yesterday, for example, I learned more than I do on an average day:

  • I learned some Python.
  • I saw a neat algorithm using matrix multiplication.
  • I got an explanation of Markov chains.
  • I attended an excellent talk that was an introduction to dynamic programming.

All this learning was unplanned except the talk on dynamic programming, which I had signed up for in advance. For example, yesterday morning I noticed some people were working on a problem on HackerRank. I got the urge to tackle it myself, and used it as an opportunity to practice Python coding, which I've been meaning to "get around to" for years. (In case you're wondering, my solution passed all of HackerRank's automated tests, but only after a bunch of fixing and reworking.)

All learning at the Recurse Center is attendee-driven. There is no lesson plan, there are no formal deliverables, and there is no certification at the end. Indeed, RC's motto is "Never graduate." We attendees show up on day 1 with some idea, possibly vague, of what we want to work on. It is perfectly fine, even encouraged, to change our minds about this over time, as long as we stay ambitious. We spend most of our days coding, studying, "pairing", doing self-organized workshops and presentations, and socializing.

RC occupies an office space in Soho, a stone's throw from Chinatown. It's a quick subway ride from my apartment, and I can walk home in less than half an hour. I think there's about 50-60 of us here during peak hours, including staff.

The interior resembles a typical open-plan tech startup office. I'm generally against open-plan design, but I like it in this case, because it serves one of RC's goals, which is to encourage us to interact with each other. I don't feel like the activity around me is intrusive; on the contrary, I like overhearing what people are talking about. Also, since there is no pressure, competition, or judgment regarding what I'm working on, I don't feel the exposed anxiety I would feel in an otherwise similar workplace setup.

Besides, the space isn't 100% open. There's a library with books on all kinds of programming topics, and there are rooms where people can hold meetings or just sit and program quietly when we don't feel like working in the open area. Every room is named after a famous computer scientist. Right now I'm sitting in Lovelace. The biggest meeting room is called Hopper. Various parts of the open area also have names: Dijkstra, Ritchie, etc.

Another nice aspect of the physical facility is that the WiFi is very fast and reliable. This means one less hassle in our day-to-day lives getting in the way of progress.

The Recurse Center strongly emphasizes diversity and support for groups that have been underrepresented in tech. I've met attendees from countries including Poland, the UK, and Singapore. All experience levels are represented. We skew pretty young, as in like 20's or 30's, but there are middle-aged folk like me as well. The community includes gay people, trans people, and black people — all in small but still, to my mind, significant numbers.

By design, roughly half the attendees are women, and WOW does that make a difference. I've worked with and for women before, but never alongside this many, not by a long shot. It changes things in a way that I'm not sure yet how to describe, except that I feel more comfortable being myself.

Speaking of comfort, there are four gentle "social rules" we're expected to observe:

  • No "well actually's".
  • No backseat driving.
  • No subtle "-isms" (sexism, racism, ageism, etc.).
  • No feigned surprise (as in "I'm surprised you didn't know X", which can have the effect of belittling relative beginners).

I suspect I was the first person in my batch to break one of these rules. On the first day, I brought some batch-mates to Chinatown for dim sum. I caught myself assuming I was the only one proficient with chopsticks. Subtle racism — mea culpa.

The Recurse Center selects attendees through an application process that includes two Skype interviews. You don't have to be a genius or a rock star to get in, although there are definitely people here who impress the heck out of me. My application process felt like the best "job interview" experience I've ever had, in terms of both making me feel understood as a person and making me feel like these were people I wanted to work with.

Attendance is 100% free. RC supports itself through job placements for its attendees. There are lots of support activities for people preparing to go job hunting, including interview practice sessions. There's no obligation to go through RC to get a job or even to be on the job market. And job-related activities should not distract from the primary business of learning and improving as programmers.

I hope to keep sharing more about this place. The staff, for example, is terrific. I might try to think of some complaints; nothing's perfect, after all. Until then, I'll just say this is the best thing to happen to me in a long time.


I'm halfway through a 12-week stint at the Recurse Center. One of the first things I did was to write a silly chess app called "ChessFidget" to help myself learn Swift. Here's more about it, including the source code. There's a link in the README to a double-clickable binary you can run without having to compile the code.

Here's a 5-minute presentation I gave about it:

The Incredible Shrinking Docs

Wouldn't you know, I was wondering about documentation in Xcode 8, and indeed it has fundamentally changed. The DevPubs team has hugely reduced the size of the docs and apparently integrated them with Xcode so that there is no longer a need for a separate download step.

Running the Xcode 8 beta, I find I'm able to browse the docs with WiFi turned off. I know I'm looking at the Sierra docs, because NSGridView is there. Furthermore, docsets are no longer listed in the Downloads pane of the prefs panel. It's like magic — kudos to the DevPubs team!

I'm guessing this news about the docs was announced during the Platform State of the Union. I missed that session when it was live-streamed, so I'll have to watch it later. I'll see if it confirms my understanding, and I'll think about implications for AppKiDo.

The Developer Tools people at Apple have a lot of momentum lately. I can't remember when it felt so much like they were working hard to connect with us, to show that they hear us (the culture around Swift seems incredibly positive), to create cool tools, and to take away pain points.

I wonder if squashing the documentation size was important not only for Xcode but for the Swift Playgrounds iPad app and/or future possibilities for using iPads for development.