Much ado about null
Posted:
null is controversial, and often derided. But let's go a bit deeper and understand what it means to mean nothing, and let that guide us to better error handling.
Technical thoughts, tutorials, and musings
Posted:
null is controversial, and often derided. But let's go a bit deeper and understand what it means to mean nothing, and let that guide us to better error handling.
Posted:
Over the last few weeks, I've been following Advent of Code 2021, using Functional PHP as an approach. It's been a fun and educational process, at least for me and apparently for a few other people, at least given how popular the articles have been.
For reference, the full list of articles in this series is here:
After letting those sit for a few days, I want to use those examples as a way to evaluate how well PHP handles functional-style programming and what improvements we could make to the language to make it even better.
Posted:
For the 10th Day of Advent of Code, we're asked to solve a matching braces problem. This is a common parser exercise, but it's made a bit more complex in this case by using multiple types of braces. Specifically, we're handling a series of lines that contain ( and ), but also < and >, [ and ], and { and }.
The story jazzes it up as being the code of our submarine's navigational computer, which consists entirely of braces in a sort of eldritch horror version of brainfuck, but that's mostly just a distraction.
We're told up front that most of the data lines are bad. None, in fact, are properly balanced. Some are corrupted by having an invalid character (say, a ] closing when a } closing was expected), while others are just incomplete. (Seriously, who wrote this submarine's computer system?)
The instructions say to ignore incomplete lines for part one and consider only corrupted lines. It's a safe bet that part two is going to have us consider the incomplete lines (spoiler alert: it does), so let's save time and consider both possibilities. The problem, then, is to find lines that are corrupted and find their first illegal character.
Then we want to turn the character into a point count and add those up, again mostly just to prove that we did it with a single final answer. Let's have a go at it.
Posted:
Day 9 of this year's Advent of Code revolves around grid interpretation. Specifically, we are given a grid of numbers and want to find the low points, that is, the numbers that are smaller than any of their orthogonal neighbors. (We're told to ignore diagonals in part 1.)
After finding the low points, we need to do a bit of math on each one, and add them up. As usual, this last step is mostly just to produce a single verification number at the end. That part is easy as usual, but how do we find the low points?
Posted:
Advent of Code Day 8 was, to put it mildly, a pain in the ass. There's a couple of reasons for that. It's a naturally tricky problem, it's hard to genericize, and it's explained fairly badly. It took a while but with some help from others I was finally able to figure out (and refactor to) a good, functional solution to it. So let's dive in.
The problem boils down to one of encryption. Our input is several lines that all look like this:
acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf
Where each letter corresponds to one segment in an LED display for a number. Each number appears once on the left side, which is enough for you to figure out what letter corresponds to what segment. Then we need to use that knowledge to decode the numbers on the right and figure out what the number is.
Posted:
Advent of Code Day 7 this year is another problem that's more about the math than about the programming, so we won't see much in the way of new functional techniques. Still, there's some interesting bits in there.
Today we need to calculate the fuel costs of moving a bunch of crabs in submarines all into a line. (Don't ask. Really, don't ask.) Essentially we want to center-align a series of points using the least "cost" possible. Crab positions are represented by a single number, as crabs can only move horizontally. (Because crabs.)
The trick for today is realizing that the crabs don't matter; it's a distance-cost calculation. In part 1, the cost for a crab to move one space toward whatever alignment number we want to pick is 1.
Posted:
After the last two days, Day 5 of Advent of Code is almost mundane in comparison. Today we're asked to read in the definition for a series of lines and compute how many times they intersect.
The process is much the same as the previous days: Parse the incoming data into some sort of data model, then run some computations on it. And both parts will consist primarily of pipe() operations, since we're really just shuffling data from one form to another.
Our input data looks like this (albeit with a much larger range of coordinates):
Posted:
Day 6's challenge is a little fishy. Given what we've already done so far, it's pretty simple. The only catch is making sure you do it in an efficient way.
Specifically, we're asked to model the growth patterns of fictional lantern fish. In this silly model, we start with a list of fish at various ages. Each fish spawns a new fish every 7 days, and a newborn fish takes an extra 2 days before it starts spawning new fish. Fish also never die. (Someone warn the AI people that we've found the paperclip optimizer.)
Part 1 asks us how many fish there are after 80 days, all around the world, given the start data. Let's find out, but let's do so efficiently.
Posted:
The third challenge in this year's Advent of Code is all about bit manipulation. We're asked to read in a series of binary numbers and interpret them in various entirely illogical ways as a form of diagnostics. (Incidentally, if you ever write a system that requires this kind of logic to debug its output, you're fired.)
In any case, we're given a file with a list of 12 digit binary numbers and asked to compute various values. In the first part, we are asked to find the most common bit (0 or 1) in each position, and the result is known as "gamma." Then we have to find the least common bit in each position, and the result is known as "epsilon." (I don't know why you would want to do this; it's all Greek to me.)
In practice, the functional part of the solution isn't all that challenging. It was the bit-wise manipulation that was tricky, as I rarely do bitwise operations. But we do get to show off a few new functional tracks, so let's dig in.
Posted:
Day 4 of Advent of Code has us playing bingo against a giant squid. (Don't ask; I don't understand it either.) More specifically, we want to take an input file that consists of a series of numbers that will get called, followed by a series of boards. We then need to compute which board will be the first to win, following the standard rules of bingo (although with no free space in the middle, the cheating squid...).
This sort of problem is inherently very stateful, and thus, frankly, not a good fit for functional code. It absolutely can be done in a functional way, but it's not the best fit. We're not interested in the best fit in this series, though, just how it could be done functional-style. So let's do it functional style just to say we did. Along the way we will really exercise the function composition concept, and show a few other tricks along the way.
Onwards!
Showing page 1 of 3