It's very name ring with terror.
Every year, hundreds of hackers download the puzzle, work on a solution for three days, and post their results to be judged and scored. Unlike other contests, this one is a tradition, not a PR stunt or hiring gimmick, and the task to be solved is generally solvable, is entertaining, and is educational.
It really bugged me that so very few people who have made Phoenix.PM meetings joined Brock, his friend David, and I to particpate in our little team, and after some thought and time, it occured to me that to not compete is a heinous disservice to yourself as a programmer, similar to never buying that first programming book when you're a kid, or spending that money on crack rather than your first computer -- but slightly less pivitol.
I always feel like I've grown a bit as a programmer after completing these. Any mediocre programmer can contrive a task that's hard; only a great hacker can create a puzzle that forces you to confront your own inexperience and put you in one of these rare pivital situations where you have the concious choice and chance to expand your mind.
And "puzzle" doesn't do these challenges justice -- just as with the DEFON CtF event, the game itself is a masterpiece, and the result of much hard work -- even a small universe unto itself. This year's puzzle was a small operating system, complete with compilers for various languages, user accounts, crackable passwords, home directories, documentation, and hundreds of little gems of prose and code scattered around, all forming an adventure, part of which *was* an Adventure-style game that benefited from some protmatic automation due to the absurdly large and recursive puzzles contained within.
Rather than my typical moralizing, I really wanted to post about what *I* got from the competition this year (which wasn't more than a small fraction of what it offered), but I got distracted. Let me do that now.
1. VNC, x11vnc (export your desktop via VNC), GNU screen (something like VNC but for xterms, and famous for offering multiple sessions) are god sent. We had three programmers in a room, all with immediate access to each other's screens (nearly, most of the time). This let us quickly move into and out of pair-programming arrangements to get second set of eyes when dumb things were stumping one of us. If you've ever played an Infocom game of medium or harder difficulty, you know first hand that a second set of eyes is god sent when dealing with difficult problems where it's easy to go awry or miss suble answers. The main problem we had, taking too long to get the VM up and running, was delayed largely by *not* getting in that second pair of eyes. One person can stay stumped by a series of small gotchas for a week, turn out a program of this size and complexity, and be far and beyond above the average level of productivity for a programmer, and generally be doing well -- but to compete effectively head-to-head with smart hackers rather than typical office workers, you have to do better. If you IRC, you'll see the smartest hackers asking for help, now and then. Any arrangement that makes this easy, casual, and non-invasive to other's concentration is a great tool. Take time to do code reviews and code audits for fellow programmers who think they could benefit from it. Not doing that delayed finding fixes for bugs and cost us all time.
2. Minimize waste by being smart about success on critical tasks -- Getting the VM up and running was a major stumbling block -- before we run explore the virtual universe, we had to write our own VM to run the universe. Documentation for the bytecode (wordcode, actually) format was provided. One of us sat out to do it. I set off to do other things that I *thought* we would need (write a good disassembler and tracer for the VM -- completely useless). The basic approach taken on the first VM implementation (writing it in Perl -- too slow) was wrong, so someone had to start over, and that was me. I wrote it up again from scratch in C. We did two implementations back-to-back taking (rounding up here) two days. So, six man-days went into getting this first obsticle out of the way before the real work started. If we'd instead started parallel development immediately and recognized this as a critical task that must be completed before we could even *speculate* about what else might need to be done, less than three man-days would have been sunk into it. As it turned out, what needs to be done afterwards is obvious, as is often the case. Why less? Because if the third programmer were also doing a VM, there's a good chance he would have finished in less time than the other two also working on the task. So, when something needs to be done before an accurate assesment of the situation can be made, put more than half of your resources on it, and take advantage of parallel teams working on the same problem.
3. Use parallel teams -- don't put all of your eggs in one basket, as the saying goes. With programming, you making thousands of assumptions, sometimes at the rate one of a second, and it's extremely easy to make an assumption that's wrong and then be at a loss to find it admist all of the complexity and other assumptions. Adding more people will help find these problems to a certain degree, but as a concensus is reached on each implementation detail, mistakes still get made. By doubling the number of parallel implementations, you're having the chances that one really nasty bad assumption will get lodged in the code and sap man-days in attempt to fix it.
4. It's nearly impossible to write verifibly correct code in C (if you can do it, you're a god, or else more likely, you're mistaken -- millions of people are mistaken about this and the universe of remote code execution flaws is proof). Perl has a lot of helpful tools in this area. However, if you're part of a project that needs to write code and have an extremely high level of confidence in it without a long debugging, beta-test, maintence cycle, it's time to check out functional programming languages. By contrast, the sort of side-effects happening in the C interpreter almost drove me to tears -- a printf() with too few arguments would corrupt the stack and make the program execute a thousnd VM ops later in an unrelated place. Imagine the extreme opposite -- no action-at-a-distance, and all bugs are right dab smack in the middle of the logic for the feature they aflict. ICFP was created to advocate functional languages and functional programming, and it does a good job of that -- usually.
5. This isn't something I've learned but something reinforced -- bring people of all backgrounds onto a project. Our collective backgrounds satisified needs for assembly programming, VMs, ML, C, gdb, Perl, parsing, goal directed evaluation, adventure games, and a lot more. That's not entirely realistic in an office setting, but almost any project can benefit from experience across the fields of parsing, functional programming, Perl, C, assembly (low level), Unix, networking, user interface, bug tracking, testing, and a whole lot more. In fact, if you're interviewing someone that has a long, interesting background in damn near anything, hire them! You're not qualified to wager a guess about how they might be able to help. One of the worst things you can do is hire 1,000 people who have experience with nothing but Java. Even in a 100% pure Java environment, most actual problems you come across aren't Java problems -- they're gaps in theory, gaps in low level understanding, holes in history, and in general, gaps in background. The more tools -- and trades -- you have on hand, the better.
As far as what I actually learned about *programming*, I picked up a touch of ML, and discovered even more C pitfalls in addition to the ones I knew about that made me not want to use it any more