Advent of Code 2025

This year Advent of Code ("AoC") was only 12 days instead of 25. Last year I solved all 25 days (both parts) and that felt pretty good. This year, I also solved both parts of all the days, but given the overall puzzle count was lower, I’m not finishing with quite the same sense of achievement as last time.

I have mixed feelings about that. I’m simultaneously grateful that this year wasn’t a gruelling ordeal, but also disappointed that I didn’t feel stretched by it. Given how important AI has become in my working life as a software engineer, I had been looking forward to AoC as something that would force me to use my brain to create code solutions instead of using it to engineer prompts.

In a "normal" AoC year, the puzzles on the first days are relatively trivial, and the difficulty slowly ramps up from there. Around the middle of the month, you might find a day that is unexpectedly difficult or unexpectedly easy, but the general progression is clear. Towards the end of the month there are generally some "epic" problems that feel really satisfying to solve.

This year, folks were wondering what would happen given the shorter schedule? Would the difficulty ramp up more quickly? Would the final days this year be just as hard as the final days of prior years?

It’s really hard to give an objective answer to that, so I’ll give a subjective one instead. My impression is that no, the final days weren’t as hard. One of the reasons why the 25-day schedule feels so tough is precisely because it’s like a marathon: if you’re going to beat 25 two-part puzzles of increasing difficulty you have to bring a maintained level of intensity and commitment to carry you through to the end. With a merely 12-day schedule, it’s more like a sprint.

This year, there were two or three days that I found to be disappointing:

  • On day 9, I felt pretty good about my part 1 solution, which used bitwise operations to great effect (the code was simple and the solution ran fast), but part 2 ended up being too hard (for me) to solve without using a linear programming library…

    I initially represented each problem as a multivariate linear Diophantine equation and was able to solve the simple cases (eg. ax + by = n) using the Extended Euclidean Algorithm, and then I started extending it to trivariate and larger cases (eg. ax + by + cz... = n) before discovering that, while I could solve the equation, minimizing the coefficients was going to require a bunch of linear programming tricks that were beyond my reach. You’re supposed to solve the puzzle relatively quickly (ideally, the same day it is published), and coding up and debugging the kind of linear solver that I would need would have taken days, or maybe even weeks. So, I reached for an existing library and used that to find minimal solutions to a system of linear equations.

  • Day 11 (part 2) felt a bit unsatisfying in a different way. It was a graph traversal problem where a naïve DFS approach would involve some ungodly number of operations. You had to count the number of paths in a Directed Acyclic Graph starting from a given node, passing through two other specified nodes — call them a and b — (in any order), and ending at another.

    As I said, a simple DFS searching from start to finish would take forever, so I tried it out on some of the subproblems: start to a; a to b; b to a; a to finish; and b to finish. I also reversed the edges in the graph on the chance that finding the paths in the backwards direction was any easier (it was). Armed with this information it was clear: there were no paths from b to a, so all I had to worry about was solving the three subproblems: start to a, a to b, and b to finish. Solving any of the equivalent problems in the reversed graph would be valid too (ie. a to start, b to a, or finish to b). Once I had the path counts for each of the three segments, I just had to multiply them together.

    So, I set about solving the subproblems, and when I found one of them to be stubbornly resisting my DFS, my first thought was that, if I switched to a BFS, I might avoid a lot of time spent going deep into unproductive pathways via DFS. As a shortcut, I figured I would test this idea out first by coding a depth limit into my DFS, before going to the trouble of writing a BFS. And as I progressively increased the depth, the answer stabilized, and eventually settled on just over 7.5 million paths for that last segment that I needed to solve.

    Multiplying all this out gave me the right answer of 553,204,221,431,080 paths. Part of me felt like I should have been happy to narrow it down from "zillions" to a correct answer of some 553 trillion odd paths, but it didn’t feel like that at all. It felt more like I’d carried out the computer-assisted calculation by hand instead of constructing a general algorithm to solve the problem. I think if I’d written it as a BFS in the first place instead of a DFS, I would have felt better, although I still would have had to hard code a semi-arbitrary depth limit in there somewhere…

  • Day 12 was much worse. On the surface, the puzzle looked like a set of large combinatorial problems with exponential complexity, even one of which would have made a brute force approach unfathomably expensive. I jotted down a bunch of heuristics for pruning the search space down, but none of them promised to be remotely enough. I decided some research was in order. I skimmed a bunch of articles on packing irregular objects and came to the conclusion that my best bet was going to be to use simulated annealing; partly because it’s a good tool for approximating a global optimum even in an enormous search space, and partly because it’s easy to understand and I’ve used it before. There were 1000 problems in the puzzle input, but I didn’t even need to find global optimums for them all; I just had to find packing configurations that were good enough to get the job done. Surely (subtle foreshadowing), many or most of the problems would be solvable using this approach.

    All of that without writing any code. When I finally sat down to write some, I was delighted to see the genetic algorithm find solutions good enough to pack the sample problems. I ran it on the actual puzzle input and was even more delighted to see it work on the vastly larger problem set too.

    But I felt uneasy. Surely, it shouldn’t have been that easy, should it? I dropped into the channel at work and saw that only one person had shared a solution. I looked at it, wondering if they’d used something stochastic like I did, and was appalled to see that they didn’t do any packing at all. Yes, that’s right: the puzzle input doesn’t actually require you to rotate or fit shapes together at all; rather, you can count the number of shapes, compute how much space they’d need if they were all 3-by-3 squares, and see if the provided space is enough.

    Good lord. One of my shower thoughts based on eye-balling the puzzle input had been that, of the thousand problems, there was probably some subset that was trivially and obviously packable into its corresponding space, and another subset that was trivially and obviously not packable. Maybe I’d be able to eliminate a few hundred of the former kind and few hundred more of the latter, leaving me only having to solve the remaining few hundred that were on the borderline.

    Well, it turns out that all the problems could be trivially classified and counted like that, and there was no need for my fancy simulated annealing algorithm at all. I kind of felt deceived, because the sample input wasn’t trivially classifiable in that way. My initial satisfaction at coding up the algorithm and seeing it work was replaced with a feeling of regret for not having followed up on my shower thought sooner.

