RU
RU is a multithreaded two dimensional esoteric programming language. It was invented by Adrian Toncean in 2010 and was first featured in the programming game called Robot Unlock!!!.
Language overview
Like PATH, RU borrows elements from both Befunge and Brainfuck.
The language is caracterized by one or two Executors that execute instructions found on the playfield, a 4 cell circular "tape" and 2 pointers for this tape. The two pointers are dark green and light green and through them dark green and light green instructions are performed.
For simplicity, the dark green pointer will be dubbed dark pointer and the light green pointer as the light pointer and the four memory locations will be dubbed First, Second, Third and Fourth.
Because the tape is so limited and the values stored in these cell are bounded, RU is not Turing-complete. However, one can still compute a large number of functions like primality testing, the n-th fibonacci number, the power function, square root, discrete logarithm.
Execution starts through the creation of an Executor in the upper left corner of the playfield and halts when when no Executor is left on the table.
Instructions
There are 2 types of instructions based on whether thay operate on memory or not.
The blue instructions are considered neutral because they do not change the state of the memory in any way, nor do they read from it or change the pointers' positions.
The dark (light) instructions will either read or write where the dark (light) pointer is at.
There are no dedicated instructions for input or output. The input is considered the initial memory state and the output is the final memory state.
The neutral instructions are as follows:
Instruction | Action |
---|---|
Kills executors | |
No Operation | |
F | Forks the Executor if there is only one |
U | Unfork - terminates the other Executor |
^ | Sets the Executor to go up |
< | Sets the Executor to go left |
v | Sets the Executor to go down |
> | Sets the Executor to go right |
# | Makes the Executor jump one instruction |
The light pointer and dark pointer have the light and dark respectively pointers associated.
The dark green instructions are as follows:
Instruction | Action |
---|---|
++ | Increments the value indicated by the dark pointer by 1 |
-- | Decrements the value indicated by the dark pointer by 1 |
>> | Moves the dark pointer one position to the left |
<< | Moves the dark pointer one position to the right |
^ | Sets the Executor to go up if the value indicated by the dark pointer is greater to the one indicated by the light pointer |
< | Sets the Executor to go left if the value indicated by the dark pointer is greater to the one indicated by the light pointer |
v | Sets the Executor to go down if the value indicated by the dark pointer is greater to the one indicated by the light pointer |
> | Sets the Executor to go right if the value indicated by the dark pointer is greater to the one indicated by the light pointer |
# | Makes the Executor jump one instruction if the value indicated by the dark pointer is greater to the one indicated by the light pointer |
+- | Multiplies the value indicated by the dark pointer with -1 |
+ | Performs and additions between the values indicated by both pointers and stores the result in the cell indicated by the dark pointer |
- | Subtracts the value indicated by the light pointer from the value indicated by the dark pointer and stores the result in the cell indicated by the dark pointer |
* | Multiplies the values indicated by both pointers and stores the result in the cell indicated by the dark pointer |
/ | Divides the value indicated by the dark pointer by the value indicated by the light pointer and stores the result in the cell indicated by the dark pointer. The operation has no effect if the divisor is 0 to prevent a division by 0. |
The light green instructions are as follows:
Instruction | Action |
---|---|
++ | Increments the value indicated by the light pointer by 1 |
-- | Decrements the value indicated by the light pointer by 1 |
>> | Moves the light pointer one position to the left |
<< | Moves the light pointer one position to the right |
^ | Sets the Executor to go up if the value indicated by the light pointer is greater to the one indicated by the dark pointer |
< | Sets the Executor to go left if the value indicated by the light pointer is greater to the one indicated by the dark pointer |
v | Sets the Executor to go down if the value indicated by the light pointer is greater to the one indicated by the dark pointer |
> | Sets the Executor to go right if the value indicated by the light pointer is greater to the one indicated by the dark pointer |
# | Makes the Executor jump one instruction if the value indicated by the light pointer is greater to the one indicated by the dark pointer |
+- | Multiplies the value indicated by the light pointer with -1 |
+ | Performs and additions between the values indicated by both pointers and stores the result in the cell indicated by the light pointer |
- | Subtracts the value indicated by the dark pointer from the value indicated by the light pointer and stores the result in the cell indicated by the light pointer |
* | Multiplies the values indicated by both pointers and stores the result in the cell indicated by the light pointer |
/ | Divides the value indicated by the light pointer by the value indicated by the dark pointer and stores the result in the cell indicated by the light pointer. The operation has no effect if the divisor is 0 to prevent a division by 0. |
Difference between the Robot Unlock language and RU
The # instruction performs differently in the two languages. In Robot Unlock it would just ignore the next instruction to be executed whereas in RU it performs a jump. This is very useful for transporting executors over long distances.
The cycle count is incremented differently. In Robot Unlock the counter is incremented after the control is passed to all executors, while in RU the counter is incremented after each Executor's move.
The playfield in Robot Unlock varied in size and shape to make it more challenging, while in the current version of RU the playfield is of a fixed 11x11 size.
Extensions
There is an extension to the RU language. It adds instructions for synchronizing Executors, changing the content of playfield cells and controlling other Executors. The instructions which allow writing and erasing on the playfield confers a reflexive side to the language. Theoretically with the ability to store data on the playfield one can compute functions that were not possible to implement due to the very limited number of registers.
These instructions are the following:
Instruction | Action |
---|---|
() | Puts the Executor on wait until all Executors are on wait |
!x | Tells the other Executors to erase the content of the cell at their position |
!p | Puts the Executor into seeking mode. Once in seeking mode it will pass the first encountered instruction to the other Executors which in their turn will place it on the playfield at their respective positions. |
!e | Puts the Executor into seeking mode. Once in seeking mode it will pass the first encountered instruction to the other Executors which then execute the respective instruction. |
Examples
In-place swapping
This is of particular interest since the memory space is very limited.
>> | + | +- | + | - | ||||||||
Computing the remainder of a division
The divident is given in First and the divisor in Second. The remainder is outputted in First.
>> | >> | + | >> | / | * | << | << | - | ||||
Greatest common divisor
The input is given in First and Second and the output is written in both First and Second.
RUv2""""""""""",""""""""""("%""""""""05&"""""""">C&""""""""%"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
>> | > | v | v | ^ | ||||||||
- | - | |||||||||||
^ | < | < | ||||||||||
Computing the n-th Fibonacci number
The input is given in First and the output in Third.
RUv2"'(""%""""",-('("""""":;-":"""""":;:"5""""""*8:B:""""""'&4,4+"""""""""",""""""";5,'"""""""4-5@""""""""-":"""""""'&'&"""""
>> | >> | >> | ++ | v | ||||||||
v | << | << | << | ++ | < | |||||||
> | > | << | >> | >> | + | << | + | v | ||||
v | + | >> | - | << | << | < | ||||||
> | >> | - | >> | + | >> | - | v | |||||
^ | -- | >> | v | # | >> | < | ||||||