Submission a5b6be6e...

ChallengeBrainFuck interpreter
Submitter0x888888417655103...
Submitted at2018-24-29
Gas used1954870
pragma solidity 0.4.24;

contract BrainFuck {

    function execute(
        bytes program,
        bytes input
    ) public pure returns(bytes output) {
        uint progLen = remove_invalid(program, program.length);
        uint8[] memory ram = new uint8[](1024);
        uint outIdx = brainfuck(program, input, progLen, ram);
        output = new bytes(outIdx-progLen);
        for (uint i = 0; i < output.length; i++) {
            output[i] = byte(ram[progLen+i]);
        }
    }

    function remove_invalid(
        bytes program,
        uint progLenFull
    ) private pure returns(uint progLen) {
        byte token;
        bool[] memory filter = new bool[](256);
        filter[43] = true; filter[45] = true;
        filter[44] = true; filter[46] = true;
        filter[60] = true; filter[62] = true;
        filter[91] = true; filter[93] = true;
        for (uint i = 0; i < progLenFull; i++) {
            token = program[i];
            if (filter[uint(token)]) {
                program[progLen++] = token;
            }
        }
    }

    function brainfuck(
        bytes program,
        bytes input,
        uint progLen,
        uint8[] ram
    ) private pure returns(uint outIdx) {
        outIdx = progLen;
        uint inIdx = 0;
        uint progIdx = 0;
        byte token;
        uint[] memory stack = new uint[] (16);
        uint stackIdx = 0;
        uint ramIdx = 0;
        while (progIdx < progLen) {
            token = program[progIdx++];
            if (token < 0x30) {
                if (token < 0x2d) {
                    if (token == 0x2b) {
                        ram[ramIdx] += 1;
                        continue;
                    }
                    ram[ramIdx] = uint8(input[inIdx++]);
                    continue;
                }
                if (token == 0x2d) {
                    ram[ramIdx] -= 1;
                    continue;
                }
                ram[outIdx++] = ram[ramIdx];
                continue;
            }
            if (token < 0x40) {
                if (token == 0x3c) {
                    ramIdx -= 1;
                    continue;
                }
                ramIdx += 1;
                continue;
            }
            if (token == 0x5b) {
                if (ram[ramIdx] == 0) {
                    while (program[progIdx++] != 0x5d) {}
                    continue;
                }
                stack[stackIdx++] = progIdx - 1;
                continue;
            }
            if (ram[ramIdx] == 0) {
                stackIdx -= 1;
                continue;
            }
            progIdx = stack[stackIdx-1] + 1;
        }
    }
}