Submission c0a7d1ae...
/**
* This file is part of the 1st Solidity Gas Golfing Contest.
*
* This work is licensed under Creative Commons Attribution ShareAlike 3.0.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
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) {
uint program_length = clean(program);
uint8[] memory ram = new uint8[](1024);
bytes memory output = new bytes(1024);
uint ptr;
uint pidx;
uint iidx;
uint oidx;
(ptr, pidx, iidx, oidx) = brainfuck(
program, input, program_length, ram, output,
0, 0, 0, 0
);
bytes memory ret = new bytes(oidx);
for (uint i = 0; i < ret.length; i++) {
ret[i] = output[i];
}
return ret;
}
function clean(bytes program) internal pure returns(uint) {
uint i = 0;
uint j = 0;
byte token;
while (i < program.length) {
token = program[i];
if (token < 0x2b
|| token > 0x5d
|| (token > 0x2e && token < 0x3c)
|| (token > 0x3e && token < 0x5b)
|| token == 0x3d
|| token == 0x5c) {
} else {
program[j] = token;
j++;
}
i++;
}
return j;
}
function brainfuck(
bytes program, bytes input, uint program_length,
uint8[] memory ram, bytes memory output,
uint ptr, uint pidx, uint iidx, uint oidx
) internal pure returns(uint, uint, uint, uint) {
byte token;
uint stack;
while (pidx < program_length) {
token = program[pidx];
if (token < 0x30) {
if (token < 0x2d) {
if (token == 0x2b) {
ram[ptr] += 1;
} else {
ram[ptr] = uint8(input[iidx]);
iidx++;
}
} else {
if (token == 0x2d) {
ram[ptr] -= 1;
} else {
output[oidx] = byte(ram[ptr]);
oidx++;
}
}
} else {
if (token < 0x40) {
if (token == 0x3c) {
ptr -= 1;
} else {
ptr += 1;
}
} else {
if (token == 0x5b) {
pidx++;
stack = pidx;
while (ram[ptr] > 0) {
(ptr, pidx, iidx, oidx) =
brainfuck(
program, input, program_length,
ram, output,
ptr, stack, iidx, oidx);
}
} else {
return (ptr, pidx, iidx, oidx);
}
}
}
pidx++;
}
return (ptr, pidx, iidx, oidx);
}
}