Recently I encountered a question about esoteric programming language. There are the tools of that language.
> - increases the data pointer (so it points to the next cell in the array);
< - decreases the data pointer;
+ - increments the value in the current memory cell (i.e. one pointed by data pointer);
- - decrements the value in the current memory cell;
. - takes the value of current memory cell, converts it to character and prints to output;
, - takes one character from input and puts its ASCII code to the current memory cell.
[ - peeks at current cell, if the value here is non-zero, then simply proceeds to the next instruction, but if the value is 0, then searches forward for corresponding ] and sets code pointer immediately after this (i.e. skips the block within brackets);
] - moves code pointer back, to corresponding [.
: - takes the value of current memory cell and prints to output as a decimal integer;
; - takes next decimal integer (probably, consisting of several digits) from input and puts it to the current cell.
So I have to make a program in this language which input 2 numbers a and b and put them in cell0 and cell1, and output the sum of this two numbers. There is an additional requirement( which I got trouble with ) is after the process there should be 3 cells, cell0 holds a, cell1 holds b, cell 2 holds a+b.
Here is my analysis: I thought that find the way to put the sum in cell3 and print it is easy, just do ;>;<[->>+]>[->+]>:
. However in this way after process, the cell0 and cell1 will all hold 0 rather than a and b. So I was trying to find a way to use the tools above to achieve that, I realized given the tool, it's like a battery, I can only move the energy from one battery to another but I can never copy the energy from one to another. If so, I can never get the sum while I trying to preserve the cell0 and cell1.
Thanks to the information @user3386109 comment under my question. I noticed there are ways to cheat "energy balance". We can increment 2 cells or more in the loop. So I use 5 cells and transfer the a and b in first cell and 2nd cell into 4th and 5th while do the sum operation. So my algorithm will be like this:
;>; input two numbers a and b
<[->>+>+] if the first cell is not zero then we keep decrementing it and incrementing the number in 3rd cell and 4th cell until it's zero.
>[->+>>+] if the second cell is not zero then we keep decrementing it and incrementing the number in 3rd cell and 5th cell until it's zero.
then we transfer back value a and b from 4th and 5th cell to 1st and 2nd cell
>>[-<<<+]>[-<<<+]
<<: go back 3rd cell and print out.
So finally my code is:
;>;<[->>+>+]>[->+>>+]>>[-<<<+]>[-<<<+]<<:
but it's not right, I checked a few times and couldn't find the bug. Anyone help me out? Thx!!!
The language you're working with is essentially Brainfuck (plus the ;
and :
operators, for convenience, but they don't really affect how the language works).
As user3386109 pointed out in the comments, the trick is to copy the input while adding it to the result. Your solution for that is almost correct, but you seem to have forgotten to move the memory pointer back within each loop. Your loop simply moves further right on each iteration. Unless you're doing something fun where you're intending to move along the tape during a loop, you'll usually want the <
and >
to be balanced in each loop.
Here is one possible solution to your problem:
; Read a into cell 0
[->+>>+<<<] Add a to cells 1 and 3
; Read b into cell 0
[->>+>+<<<] Add b to cells 2 and 3
>>>: Print cell 3 (with cells 1 and 2 holding copies of a and b)
You can (sort of) test this here. It's a standard Brainfuck interpreter, so it doesn't support ;
and :
, but if we add the character !
(33) and A
(65), we get b
(98).
For more information about how to solve problems in Brainfuck, I recommend the esolangs article I linked to at the top, as well as the many links you can find at the bottom of that.