Mechanical watches

Every now and again, I decide to look into a field of interest — like home networking, or mechanical keyboards, or meditation — and after the first web search or two, I discover communities far larger and more deeply devoted to the pursuit of the subject than I would have thought possible. I stumble into the subreddits with their jargon, their memes, their local "zeitgeists"; I discover the YouTube influencers I’d never heard of before but which have 3 million subscribers each; I see the uncountable listicles of "Top 10 X’s in some subspeciality Y (2025 edition)". I’m always surprised at the scale and depth of activity, and often a bit scared, but at the same time a little bit awed.

This has happened most recently for me for the topic of mechanical watches. It occurred to me that my practice of using my mobile phone as a timepiece was getting under my skin — because it meant that I often got distracted by notifications when all I wanted to do was see the time — and that wearing a watch would eliminate my single most frequent reason for pulling my phone out of my pocket. This is somewhat of a reversal of my previous position that concentrating the maximum number of functions into the smallest possible number of devices was an embodiment of minimalism and simplicity. It turns out that it’s perhaps not that easy. I began to wonder if maybe consolidation isn’t always the answer, and that simplicity might sometimes best be found in simple objects that do one thing alone. Not so much the "Internet of Things" as "Things Without Internet".

So I innocently typed "mechanical watch for men 2025", expecting to get to the bottom of the matter after an hour or two’s investigation. Sweet summer child. Little did I know that when I peeked behind that door I’d find one of those larger-than-I-could-have-imagined internet ecosystems with all of the hallmarks of one of those communities of belonging in which people take the hobby to an extreme, constructing an identity around being "watch nerds" and collectors, and shelling out gobsmacking amounts of cash to acquire these intricate machines, sometimes in a multiplicity that no two-wristed mammal could realistically expect to make sufficient use of in any reasonable way.

