    import std.stdio, std.ascii, std.algorithm, std.array, std.range;

    alias Block = char[2];

    bool canMakeWord(immutable Block[] blocks, in string word) pure nothrow
    in {
        assert(blocks.all!(w => w[].all!isAlpha));
        assert(word.all!isAlpha);
    } body {
        bool inner(size_t[] indexes, in string w) pure nothrow {
            if (w.empty)
                return true;

            immutable c = w[0].toUpper;
            foreach (ref idx; indexes) {
                if (blocks[idx][0].toUpper != c &&
                    blocks[idx][1].toUpper != c)
                    continue;
                indexes[0].swap(idx);
                if (inner(indexes[1 .. $], w[1 .. $]))
                    return true;
                indexes[0].swap(idx);
            }

            return false;
        }

        return inner(blocks.length.iota.array, word);
    }

    void main() {
        enum Block[] blocks = "BO XK DQ CP NA GT RE TG QD FS
                               JW HU VI AN OB ER FS LY PC ZM".split;

        foreach (w; "" ~ "A BARK BoOK TrEAT COmMoN SQUAD conFUsE".split)
            writefln(`"%s" %s`, w, blocks.canMakeWord(w));

        // Extra test.
        immutable Block[] blocks2 = ["AB", "AB", "AC", "AC"];
        immutable word = "abba";
        writefln(`"%s" %s`, word, blocks2.canMakeWord(word));
    }