Submission 5ac2bda8...

ChallengeBrainFuck interpreter
Submitter0x9e0ad99de20a444...
Submitted at2018-34-16
Gas used4013200
pragma solidity 0.4.24;

contract BrainFuck {
    /**
     * @dev Executes a BrainFuck program, as described at https://en.wikipedia.org/wiki/Brainfuck.
     *
     * Memory cells, input, and output values are all expected to be 8 bit
     * integers. Incrementing past 255 should overflow to 0, and decrementing
     * below 0 should overflow to 255.
     *
     * Programs and input streams may be of any length. The memory tape starts
     * at cell 0, and will never be moved below 0 or above 1023. No program will
     * output more than 1024 values.
     *
     * @param program The BrainFuck program.
     * @param input The program's input stream.
     * @return The program's output stream. Should be exactly the length of the
     *          number of outputs produced by the program.
     */
    function execute(bytes program, bytes input) public pure returns(bytes) {
        //v1.3
        uint ipp = 0;
        uint opp = 0;
        uint dp = 0;
        uint depth;
        uint programLen = program.length;
        uint counterPlus;
        bytes memory mem = new bytes(1024);
        bytes memory output = new bytes(1024);

        ///Find Index Position Loops
        uint[] memory indexPos = new uint[](6);
        for(uint ip = 0; ip < programLen; ip++){
            instruction = program[ip];
            if(instruction == 0x5b || instruction == 0x5d ){
                indexPos[counterPlus] = ip;
                counterPlus++;
                if(instruction == 0x5b)
                    depth++;
           }
        }
        for(ip = 0; ip < programLen; ip++) {
            byte instruction = program[ip];
            if((instruction&0x88 != 0x08)){
                continue;
            }else if(instruction == "+") {
                counterPlus = 1;
                while(program[ip + counterPlus] == "+"){
                    counterPlus++;
                }
                mem[dp] = bytes1(uint8(mem[dp]) + counterPlus);
                ip = ip + (counterPlus-1);
            } else if(instruction == "-") {
                counterPlus = 1;
                while(program[ip + counterPlus] == "-"){
                    counterPlus++;
                }
                mem[dp] = bytes1(uint8(mem[dp]) - counterPlus);
                ip = ip + (counterPlus-1);
            } else if(instruction == ">") {
                counterPlus = 1;
                while(program[ip + counterPlus] == ">"){
                    counterPlus++;
                }
                dp = dp + counterPlus;
                ip = ip + (counterPlus-1);
            } else if(instruction == "<") {
                counterPlus = 1;
                while(program[ip + counterPlus] == "<"){
                    counterPlus++;
                }
                dp = dp - counterPlus;
                ip = ip + (counterPlus-1);
            } else if(instruction == ".") {
                output[opp++] = mem[dp];
            } else if(instruction == ",") {
                mem[dp] = input[ipp++];
            } else if(instruction == "[") {
                if(mem[dp] == 0) {
                    if(depth > 1){
                        if(ip == indexPos[0])
                            ip = indexPos[5];
                        else if (ip == indexPos[1])
                            ip = indexPos[2];
                        else
                            ip = indexPos[4];
                    }else
                        ip = indexPos[1];
                }
            } else if(instruction == "]") {
                if(mem[dp] != 0) {
                    if(depth > 1){
                        if(ip == indexPos[2])
                            ip = indexPos[1];
                        else if (ip == indexPos[4])
                            ip = indexPos[3];
                        else
                            ip = indexPos[0];
                    }else
                        ip = indexPos[0];
                }
            }
        }

        bytes memory ret = new bytes(opp);
        for(uint i = 0; i < opp; i++) {
            ret[i] = output[i];
        }
        return ret;
    }
}