The first thing I discovered was that there aren’t just "mechanical watches", but "field watches", "dive watches", "tool watches", "pilot watches", "engineer watches", "racing watches", "dress watches", and countless other genres. There are titans, luxury brands, value brands, "micro brands". Every possible axis of decision-making is populated by a range of options from the obscure to the mainstream, from the traditional to the avant garde, and from the economical to the profligate. Even after my relatively elementary excursions into the subject, I could probably already put together many thousands of words talking about all the choices one has to make to whittle it down to the watch type, feature set, price range, brand, and so on, to the point where you can actually pull the trigger and make a selection.

But that’s not my goal here. I just wanted to say that after all this, I don’t think there is a perfect watch. All there is is a series of compromises that can eventually lead you to a choice that feels right enough. At this point, after about 5 10 or so hours of research, I have looked at hundreds of watches and developed enough of a sensibility for things I like and do not like to know what I want.

In short:

  • Given that this is all partly motivated as an act of rebellion against our big tech overlords, I was initially thinking that I just wanted a simple mechanical watch (ie. a watch you wind manually), not an automatic (self-winding) one. I figured the ritual of winding the watch every day or two might make we feel some kind of edifying sense of connection with the real, tactile, non-digital world; that it would be a kind of meditative act. But I found that as I searched for watches that matched my desiderata (below) I simply found way more automatic options than mechanical ones. Out of sheer pragmatism then, I decided to fish where the schools were swimming, and I opened my mind to buying an automatic watch if that was the one that best checked all my other boxes.
  • I want what some folks call a "one and one" and others call a "daily driver". Those are actually two subtly different things, albeit closely related ones, so let’s talk about them separately. First, by "one and done", I mean I only want one watch. I don’t want to start a collection. I want to buy something good enough that I won’t find myself angling for an upgrade soon after buying it. But neither do I want to break the bank buying something extravagant before I’m even sure that I’ll truly commit to wearing the thing every day (after not having worn a watch for most of my adult life). I need it to be versatile enough that I can use it for everything. This is where the objective starts to blend with that of "daily driver". Versatility means something casual enough to wear with a pair of shorts or jeans, but also compatible with an office environment or a formal one (relatively rare for me, but I do sometimes need to dress up). That in turn means a bunch of other things, like not being too bulky (or too small — it has to be in the "Goldilocks" zone), not being too heavy, but also being robust.
  • I don’t want something ostentatious or luxurious; both of those just sound like recipes for spending more money than you need to. I’m not drawn to big brands — in fact, I feel somewhat of a revulsion to them — although I do appreciate quality. I have no interest in owning a Rolex, nor indeed any of the even-more-expensive brands that you could describe as "something that rich people buy, not because it’s better quality or more functional, but because it signifies that the buyer is rich". When I look at those, I don’t think "I wish I could afford that", but rather, "Yuck!". So, my goal is to find something that is good value for money, but keeping the price down isn’t my primary motivation; merely something to be balanced against other objectives.
  • So, to recap a theme that is developing over the last few points, I want a watch that I can use all the time without having to worry about it getting damaged or stolen; it should be durable and not too expensive. I want this thing to be good enough to last a lifetime or at least a sizeable chunk of it, but it need not become a family heirloom.
  • I don’t want it to have any "bling" too it (ie. no shiny metals), I prefer it to have a matte finish or a brushed metal look (it really has to be metal so that it can straddle the divide between casual and formal). I prefer a black face because that is going to pair well with more contexts (clothing, environment etc). I’m not really interested in having a "dress watch", but I want something that looks respectable enough to use in dressy situations. I like watches that look a bit masculine, but not absurdly so (chunky things that look undecided about whether they’re timepieces or tanks).
  • Aesthetically, I value simple, utilitarian design. I don’t need bells and whistles. I don’t need a diving bezel, I don’t need UTC or word clocks, nor a chronometer. About the farthest I’d go in the direction of "complications" if you can even call it that, would be a date window. My eyes aren’t getting any better, so I want a simple face without anything "busy" on it. And in terms of branding I want something that doesn’t scream out the name of its manufacturer; I want something subtle and discreet.
  • These requirements push me into the realm of "field watches" and their neighbors. The watches that have resonated the most with me so far tend to be described as "tool watches", sometimes "field watches", or "pilot watches". There are some watches that inhabit spaces near enough to multiple categories that they wind up making it into more than one "top list" for different categories.
  • As much as one might want to come up with a mathematical formula for ranking all the options against one another, there is a huge subjective element to this. Once I’ve ruled out a bunch of watches because they clearly don’t meet requirements, I am left with many (dozens) that come close (albeit none perfectly hit the bullseye). So, the rest comes down to intuition and subjective preference. Many you can drop down the list because they don’t "spark joy". It might be a question of proportions, or a curve, or the font used in a logo or a numeral. Conversely, something else is going to rise to the top of the list simply because it "feels" somehow right.
  • I love watches which show off the movement via a transparent back cover, but I recognize that’s just a whimsical and emotional thing, and I know that my other criteria (about ruggedness and simplicity etc) bring me into territory where many of the options I’m looking at don’t have this feature; it’s definitely a "nice to have" and nothing more. If I choose a watch that doesn’t have it because it’s the way to obtain all the other things I’m looking for, then so be it. Similar to the "wanted mechanical, but will end up with automatic" situation I described above, what we have here is "would have loved a visible movement, but am not going to get one" scenario.
  • How much to spend? Given that you can find watches for anywhere between, say, 50€ and 50,000€ (or even more, but I’m talking about the kinds of watches you can at least see in online stores, not the kinds of limited edition or rare specimens that you can only find at auction) you need to have some way of setting a budget. The fact that I want a "one and done" watch tends to exercise an upwards pressure on the price I’d need to pay, because I don’t want to buy something cheap only to regret it soon after. But my level of inexperience must exercise a countervailing, downwards pressure; I don’t want to blow a wad of cash on something only to experience buyers remorse. This is very context dependent, but as a rule of thumb, say that you’re living below you means (ie. not living paycheck-to-paycheck, but able to save some percentage of your earnings every month), then you should be able to define a threshold in terms of your income. For example, if you are living modestly with no debt and rarely spend on "discretionary" material goods, then you might be a able to set a guideline like "half a month’s salary" (as of 2025, the average monthly net salary in Spain is about 1,800€, so that would be 900€). Depending on your psychology and your personal circumstances you might be able to push higher, or need to go lower. Me personally, where I am right now, I feel at peace with the idea of spending about a quarter of my monthly salary (ie. one week) to get this watch. That’s enough to get something nice, but it keeps me far away from anything which might be considered extravagant.
  • Finally, I’ll say that I’m not interested in "micro brands". I don’t care about being the only guy in the office to have some rare thing from a startup that only other watch nerds have heard of. It just doesn’t matter how cool it is. I’d much rather buy something from a company that operates in many countries all over the world, so I can get this thing repaired or serviced when it needs it, and ideally a company that has been established for many decades, so that I can be relatively confident that it will still be around when both me and my watch are old and need some extra love and care. As such, I don’t have any problem with "off-the-shelf", commoditized movements from producers like Sellita and others that are used by many watchmakers; some of the better movements of this kind wholesale for a few hundred euros, and represent battle-tested, extremely reliable pieces of engineering. While I get why "in house" manufacturing can be attractive and impressive, pragmatism says that going without it is the way to go because it leads to something that can be repaired or serviced easily and offers better value for money, to boot.

