@Override
    public String solve() {

        final long[][][] cache = new long[MAX][16][1 << 3];
        
        for (int f = 0; f < 0x10; ++f) cache[0][f][mask(f)] = cache[0][f][0] = 1;

        long sum = 0;
        
        for (int n = 1; n < MAX; ++n) { // length
            for (int f = 0; f < 0x10; ++f) { // first digit
                for (int d0 = 0; d0 < (1 << 3); ++d0) { // digits to be contained
                    if (bitCount(d0) <= n + 1) {
                        
                        final int d1 = d0 & ~(mask(f));
                        for (int s = 0; s < 0x10; ++s) {
                            cache[n][f][d0] += cache[n - 1][s][d1];
                        }
                    }        
                }
                if (f > 0) sum += cache[n][f][(1 << 3) - 1];
            }
        }

        return String.format("%X", sum);
    }