lambda s:"".join([3*c,p:="++[->>+<]>[-<]<","[-]-.",p*255,c][ord(c)%31%11%7]for c in s)
Try it online!
Basically the idea is that we only use every third cell to store the memory that the input program uses. The other cells are simply zero. This gives space to implement the addition code. The addition code is as follows:
++[->>+<]>[-<]<
Let's see how this works. There are two possibilities, either the cell has value of 255
or it has a lower value.
If the cell has value 255
then, after the first additions the value of the cell is now 0
(since it's mod 257). This means that the next loop won't execute at all. So we skip the first loop and move right. This square is 0, so we won't execute the next loop and we finally move left, back to the starting square, which has now value 0, meaning that we succeeded in doing 255->0
.
If the cell has some other value x
, the first two additions will make the value of the cell x+2
which is not zero. This means that the next loop will execute. We decrement this cell (value now is x+1
) and move twice to the right. We increment that cell (now has value 1
) and move left. The cell we are on right now has also value 0, so the loop stops. We then move right, to find our cell which has value 1. We decrement it to leave it in a clean state and move left. Again, this cell has value 0, so the loop stops. Finally we move left once to get back to where we started, with the cell having value x+1
Decrementation is just addition 255 times. [
, .
and ]
don't need to be changed. We triplicate >
and <
since every third cell stores the "original" program values. Actually, we also triplicate [
and ]
, but this doesn't have any effect on the execution of the program. For ,
we just zero the cell with [-]
and then decrement once more to get value 256 and then use the dot.
-.
translate to--.
or-.
? \$\endgroup\$