So, I think I’ve engaged in enough research now, commensurate with the level of outlay I’m going to incur. Once I’ve actually followed through and gotten the watch I may have more to say here about exactly what I choose and whether I stand by the decision process outlined above. 🤞

Rate my setup

For the first time since forever I’m actually happy with my current desk setup, so I thought I’d go back and look for some photos of older setups and rate them.

2010 edition

On display we have an iMac "Core i5" 2.66 27" (Late 2009), some Harman Kardon SoundSticks, an Apple keyboard, and a LaCie external drive sitting on a glass IKEA desktop and a crappy plastic chair. Amusingly, the LaCie is sitting on a foam block to dampen the noise caused by the vibrations from the spinning HDD platters. A Blue Snowball mic can be spotted sitting up on a shelf above the desk.

2011 edition

Start-up life, part 1. The Apple keyboard is now accompanied by a "Magic" Trackpad, and we see a MacBook Air next to a decidedly-not-4K Dell monitor (to which is taped a picture of a US keyboard layout because my brain was trying to recover after being rewired when using Spanish layout keyboards). In a minor concession to ergonomics, the monitor is raised close to a suitable height by sitting on a ream of paper, but it’s not centered in front of the keyboard, something I’d never tolerate now.

Part 2. The start-up life intensifies, with an Aeron chair and a crankable standing desk (horridly unsafe, BTW, with a bespoke mechanism). The LaCie has again joined me on the desk, but this time without the foam dampening block. In typical VC-funded bubble fashion, I’ve gone from a single ream of paper to six whole reams, significantly improving the ergonomics of the setup by center-aligning the monitor and elevating the laptop (that’s what the two reams on the right are for).

