I like the explanation in the case study in Sedgewick's Algorithms [1].
Compare its simplicity to connected-components [2], another elegant algorithm but with a perhaps a bit more involved implementation.
You wanna flex your muscles with this data structure, this is a fun Project Euler problem: https://projecteuler.net/problem=186
After hearing the word "memoization" go through my head (part of "Hacking the Coding Interview." which I recommend at least for the wealth of example questions for practice), I basically walked my way through making a disjoint-set data structure using the words as keys and the set number as values. I'm prettyy sure that making that up on the spot is what got me the job.
Could you expand on this? This is something I've just started reading about. I'd be interested in good resources to use to get started. At the moment I've just started reading TAPL.
In fact, that might be a good starting point - first implement something with the above 2 types, and where every variable and function parameter has a type annotation. From then, you could (1) add more complex types, like function types, tuples or lists, (2) implement type propagation where each variable has the type of the value it's assigned (like auto in modern C++), and then (3) go full HM type inference.
TAPL definitely sounds like a good resource. The next book might be this one: Advanced Topics in Types and Programming Languages https://www.cis.upenn.edu/~bcpierce/attapl/frontmatter.pdf
Another good resource could be Programming Language Zoo http://plzoo.andrej.com/ that covers different evaluation techniques as well.
In general, I've been "involved" in PL design for quite some time, so I've no idea where I've gained all the knowledge I have... but in recent years, there have been quite a few modern resources, even a few on HN IIRC!
e.g.
http://craftinginterpreters.com/
http://createyourproglang.com/
(disclaimer: I haven't read them)