Recover a secret string from random triplets
I have mainly two things I'd like to look at:

I'm not a big of fan of the constant deconstructing and recreating of Sets in the loop, especially since this most likely has negative impact on the performance. Unfortunately because there is not direct way to add multiple values to a Set there is no functional "one line" solution. My function to do this would look like this:

const addToAfter = (key, values) =&gt; {
    const set = after[key] || (after[key] = new Set());
    values.forEach(a =&gt; set.add(a));
};


which changes the loop to 

for (let triplet of triplets) {
    addToAfter(triplet[0], triplet.slice(1));
    addToAfter(triplet[1], [triplet[2]]);
    addToAfter(triplet[2], []);
}


This leads to my second point: the obvious code repetition. I don't think there is a reason not to use another loop here, which also has the "advantage", that you don't need to limit yourself to "triplets", but support arrays of any length:

for (let triplet of triplets) {
    for (let i = 0, len = triplet.length; i &lt; len; i++) {
        addToAfter(triplet[i], triplet.slice(i + 1));  
    }
}


If performance is important, I'd even consider getting rid of the .slice call and replace it with a loop, that adds the characters directly to the Set.

In general: I'm avoiding the "modern" functional way, because it (at least in this case) leads to slightly cryptic syntax (and thus unread code) and a lot of (slow) memory reallocation and data copying.