2015 edition

Fast-forward to 2015 and I just moved into this fancy building at FB along with the rest of Product Infrastructure. You get a standing desk! And you get a standing desk! You get a standing desk! Also, an "ergo consult" where they give you a real laptop stand and make sure your keyboard (now a Realforce) and display are at the right height. Some kind of Apple Monitor — I don’t remember exactly which — but at that time it wasn’t a 4K or Retina one. Some fun details in there, if you look closely, like a React logo leant casually against a desk, a glimpse of the corner of Zuck’s "Acquarium" office in the background, and Joe Savona intently ripping through some some god-level-hard problem, as is his wont.

2020 edition

One pandemic later, working from home — at the kitchen table, no less — in another country. The keyboard is the same, but everything else is different. A new employer, new headphones, a shitty 5€ mouse (not even cordless), and an unfortunate new era of Apple laptops without ports (see the dongle) but with horrible butterfly switch keyboards and useless "Touch Bars".

2021 edition

Still working from home, but now from the living room, and another employer. We’re still afflicted with a cursed Touch Bar, but we have awesome Apple Silicon now. Note that the "upgrade"[1] from the kitchen table to a dedicated but non-adjustable standing desk requires an ingenious new laptop stand[2] while I send my intermittently faulty monitor away for warranty repair or replacement.

2023 edition

Better view of the same desk. Ignore the cardboard boxes (this was a moving day). Not too much has changed at this point, but I have acquired a few accessories, like a "Blue Yeti" mic and mount, and an Elgato ring light: both of those were principally chosen on the not-so-sound basis of being actually available (things got scarce in the pandemic), and I wanted to put my employer’s "home office" budget to use. Also visible: new headphones, better in many ways, and my trusty Linux desktop.

2025 edition

I’m not quite ready to show this yet, but I think I’m actually happy with my setup for the first time since basically forever. I’ve still got the ridiculous ring light, but that’s about the only thing that’s out of place any more. I now have an adjustable desk! I actually have a chair! I got rid of the rather mediocre Blue mic and upgraded to a nicer Røde one. I replaced my 4K monitor with a 5K one (a Retina-ish external display, finally). New headphones[3], courtesy of my employer. I even have a desk mat now to put the keyboard and trackpad. Not sharing a photo at this time because of one small problem: it’s in the corner of the living room and I don’t really have a good angle on it.


  1. "Upgrade" in quotes because it was a horrible, low quality thing made out of the cheapest, warped wood. I got it because it was the just pleasing enough, aesthetically speaking, that I could hope to put in the living room without becoming the most unpopular member of the household. In the end, I think I did become the most unpopular member anyway, but that’s all water under the bridge now. ↩︎

  2. Don’t judge me for my taste in books. My then-employer gave me a learning budget every year, and I ended up buying a ton of books. The ones in the photo were just the ones that happened to be the right height for my needs. ↩︎

  3. To be honest, I am not sure which QuietComfort model I’ve got, but whichever one it is, the sound is great and the UX is good too. ↩︎