[ create a new paste ] login | about

Link: http://codepad.org/gtWDdRoJ    [ raw code | fork ]

D, pasted on Mar 19:
import std.stdio: writeln;
import core.bitop: bsr;
import std.string: countchars;


/// Returns the number of the top bit that changed from self - 1.
uint topChangedBit(uint x) pure nothrow {
    return bsr(x ^ (x - 1));
}


/// Creates XOR masks for the folds, generates the sequence directly.
uint[] fold(in uint h, in uint v, in string folds) pure /*nothrow*/ {
    immutable uint hBits = folds.countchars("LR"); // Not nothrow.
    immutable uint vBits = folds.countchars("TB");

    // Pre-condition.
    assert(hBits + vBits == folds.length, "Illegal folds");
    assert((1 << hBits) == h && (1 << vBits) == v);

    enum uint one = 1;
    uint hMask = (one << hBits) - 1;
    uint vMask = (one << vBits) - 1;

    uint[] masks;
    uint hFinal, vFinal;

    foreach (immutable char fold; folds) {
        if (fold == 'L' || fold == 'R') {
            masks ~= hMask;
            hMask /= 2;
            hFinal = hFinal * 2 + (fold == 'L');
        } else {
            masks ~= vMask << hBits;
            vMask /= 2;
            vFinal = vFinal * 2 + (fold == 'T');
        }
    }

    uint n = (vFinal << hBits | hFinal) ^ masks[$ - 1];
    auto result = [n + 1];

    while (true) {
        immutable i = result.length.topChangedBit;
        if (i >= masks.length)
            return result;
        n ^= masks[i];
        result ~= n + 1;
    }
}


void main() {
    fold(16, 16, "TLBLRRTB").writeln;
}


Create a new paste based on this one


Comments: