Butterbrain
Designed by | {{{author}}} |
---|---|
Appeared in | {{{year}}} |
Dimensions | one-dimensional |
Computational class | Unknown |
Reference implementation | (probably) [1] |
Influenced by | brainfuck |
File extension(s) | {{{files}}} |
Butterbrain is an esolang heavily inspired by brainfuck. Butterbrain and brainfuck both share the idea of a strip of memory cells that can be looked at through a "head" which is pointing to one cell. While brainfuck uses relative positioning, such as >
to move the head to the right, Butterbrain uses absolute positioning.
Evaluation
Butterbrain code is made of special characters and expressions. Characters not matching the instruction set are ignored. Comments are not supported, though it might be possible to improvise one.
Special Characters
Special characters perform I/O, loops, and movement. Most special characters depend on the value the head is pointing at, so that value will from now on be referred as #. The special characters are the following:
Symbol | Use |
---|---|
s |
sets # to input |
g |
sets the head's position to input |
p |
prints # |
i |
sets # to input from stdin |
n |
prints a newline to stdout |
a |
prints # as Unicode |
~ |
prints the values from the 0th cell up to #'s cell - used for improvised debugging |
[ |
jumps to the next balanced ] if # is 0
|
] |
jumps back to the previous balanced [ if # is not 0
|
{ |
jumps to the next balanced } if # is not 0
|
} |
jumps back to the previous balanced { if # is 0
|
The bread and butter of this language is s
and g
. These two special characters take input by evaluating the expression to the right of them.
Expressions
Using expressions can be thought of as nesting functions. Each expression is a single character that takes the value on the right as input, performs a simple operation, then returns another value. These concatenated chains of expressions start at the right, modify the input as it moves left, and has their final value used by s
or g
at the leftmost. They are as follows:
Expression | Use |
---|---|
v |
returns the head's position |
base 10 whole number | returns its value |
Expression | Use |
---|---|
@ |
returns the value of cell input |
) |
returns the head's position + input |
( |
returns the head's position - input |
+ |
returns # + input |
- |
returns # - input |
* |
returns # * input |
/ |
returns # / input, rounded down |
% |
returns # bitwise modulo input |
& |
returns # bitwise and with input |
∣ |
returns # bitwise or with input |
^ |
returns # bitwise xor with input |
= |
returns 1 if # = input, 0 otherwise |
> |
returns 1 if # > input, 0 otherwise |
< |
returns 1 if # < input, 0 otherwise |
! |
returns 1 if input is 0, 0 otherwise |
As an example, this expression takes the number 66
, adds # to it, multiplies it by #, checks if it equals #, then sets # to that check.
s=*+66
If # was 2, the expression would be evaluated as follows:
pseudocode: s = (2 == (2 * (2 + (66)))) s=*+66 s=*68 s=136 s0
Examples
Hello, world!
This program repeatedly sets a cell to the ASCII values of Hello, world!\n
, printing the character via a
then a newline:
s72 a s101 a s108 a s108 a s111 a s44 a s32 a s119 a s111 a s114 a s108 a s100 a s33 a n
Truth-machine
A truth machine prints 0
if the input is 0 or an infinite amount of 1
s otherwise. Comments are not supported and should be erased before running.
i set cell to user input [s1p] while cell is 1, set the cell to 1 then print it p only reached if cell is 0, print input
Nim AI
Nim is a 2-player game played with piles of objects. Players take turns taking any number of objects from any single pile until there are no objects left. The objective is to either take, or force the opponent to take, the last object, depending on the game. This instance of Nim is played with the objective to take the last object with 3 piles of 3, 5, and 7 objects.
The first line of code sets up cells 0 to 7 to for the game. Cells 0, 1, and 2 cells represent the 3 piles. Cell 3 is reserved for printing the board and is set later. Cell 4 represents whose turn it is and is set to user input, so the player can decide if the AI can go first. Cells 5 and 6 represent user input, where 5 is which pile to take from and 6 is how much to take. They are set to 0 and 1 for by default. Cell 7 is 1 as long as the game is not over.
As before, comments should be erased before the interpreter runs.
s3 g1s5 g2s7 g4i g5s0 g6s1 g7s1 [ g3s3 prints out the board [ g(@v p g3s-1 ] n g4 gets user input if it is their turn { g5i g6i } g4s!@v gets the ideal move the AI should make via XOR or a nimsum { g8s0 g9s1 [ g9 s@@8 g10s@8s+1s%3s@@v g11s@8s+2s%3s@@v g10s^@)1 g9s-@10 g12s@9s<1 g13s@@8 s<@9 s|@12 g12 s!@13 { g15s1 g5s@8 g6s@9 } g8s+1 g14 s@8s<3 ] g15 s!@v if no ideal move exists, take 1 from the first non-zero pile { g5s0 g6s1 [ s@@5 s!@v{ g5s+1 } g6 ] g6s1 } } update board and check if the game is over g6 g@(1 s-@6 g7 s@0s+@1s+@2 ] g4 print winner s!@v p
Minimized:
s3g1s5g2s7g4ig5s0g6s1g7s1[g3s3[g(@vpg3s-1]ng4{g5ig6i}g4s!@v{g8s0g9s1[g9s@@8g10s@8s+1s%3 s@@vg11s@8s+2s%3s@@vg10s^@)1g9s-@10g12s@9s<1g13s@@8s<@9s|@12g12s!@13{g15s1g5s@8g6s@9}g8 s+1g14s@8s<3]g15s!@v{g5s0g6s1[s@@5s!@v{g5s+1}g6]g6s1}}g6g@(1s-@6g7s@0s+@1s+@2]g4s!@vp
Example terminal output with comments:
input not actual output but console awaiting input 1 who goes first - player 0 == computer, player 1 == player 357 board input 0 inputted 0th pile input 1 inputted taking 1 257 board after taking 1 from 0th pile 157 AI also taking 1 from 0th pile input 2 input 3 154 taking 3 from 2nd pile 151 AI also taking 3 from 2nd pile input 0 input 1 051 taking 1 from 0th pile 011 AI taking 4 from 1st pile input 1 input 1 001 taking 1 from 1st pile 0 computer wins as it took the last of the pile
Binary Search Tree
This code sets up the memory for a binary search tree, occupies that memory with an example tree, then searches through the tree for a given value. The node is made up of 4 cells: data is in the 1st cell, a pointer to the parent node in the next cell, and pointers to the left and right branch nodes in the last 2 cells.
g)1 s1 [g)1s(1s+4s/8s-1s*4s+1g)1svs*2s-1g)1svs*2s+1g)1svs<32] sets up memory g1 s10 g@)2 s5 g@)2 s2 g@)1g@)3 s7 g@)1g@)1g@)3 s15 g@)2 s12 g@)1g@)3 s20 g1000i g)1s1 [ g0 s@@1001 pn s=@1000 {s@1000pns1} s!@v { s@@1001 s<@1000 {g1001s+1} g1001 s+2 s@@v g0 s@1001 s<32 } ]