Unless YOUVE LIVED UNDER ROCKS, you've heard of Wordle,
the online word game that has become wildly popular since late 2021.
You've probably seen people posting their Wordle games
as grids of little green, yellow, and black (or white) emojis on social media.
Wordle 797 4/6
⬛ ⬛ ⬛ ⬛ 🟨
🟨 ⬛ 🟩 ⬛ ⬛
⬛ ⬛ 🟩 🟨 ⬛
🟩 🟩 🟩 🟩 🟩
The problem that I want to address in this post is:
Given some GUESS=SCORE pairs for Wordle and a word list,
programmatically find all the words from the list
that are eligible as answers.
Let's look at this four-round game for Wordle 797:
Most regular expression engines make it easy to
match alternations (or disjunctions) with the | operator:
to match either foo or bar,
Few regex engines have any provisions for conjunctions,
and the syntax is often horrible.
Awk makes it easy to match /pat1/ && /pat2/ && /pat3/.
$ cat <<EOF | awk '/bar/ && /foo/'
> foo bar
> barfy food
In the case of a Unix pipeline,
the conjunction could also be expressed as a series of pipes:
... | grep pat1 | grep pat2 | grep pat3 | ....
The longest regex that I ever encountered
was an enormous alternation—a true horror that shouldn’t have …continue.
Python enumerations are useful for grouping related constants in a namespace.
You can add additional behaviors to an enum class,
but there isn’t an easy and obvious way
to add attributes to enum members.
CORRECT = 1
PRESENT = 2
ABSENT = 3
if self is self.CORRECT:
elif self is self.PRESENT:
Recently, I had to create a new Python wheel for PyTorch.
There is a cyclic dependency between PyTorch 2.0.1 and Triton 2.0.0:
Torch depends upon Triton, but Triton also depends on Torch.
Pip is okay with installing packages where there’s a cyclic dependency.
Bazel, however, does not handle cyclic dependencies between packages.
We use Bazel extensively at Stripe
and this cyclic dependency prevented us from using the latest version of Torch.
I spent a few days trying to build the PyTorch wheel from source.
It was a nightmare!
I ran out of disk space on the root partition on my EC2 devbox
trying to install system packages,
so I had to bring …continue.
I woke up on Saturday to read on Bram Moolenaar’s Facebook page
an announcement of his death.
I knew Bram online for nearly 30 years and
I was one of his relatively small number of Facebook friends,
but we never met in real life.
I knew that he had retired from Google Zurich to Tenerife,
but I hadn’t been aware that he had been ill.
Bram was known to the world for his signature creation,
the Vim text editor,
used by millions of developers on Linux, macOS, and Windows.
Vim stands for Vi IMproved,
but it outgrew the original vi long ago.
I was an active contributor to Vim in the 1990s:
I wrote a …continue.
I often enjoy cold brew coffee in summer.
I bought an Oxo Cold Brew Coffee Maker one winter
when it was on sale at Bed, Bath & Beyond.
Before that, I used a nut milk bag in a jar.
I like the Oxo and it gets high marks in many reviews,
such as HomeGrounds or Wirecutter.
It’s easy to use, easy to clean, and makes a good brew.
The only downside to making your own cold brew coffee
is that you must plan ahead.
You can make hot coffee in a few minutes,
but cold brew takes hours.
I have used this recipe for a number of years.
It makes a smooth, less acidic coffee.
TL;DR: use tar -I pigz or tar -I lbzip2
to compress large tar files much more quickly.
I investigated various ways of compressing a 7GiB tar file.
The built-in --gzip and --bzip2 compression methods in GNU tar
If you invoke an external compressor with --use-compress-program,
you can get some huge reductions in compression time,
with slightly worse compression ratios.
You can use pigz as a parallel replacement for gzip
and lbzip2 as a parallel version of bzip2.
Both of them will make heavy use of all the cores in your system,
greatly reducing the real time relative to the user time.
Single-threaded compression timing:
gzip is a lot faster than bzip2:
$ time tar --bzip2 -cf …continue.
In Part 1, we saw how to walk directory trees,
recursively using fs::read_dir
to construct an in-memory tree of FileNodes.
In Part 2, we’ll implement the rest of the core of the tree command:
printing the directory tree with Box Drawing characters.
Let’s take a look at some output from tree:
│ ├── wasi
│ │ ├── ffi.rs
│ │ ├── mod.rs ➊
│ │ └── net ➋
│ │ └── mod.rs
│ └── windows
│ ├── ffi.rs …continue.
I’ve been learning Rust lately.
I started by reading several books,
including Rust in Action,
Code Like a Pro in Rust,
and most of Programming Rust.
Now, I’m starting to actually write code.
I read the Command-Line Rust book last month,
which challenged readers to write
our own implementations of the tree command.
I decided to accept the challenge.
At its simplest, tree simply prints a directory tree,
using some of the Unicode Box Drawing characters
to show the hierarchical relationship,
as in the image at right.
I’ve split the code into two phases,
which will be covered in two blog posts.
- Walking the directory tree on disk to build an in-memory tree.
- Pretty-printing the in-memory tree.
While it’s certainly possible to print a …continue.
My display name on Twitter currently looks like @ɢᴇᴏʀɢᴇᴠʀᴇɪʟʟʏ@ᴛᴇᴄʜ.ʟɢʙᴛ,
an attempt to route around Twitter’s apparent censorship of Mastodon information.
I used the FSymbols Generators to produce several variants.
Many of these variants come from
Unicode Block “Mathematical Alphanumeric Symbols”.
There are a lot more things you can do with Unicode
than just upside-down text.