# Gravity simulator

### Statement

You are given a still of a series of balls falling in a 2D grid. This grid is surrounded by immutable and unbreakable walls so all the action in contained within them. Your task is to determine what will the state of the scenario be after gravity does all it's work.

### Elements inside grid

• - Floor, doesn't alter the direction of falling balls.
• \ Right slide, alters the path of the ball one (1) position right.
• / Left slide, alters the path of the ball one (1) position left.
• o A ball.

### Rules

• Balls fall.
• Floors, and slides don't fall.
• If the ball hits a slide that would make it go through a wall (\#or#/), or cross through a floor the slide will act as a floor.
• When a ball hits another ball the will become one ball, but increase their power to the sum of both balls.
• New balls (joined) will continue to behave as usual.
• When a ball can't move anymore, it's replaced by its power.
• The power of a ball will always be at most 9.

### Input

The grid will be given in a string variable with whatever name is shortest in your language of choice. By default we will use a as the input. A sample of an input, exactly as received:

##########\n# \      #\n#o       #\n#  - -\o #\n#/-    \ #\n#  \oo-/\#\n#-/ \   /#\n#   \ \  #\n#       /#\n##########


For random grids generated use https://repl.it/B1j3/2. Use my generated page instead (no ads, no crap, just the input and the output)

Note line breaks are \n. Printing the input to screen (not required for the challenge) would show things like this. Although I've put four puzzles alongside to safe space.

##########  ##########  ##########  ##########
# \      #  # o    -/#  #       o#  #-o /    #
#o       #  #    \   #  # o     -#  #-- \ /\ #
#  - -\o #  #-  \    #  #    - \o#  # - -- o-#
#/-    \ #  #        #  #o /\    #  #/ \     #
#  \oo-/\#  #o  -o-  #  # /    -o#  #/ /o oo/#
#-/ \   /#  #   -/-  #  # -  o  -#  #o/      #
#   \ \  #  #    \\  #  #   \o  /#  #o-o    o#
#       /#  # \o\  /\#  #     \o #  # -\o o /#
##########  ##########  ##########  ##########


### Output

The same grid, printed to screen with the final result of ball power. A valid answer would be one (1) of the following puzzles, each one corresponds to the input at the same position, of course if the input is different you should adjust the output. Not limit it to those four!

##########  ##########  ##########  ##########
# \      #  #      -/#  #       1#  #-1 /    #
#        #  #    \   #  #       -#  #-- \ /\ #
#1 - -\  #  #-  \    #  #    - \ #  # - --  -#
#/-    \1#  #        #  #  /\    #  #/ \     #
#  \  -/\#  #   -1-  #  # /    -2#  #/ /    /#
#-/ \   /#  #   -/-  #  # -     -#  # /      #
#   \ \  #  #    \\  #  #   \   /#  # -      #
#    2  /#  #1\2\  /\#  #2   2\1 #  #2-\3 23/#
##########  ##########  ##########  ##########


### Score

Languages will compete against themselves so feel free to use nongolf languages. To validate a solution I must be able to test it somewhere to see it works!.

Score is number of bytes. In the event of a tie, the first answer to reach the tied score wins.

### Warnings

• If unsure of how a ball should react, ask me and I'll clarify, I've been as clear as I could but I'm sure there are cases that are confusing.
• Slides are only ridden if you can exit them, think about it like a real slide. There's a guy at the top that doesn't let you through the ball unless it will exit through the other side.

### Clarifying examples of ball movement

######                       ######
#-o- #    BALL WOULD GO RD   #- - #
# \  #                       # \o #
######                       ######

######                       ######
#-o- #     BALL WOULD STAY   #-o- #
# \\ #                       # \\ #
######                       ######

######                       ######
#  -o#     BALL WOULD STAY   #  -o#
#   \#                       #   \#
######                       ######

######                       ######
#  o #     BALL WOULD STAY   #  o #
#  \/#                       #  \/#
######                       ######

######                       ######
#-o- #    BALL WOULD GO LD   #- - #
# /\ #                       #o/\ #
######                       ######


### How can I test if my answer is valid?

I've set up a simple page in one of my sites that will give you a random puzzle, and its answer. Take the input and check it against the output. My solution, without worrying too much about golfing is 389b 355b in python (generator, and page also python)

var QUESTION_ID=64359,OVERRIDE_USER=8478;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

• I'm reminded of Marbelous. – Arcturus Nov 20 '15 at 2:08
• Bonus points if anybody answers in Marbelous. – user45941 Nov 20 '15 at 2:09
• Borderline dupe of A Mere Bagatelle and Not Your Routine Bean Machine – Peter Taylor Nov 20 '15 at 8:20
• sounds like potentially an ascii-art pinball game – Khaled.K Dec 9 '15 at 22:28
• @JuanCortés why don't you use the fancy leader board code so you don't have to update the rankings yourself? – rgajrawala Jan 4 '16 at 16:56

# JavaScript (ES6), 157 196

Edit char by char instead of row by row, much better result

g=>(s=~g.search
,g=[...g]).map((c,i)=>c<' '?0:g[[0,1,-1].map(d=>!d|'\\ /'[d+1]==g[d+=i]&&+g[d+=s]?g[v+=+g[d],d+v-v]=' ':0,v=c>'a'?1:+c),i]=v?v:c)&&g.join


Note: does not handle ball values > 9. But it could, with a 18 bytes cost. See basic code below.

TEST snippet (better full page)

F=g=>(s=~g.search
,g=[...g]).map((c,i)=>c<' '?0:g[[0,1,-1].map(d=>!d|'\\ /'[d+1]==g[d+=i]&&+g[d+=s]?g[v+=+g[d],d+v-v]=' ':0,v=c=='o'?1:+c),i]=v?v:c)&&g.join

// Basic code, starting point before golfing
B=g=>{
s = ~g.search('\n');
(g=[...g]).map((c,i)=>{
v = c == 'o' ? 1 : +c
if (c>=' ' // skip newlines
&& !isNaN(v)) // digit or space
{
if (w=+g[i+s]) v += w, g[i+s]=' '
if (g[i-1]=='\\' && (w=+g[i+s-1])) v += w, g[i+s-1]=' '
if (g[i+1]=='/' && (w=+g[i+s+1])) v += w, g[i+s+1]=' '
if (v) g[i] = v
}
})
// return g.join
// To handle values > 9 ...
return g.map(v=>+v?v%10:v).join
}

function test() {
O.textContent = F(I.value)
}

test()
textarea,pre { width: 15em; height: 15em; display: block; margin: 0; }
iframe { height: 25em; width: 15em}
td { vertical-align: top }
<table>
<tr>
<th>Test cases</th>
<th>Input</th>
<td></td>
<th>Output</th>
</tr><tr>
<td>
Copy/paste test cases from here <br>(courtesy of OP)
</td>
<td><textarea id=I>##########
#  o  o o#
# o\o o  #
#oo o/   #
#       o#
#     /o #
#\o   o  #
# o /-   #
#   o  - #
##########</textarea></td>
<td><button onclick='test()'>Test</button></td>
<td><pre id=O></pre></td>
</tr>
</table>

• Nice! I have a lot to learn in the ways of golf – rgajrawala Jan 4 '16 at 23:48
• shouldn´t you map values >9 with v>9?9:v? – Titus Nov 8 '17 at 2:29
• @Titus I could, but in fact I could do whatever I want, as a value > 9 is not expected, see the comment by OP answering my question. – edc65 Nov 8 '17 at 10:00

# Javascript (ES6), 453426409306290 286 bytes

The first and most obvious solution that came to my mind is one that looks around the slides and then merges or replaces.

a=>{a=a.split
.map(b=>[...b.replace(/o/g,'1')]);for(r=1;r<a.length-1;r++){d=a[r];for(c=1;c<d.length-1;c++){e=a[r+1];f=e[c]=='\\'?c+1:e[c]=='/'?c-1:!isNaN(+e[c])?c:null;(''+d[c]).match(/[0-9]/g)&&f!=null&&!isNaN(+e[f])?(e[f]=+e[f]+ +d[c],d[c]=' '):0}}return a.map(b=>b.join).join
}


Ungolfed:

func = state => {
state = state.split 
.map(line => [...line.replace(/o/g, '1')]);

for (r = 1; r < state.length - 1; r++) {
thisState = state[r];
for (c = 1; c < thisState.length - 1; c++) {
nextState = state[r + 1];
nc = nextState[c] == '\\' ? c + 1 : nextState[c] == '/' ? c - 1 : !isNaN(+nextState[c]) ? c : null;

('' + thisState[c]).match(/[0-9]/g) && nc != null && !isNaN(+nextState[nc]) ? (
nextState[nc] = +nextState[nc] + +thisState[c],
thisState[c] = ' '
) : 0;
}
}

return state.map(line => line.join ).join 
;
}


Test like:

func(##########
# -- o - #
# \\\\\\ -  #
#-       #
# o  o   #
#o \\\\ /-\\#
#      \\ #
#/-  //  #
#   /- o #
##########)


Thanks to: @edc65

• I'll post my python when I'm sure I can't golf it anymore, but so far it's the python code that's generating the answer. Any way I can test your golfed code somewhere so I can pop you on the leaderboard? (jsfiddle,jsbin,ideone,whatever) – Juan Cortés Jan 1 '16 at 21:01
• got it down to 355, your move! – Juan Cortés Jan 4 '16 at 2:54
• @JuanCortés Done! – rgajrawala Jan 4 '16 at 16:44
• b.replace(/o/g,'1').split  can be shortened to [...b.replace(/o/g,1)] – edc65 Jan 4 '16 at 19:44
• @edc65 I think I fixed it. Basically it always keeps the power under 10 by mod'ing 10. – rgajrawala Jan 4 '16 at 20:22

## Java, Too Many1102 987 bytes

Because, Java.

\o/ It's under 1000!

class G{class T{char s;int p=0;T(char c){s=c;}}T A=new T(' ');T[][]o;boolean i(){for(int i=1;i<o.length;i++)for(int j=1;j<o[i].length;j++)if(o[i][j].p>0){if(m(i,j,i+1,j)||o[i+1][j].s=='/'&&m(i,j,i+1,j-1)||o[i+1][j].s=='\\'&&m(i,j,i+1,j+1))return 1>0;int w=o[i][j].p;o[i][j]=new T(Integer.toString(w).charAt(0)){{p=w;}};}return 1<0;}boolean m(int a,int b,int c,int d){if(o[c][d]==A||o[c][d].p>0){o[a][b].p+=o[c][d].p;o[c][d]=o[a][b];o[a][b]=A;return 1>0;}return 1<0;}String s(){String s="";for(T[]r:o){for(T t:r)s+=t.s;s+="\n";}return s;}void f(String s){String[]r=s.split("\\\\n");o=new T[r.length][r[0].length()];for(int i=0;i<o.length;i++)for(int j=0;j<o[i].length;j++)switch(r[i].charAt(j)){case'-':o[i][j]=new T('-');break;case'\\':o[i][j]=new T('\\');break;case'/':o[i][j]=new T('/');break;case'o':o[i][j]=new T('o'){{p=1;}};break;case'#':o[i][j]=new T('#');break;default:o[i][j]=A;}}public static void main(String[]a){G g=new G();g.f(a[0]);while(g.i());System.out.println(g.s());}}


A side goal was being able to print every iteration of the board: just remove the middle ; in while(g.i()) ; System.out.print(g.s()); (Though this does disable the last print which has the 0->power conversion). Unfortunately, in this version, gravity works in strangely. Each pass I take the first non-stuck ball and move it. Short circuiting iterate() there is less bytes than going over the whole board then returning if anything changed.

This is a complete main class, compile and run on the command line with argument:

java -jar G.jar "##########\n# o-/    #\n#-  / -/ #\n# oo   o #\n# /   \o #\n# o   o \#\n#    o   #\n#   -\o  #\n#\  \\ o/#\n##########"


class GravitySimulator {
class Token {
char symbol;
int power = 0;

Token(char c) {
symbol = c;
}
}

Token A = new Token(' ');

Token[][] board;

boolean iterate() {
for (int i=1; i<board.length; i++)
for (int j=1; j<board[i].length; j++)
if (board[i][j].power>0) {
if (move(i,j,i+1,j) || board[i+1][j].symbol=='/' && move(i,j,i+1,j-1) || board[i+1][j].symbol=='\\' && move(i,j,i+1,j+1)) return true;
int pow = board[i][j].power;
board[i][j] = new Token(Integer.toString(pow).charAt(0)){{power=pow;}};
}
return false;
}

boolean move(int x1, int y1, int x2, int y2) {
if (board[x2][y2] == A || board[x2][y2].power>0) {
board[x1][y1].power += board[x2][y2].power;
board[x2][y2] = board[x1][y1];
board[x1][y1] = A;
return true;
} return false;
}

String string() {
String s = "";
for (Token[] row : board) {
for (Token token : row) s+=token.symbol;
s+="\n";
}
return s;
}

void fromString(String s) {
String[] rows = s.split("\\\\n");
board = new Token[rows.length][rows[0].length()];
for (int i=0; i<board.length; i++)
for (int j=0; j<board[i].length; j++)
switch(rows[i].charAt(j)) {
case '-': board[i][j]=new Token('-');break;
case '\\':board[i][j]=new Token('\\');break;
case '/': board[i][j]=new Token('/');break;
case 'o': board[i][j]=new Token('o'){{power=1;}};break;
case '#': board[i][j]=new Token('#');break;
default:  board[i][j]=A;
}
}

public static void main(String[] args) {
GravitySimulator g = new GravitySimulator();
g.fromString(args[0]);
while(g.iterate());
System.out.println(g.string());
}
}

• Such java much verbose. +1 – Rohan Jhunjhunwala Jul 9 '16 at 11:01

# Marbelous, 19561 bytes

(Not that I tried to optimize the size.)

This claims the final bounty here.

This expects a trailing newline in the input. It works for boards up to 15x15 (including the edges) but I feel like this is reasonable as that is a direct result of the num size limit being 255. Please use my interpreter as I can make no guarantees about other interpreters. It is based on the one here but with a few bug fixes and an added debugger.

To solve the boards in the example takes about 330000 ticks. That is mostly due to the difficulty of arbitrary data storage. Marbelous is not turning complete so I have to use a big rotating tape to store the board. The code is divided into roughly three sections. (Separated by those four big lines of %%).

1. This gets the full input and converts it to the encoding expected by the rest of the code. It also populates the initial fields of the main processing loop.
2. This function takes a t of values (ie one square and the three below it) and figures out the state after one tick. It then outputs all the values that need to be sent to the memory tape or terminates the program if we are complete.
3. This is the memory tape. It is possible to read or write to it by sending values to the appropriate portals.

Overall this is an interesting language that could be fun if it is made turning complete. I do feel that the coding can get a bit repetitive (it is mostly just lots of &0s) but it is still fun.

# ENCODING:
# 0 = empty square
# 1-9 = that many marbles
# A = wall
# B = right ramp
# C = left ramp
# D = reset count
# E = nothing

.. @B .. .. .. .. .. .. .. @C .. .. .. .. .. .. .. .. .. .. ..
.. 00 00 // // // // // // // .. .. .. .. .. .. .. .. .. .. ..
.. ge t_ in pu t_ +_ in it .. .. .. .. .. .. .. .. .. .. .. ..
.. @B @C .. .. &A .. .. @K .. .. .. .. .. .. .. .. .. .. .. ..
%% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
.. .. .. .. .. .. .. \\ \\ \\ \\ .. .. .. .. .. .. .. .. .. ..
.. .. .. // .. .. \\ \\ \\ .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. \\ \\ %% @4 %% @9 %% .. .. .. .. .. .. .. .. ..
.. .. .. .. \\ %% @3 \\ .. .. &4 .. .. .. .. .. .. .. .. .. ..
.. .. .. .. @2 \\ \\ .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. %% @1 \\ \\ .. .. .. .. // .. @A .. .. .. .. .. .. .. ..
0A @0 \\ \\ \\ .. 01 .. .. .. .. // // .. .. .. .. .. .. .. ..
\\ \\ \\ \\ ti ck _r et ur n_ pr in t_ an d_ te rm in at e_ pg # ys: v0 v3
.. .. .. .. @0 @1 @2 @3 @4 .. &0 &1 &2 .. &0 &1 &2 &3 &4 &3 &4 # xs: v1 v2 l0 w sl
.. .. .. .. .. .. .. .. .. \\ \\ \\ @5 \\ \\ \\ @6 \\ @7 \\ @8 # @5 = write loc
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. # @6 = write val
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. # @7 = read loc
.. .. .. .. .. .. .. .. .. .. .. .. \/ .. .. .. \/ .. \/ .. \/ # @8 = read ret loc
%% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% @D @E 01 .. %% # Acts as a switchboard
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% &5 &5 // .. %% # to activate the right
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% pl us .. .. %% # gate when a write is
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% =1 =2 =3 =4 %% # complete
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% &0 &1 &2 &3 %%
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% ++ ++ ++ eo %%
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% \\ \\ \\ @E %%
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. %% %% %% %% %% %%
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. @G @K .. ..
.. .. @P 0E .. .. @O 0E .. .. @N 0E .. .. @M 0E .. \\ .. .. ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 .. ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E .. \\ &9 0E ..
.. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // .. 0E &9 // ..
.. \\ &9 0E .. \\ &9 .. .. \\ &9 .. .. \\ &9 .. .. \\ &9 .. ..
.. 0E &9 // .. .. @P .. .. .. @O .. .. .. @N .. .. .. @M .. ..
.. \\ &9 0E .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. 0E .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. &A .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. \\ \\ .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. // // .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. \\ \\ .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. // // .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. \\ \\ .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. // // .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. 01 .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. ng .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. &A .. @5 .. @7 .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. .. du pe du pe .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. .. ez @L ez .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. .. +2 .. +3 .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. @H .. .. .. .. .. .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. // // // // .. .. .. .. .. .. .. .. ..
.. \\ &9 0E .. .. .. .. .. @I .. .. .. @L .. .. .. .. .. .. ..
.. 0E &9 // .. .. .. .. .. // // // // // .. .. .. .. .. .. ..
.. \\ &9 0E .. .. @F .. .. .. @J @8 @6 .. .. .. .. .. .. .. ..
.. .. &9 // .. .. 00 01 00 00 // // // .. .. .. .. .. .. .. ..
.. .. \\ \\ \\ lo op er lo op er lo op .. .. .. .. .. .. .. ..
.. .. .. .. .. @G @F @H @I @J @D @9 @A .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

#
# mode 0 = waiting
# mode 1 = inputing
# mode 2 = writing
:looper
# &6 = reset
# &5 = not reset
#
# &7 = writing and match
# &8 = writing and no match
#
# &9 = reading and match
# &A = reading and no match
#
# mode 1: output nothing
# mode 2:
}2 .. %% }0 .. %% 00 01 00 00 00 .. .. .. .. .. ..
>0 &0 %% =D &5 %% &1 &1 &1 &1 &1 .. .. .. .. .. ..
.. \/ %% &6 \/ %% {1 {2 {3 {4 \\ !! .. .. .. .. ..
>1 &1 %% \/ .. %% %% %% %% %% %% %% %% %% %% %% %%
.. \/ %% .. .. %% }1 }3 .. }4 }1 00 00 00 00 .. ..
>2 &2 %% %% %% %% &2 &2 .. .. ++ .. .. .. .. .. ..
.. \/ %% .. .. %% mi nu .. &7 &7 &7 &7 &7 &7 .. ..
>3 &3 %% .. .. %% =0 &8 .. {0 {1 {5 {3 {4 \\ !! ..
&4 \/ %% .. .. %% &7 .. .. .. .. .. .. .. .. .. ..
\/ .. %% .. .. %% .. .. }0 }0 }1 .. .. .. .. .. ..
.. .. %% .. .. %% .. .. .. ne wl 02 }3 }4 00 .. ..
.. .. %% .. .. %% .. .. &8 &8 .. &8 &8 &8 &8 .. ..
.. .. %% .. .. %% .. .. {0 {1 .. {2 {3 {4 \\ !! ..
.. .. %% .. .. %% %% %% %% %% %% %% %% %% %% %% %%
.. .. %% .. .. %% }1 }3 .. }0 }1 00 00 }4 }0 00 ..
.. .. %% .. .. %% &3 &3 .. .. ++ .. .. &9 &9 .. ..
.. .. %% .. .. %% mi nu .. &9 &9 &9 &9 se nd &9 ..
.. .. %% .. .. %% =0 &A .. {0 {1 {3 {4 {6 {7 \\ !!
.. .. %% .. .. %% &9 .. .. .. .. .. .. .. .. .. ..
.. .. %% .. .. %% .. .. }0 }0 }1 .. .. .. .. .. ..
.. .. %% .. .. %% .. .. .. ne wl 03 }3 }4 00 .. ..
.. .. %% .. .. %% .. .. &A &A .. &A &A &A &A .. ..
.. .. %% .. .. %% .. .. {0 {1 .. {2 {3 {4 \\ !! ..
.. .. %% .. .. %% .. .. .. .. .. .. .. .. .. .. ..
.. .. %% .. .. %% .. .. .. .. .. .. .. .. .. .. ..

:newl
# }0 = 0 -> same
# }0 = D -> 0
# else -> }1 + 1
}0 .. ..
=E =D ..
&0 &1 &2
\/ \/ \/
}1 00 }1
.. .. ++
&0 &1 &2
{0 {0 {0

# Tik, Return, Print, and Terminate Program
#
# 0,1,9-C,
#
:tick_return_print_and_terminate_pg
%% %% %% %% %% %% %% %% %% %% %% %% %%
%% }2 }3 }4 00 01 }2 }2 }2 }2 }2 }2 %% # Echo values that should be echoed
%% ++ .. .. .. .. ++ +2 .. -- .. ++ %%
%% .. .. .. .. .. .. }3 .. }3 }3 }3 %%
%% &0 &0 &0 &0 &0 &0 &0 &0 &0 &0 &0 %%
%% {2 {3 {4 {F {G {D {E {5 {6 {7 {8 %%
%% %% %% %% %% %% %% %% %% %% %% %% %%
%% .. .. .. .. %% .. }5 }0 }1 }6 .. %% # (left)  prints the cell
%% .. .. .. .. %% .. so lv ev ls .. %% # (right) solve the position
%% .. .. .. .. %% // // .. .. .. .. %%
%% .. }3 }2 .. /\ \\ .. .. .. .. .. %%
%% .. pr in tc %% .. &0 &0 &0 &0 .. %%
%% .. .. .. .. %% .. {9 {A .. du pe %%
%% .. .. .. .. %% .. .. .. // {C {1 %%
%% .. .. .. .. %% .. .. du pe .. .. %%
%% .. .. .. .. %% .. .. {B {0 .. .. %%
%% %% %% %% %% %% %% %% %% %% %% %% %%
%% .. }4 }2 .. .. .. .. .. .. .. 00 %% # Check if the program should terminate
%% .. mi nu .. .. .. .. }3 .. .. &1 %%
%% .. \\ \\ \\ =0 &0 .. &1 .. .. .. %%
%% .. .. .. .. &1 \/ .. pb .. .. .. %%
%% .. .. .. .. \/ .. .. .. .. .. !! %%
%% %% %% %% %% %% %% %% %% %% %% %% %%

# Get Input and Initlize
#
# gets the full board input
:get_input_+_init
# 1) }1 = 0 then print char }0++
# 2) }1 = 0 & char = \n then }1 = }0, }0 := 0
# 3) }1 != 0 & char != \n then }1++
# 4) eof then output stop
# 5) }0 = 1 or w-1 or w or w+1 & }1 != 0 output v
# 6) }1 != 0 output encoding
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. 00 .. .. .. .. .. .. .. .. .. .. .. .. .. }0 }1 ..
.. ]] &1 .. .. .. .. .. .. .. .. .. .. .. .. mi nu ..
.. .. \/ .. .. }0 }1 .. .. .. .. .. .. .. .. -2 .. 0D
.. \\ \\ \\ c+ ge t_ in pu t_ +_ in .. .. .. &1 .. &1
.. .. .. .. // .. .. .. .. .. .. .. .. .. .. /\ {4 {7
.. .. .. /\ {0 {1 {2 {3 {4 {5 {6 {7 .. .. !! .. .. ..
.. .. !! .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

# Char + Get Input and Initlize
#
# gets the full board input
:c+get_input_+_init
# &0 = no width
# &1 = width
# &2+&9 = newline
# &3+&8 = not newline
# &4 = no width & newline
# &5 = no width & !newline
# &6 = width & newline
# &7 = width & !newline
# &A/B/B = release v0/2/3
.. .. .. .. %% 00 00 %% .. .. .. .. .. .. .. .. .. .. .. .. ..
}2 .. .. .. %% &0 &0 %% }0 .. }1 00 .. 00 }1 }1 .. }0 }1 }2 ..
=0 &1 .. .. %% &2 &3 %% &0 .. &5 &5 .. &4 &4 &4 .. ec ++ .. ..
&0 \/ .. .. %% &4 &5 %% [[ .. ++ .. .. {0 {1 {3 .. &7 &7 &7 ..
\/ .. .. .. %% \/ \/ %% .. .. {0 {1 .. .. .. .. .. {7 {0 {1 ..
%% %% %% %% %% %% %% %% .. .. .. .. .. .. .. .. .. .. .. .. ..
}0 .. .. .. %% 00 00 %% }1 }2 .. }0 }0 }0 .. 23 .. .. .. .. ..
=A \\ du pe %% &1 &1 %% &6 &6 .. ec ec ec .. &4 .. .. .. .. ..
du pe &3 &8 %% &9 &8 %% {0 {1 .. &A &B &C .. [[ .. .. .. .. ..
&2 &9 \/ \/ %% &6 &7 %% .. .. .. {5 {2 {6 .. .. .. .. .. .. ..
\/ \/ .. .. %% \/ \/ %% .. .. .. .. .. .. .. .. .. .. .. .. ..
%% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
}1 .. .. }1 .. .. }1 .. .. .. .. .. .. .. .. .. .. .. .. .. ..
&7 .. .. &7 }2 .. &7 }2 .. .. .. .. .. .. .. .. .. .. .. .. ..
=1 \/ .. mi nu .. mi nu .. .. .. .. .. .. .. .. .. .. .. .. ..
&A .. .. =1 \/ .. =2 \/ .. .. .. .. .. .. .. .. .. .. .. .. ..
\/ .. .. &B .. .. &C .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. \/ .. .. \/ .. .. .. .. .. .. .. .. .. .. .. .. .. ..
00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ !!

# Encoding
#
# convert the char code to the encoding
:ec
}0 .. .. .. .. ..
++ .. .. .. .. ..
>> .. .. .. .. ..
>> .. .. .. .. ..
=S =B =C =N =9 ..
&0 &1 &2 &3 &4 &5
\/ \/ \/ \/ \/ \/
01 0A 0C 0B 0A 00
&0 &1 &2 &3 &4 &5
\\ \\ \\ {0 // //

# Print Bottom
#
# prints #\n then # repeated }0 times
:pb
0A .. @0 .. @1 ..
23 .. &0 .. &0 ..
[[ 23 /\ [[ -- ..
.. @0 .. }0 >0 \/
.. .. .. \\ @1 ..

# Print Cell
#
# }0 = the width of the board
# }1 = the position of the cell to print
# }2 = the cell to print
#
# prints the cell and a newline if needed
:printc
%% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
%% }0 }1 %% .. %% }2 .. .. .. .. %% .. .. .. .. }2 %% }1 }0 %% .. %%
%% is bd %% 23 %% &0 .. .. .. .. %% 20 2D 5C 2F tn %% ++ .. %% 0A %%
%% =1 &0 %% &1 %% =0 =A =B =C <A %% &2 &3 &4 &5 &6 %% di vb %% &7 %%
%% &1 \/ %% [[ %% &2 &3 &4 &5 &6 %% [[ [[ [[ [[ [[ %% =1 \/ %% [[ %%
%% \/ .. %% .. %% \/ \/ \/ \/ \/ %% .. .. .. .. .. %% &7 .. %% .. %%
%% .. .. %% .. %% .. .. .. .. .. %% .. .. .. .. .. %% \/ .. %% .. %%
%% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%

# Is Border
#
# }0 = board width
# }1 = position
#
# {0 = 1 if on border else 0
:isbd
}1 }0 }1 }0
.. .. ++ ..
di vb di vb
\\ {0 // ..

# Solve Values
#
# takes input in a t:
# takes 4 cells in a t shape:
#       x    or    1
#      xxx        234
# and returns their values
# after 1 tick
:solvevls
# &0) center is space
# &1) center is wall
# &2) left slide & left is space
# &3) left slide & left isn't space
# &4) right slide & right is space
# &5) right slide & right isn't space
# &7) no ball
%% %% %% %% %% %% %% %% %% %% %%
%% }0 .. .. .. .. .. .. .. .. %% # Top Center
%% du pe 6x 6x 6x 6x .. .. .. %%
%% <A <A <A <A <A <A &7 .. .. %%
%% &0 &1 &2 &3 &4 &5 \/ .. .. %%
%% \/ \/ \/ \/ \/ \/ .. .. .. %%
%% %% %% %% %% %% %% %% %% %% %%
%% }1 .. .. .. .. .. .. .. .. %% # Bottom Left
%% du pe 6x 6x 6x 6x .. .. .. %%
%% .. .. <A >9 .. .. \/ .. .. %%
%% .. .. &2 &3 .. .. .. .. .. %%
%% \/ \/ \/ \/ \/ \/ .. .. .. %%
%% %% %% %% %% %% %% %% %% %% %%
%% }2 .. .. .. .. .. .. .. .. %% # Bottom Center
%% du pe 6x 6x 6x 6x .. .. .. %%
%% <A =A =C =C =B =B \/ .. .. %%
%% &0 &1 &2 &3 &4 &5 .. .. .. %%
%% \/ \/ \/ \/ \/ \/ .. .. .. %%
%% %% %% %% %% %% %% %% %% %% %%
%% }3 .. .. .. .. .. .. .. .. %% # Bottom Right
%% du pe 6x 6x 6x 6x .. .. .. %%
%% .. .. .. .. <A >9 \/ .. .. %%
%% .. .. .. .. &4 &5 .. .. .. %%
%% \/ \/ \/ \/ \/ \/ .. .. .. %%
%% %% %% %% %% %% %% %% %% %% %%
%% .. .. }0 .. %% .. .. .. .. %%
%% 00 }1 }2 }3 %% }0 }1 }2 }3 %%
%% &0 &0 &0 &0 %% &1 &1 &1 &1 %%
%% {0 {1 {2 {3 %% {0 {1 {2 {3 %%
%% %% %% %% %% %% %% %% %% %% %%
%% .. }0 .. .. %% .. .. .. .. %%
%% 00 }1 }2 }3 %% }0 }1 }2 }3 %%
%% &2 &2 &2 &2 %% &3 &3 &3 &3 %%
%% {0 {1 {2 {3 %% {0 {1 {2 {3 %%
%% %% %% %% %% %% %% %% %% %% %%
%% .. .. .. }0 %% .. .. .. .. %%
%% 00 }1 }2 }3 %% }0 }1 }2 }3 %%
%% &4 &4 &4 &4 %% &5 &5 &5 &5 %%
%% {0 {1 {2 {3 %% {0 {1 {2 {3 %%
%% %% %% %% %% %% %% %% %% %% %%
%% .. .. .. .. %% .. .. .. .. %%
%% }0 }1 }2 }3 %% .. .. .. .. %%
%% &7 &7 &7 &7 %% .. .. .. .. %%
%% {0 {1 {2 {3 %% .. .. .. .. %%
%% %% %% %% %% %% %% %% %% %% %%

# @0 set tape to position
#    @7 gets zero once complete
# @1 send current marble to location + advance one
# @2 write to current marble + advance one

# &0 = marble tape
# &1 = counter

# @3 counter loop
# @4, @5, @6

# .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. 08 @5 .. .. .. .. .. .. .. .. .. ..
# .. 07 &0 // // .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 06 .. .. .. .. .. .. .. .. .. .. ..
# .. 05 &0 // .. .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 04 .. .. .. .. .. .. .. .. .. .. ..
# .. 03 &0 // .. .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 02 .. .. .. .. .. .. .. .. .. .. ..
# .. 01 &0 // .. .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 00 .. .. .. .. .. .. .. .. .. .. ..
# .. 00 &0 // .. .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 00 .. .. .. .. .. .. .. .. .. .. ..
# .. 00 &0 // .. .. .. .. .. .. .. .. .. .. ..
# .. \\ &0 .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. /\ @5 .. .. .. .. 00 .. .. .. .. .. ..
# .. >0 @8 .. .. .. .. .. .. .. .. .. .. .. ..
# .. &1 .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. .. .. .. .. @8 .. @9 .. .. .. .. ..
# .. .. .. .. .. .. .. \\ &0 // .. .. .. .. ..
# .. .. .. .. .. .. .. .. \/ .. .. .. .. .. ..
# .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. .. .. .. .. .. @3 00 .. .. .. .. ..
# .. .. .. .. .. .. .. .. &1 // .. .. .. .. ..
# .. .. .. .. .. .. .. .. ++ .. .. .. .. .. ..
# .. .. .. .. .. .. .. @3 /\ .. .. .. .. .. ..
# .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. .. .. .. 05 @0 @4 .. .. .. .. .. ..
# .. .. .. .. .. .. \\ \\ te st .. .. .. .. ..
# .. .. .. .. .. .. .. .. @4 .. =0 \\ .. .. ..
# .. .. .. .. .. .. .. .. .. .. @9 .. .. .. ..
# .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
# .. .. .. .. .. .. .. .. .. .. .. .. \/ .. ..

# Test Equality
#
# if }0 == }1 sends 00 to {0 and 01 to {>
# else sends }0 to {0 and 00 to {>
:test
}0 }1 .. .. .. .. ..
mi nu .. .. }0 .. ..
=0 \\ \\ &0 &0 .. ..
du pe 3x \/ du pe 3x
ez eo .. .. .. .. ez
{0 {> !! .. !! {0 {>

### SIMPLE HELPERS ###

# Send
#
# sends }1 to {0 if }0 = 0 else {1
:send
}0 .. 00
=0 &1 ..
&0 \/ ..
\/ .. ..
}1 }1 ..
&0 &1 ..
{0 {1 !!

# Marker
#
# does nothing
:%%
}0
{0

## EQUALS ##

# Equals Max
#
# sends FF to {0
:em
}0 FF
.. {0

# Equal One
#
# sends 01 to {0
:eo
}0 01
.. {0

# Equal Zero
#
# sends 00 to {0
:ez
}0 00
.. {0

## DUPLICATE ##

# Duplicate 2 times
#
# sends }0 to {0 and {1
:dupe
.. }0 ..
{0 /\ {1

# Duplicate 3 times
#
# sends }0 to {0, {1, and {2
:dupe3x
.. }0 .. ..
.. /\ .. ..
.. .. /\ ..
.. .. .. //
{0 {1 {2 ..

# Duplicate 4 times
#
# sends }0 to {0, {1, {2, and {3
:dupe4x4x
.. }0 .. .. ..
.. /\ .. .. ..
.. .. /\ .. ..
.. .. .. /\ ..
.. .. .. .. //
{0 {1 {2 {3 ..

# Duplicate 6 times
#
# sends }0 to {0, {1, {2, {3, {4 and {5
:dupe6x6x6x6x
.. }0 .. .. .. .. ..
.. /\ .. .. .. .. ..
.. .. /\ .. .. .. ..
.. .. .. /\ .. .. ..
.. .. .. .. /\ .. ..
.. .. .. .. .. /\ ..
.. .. .. .. .. .. //
{0 {1 {2 {3 {4 {5 ..

### MATH ###

# Divisible By
#
# returns }0 % }1 == 0
:divb
}0 }1
mo du
=0 &1
&0 ..
01 00
&0 &1
{0 {0

# Modulo
#
# sends }0 % }1 to {0
#
# if }0 > }1 return modu }0 - }1 else }0
:modu
}0 }1
Gt eq # interpreter includes this
=1 &0
&1 \/
\/ ..
}0 ..
&0 ..
{0 ..
.. ..
}0 }1
mi nu
&1 }1
mo du
{0 ..

# To Number Char
#
# converts number 0-9 to a number character
:tn
}0
+F
+F
+F
+3
{0

# Plus
#
# sends }0 + }1 to {0
:plus
}0 .. }1
\\ {0 //

# Minus
#
# sends }0 - }1 to {0
:minu
.. }1
}0 ng
\\ {0

# Negative
#
# sends -}0 to {0
:ng
}0
~~
++
{0


• Amazing. I'd like to add to the bounty as well. – Razetime Apr 7 at 5:06

## Python3, 355b

g=g.replace("o","1").split("\n")
r=1
while r:
r=0
for y in range(len(g)):
for x in range(len(g[y])):
if g[y][x].isdigit():
h=g[y+1]
m={"/":-1,"\\":1}
j=x+m[h[x]]if h[x]in m else x
if("0"+h[j].strip()).isdigit():
r=1
g[y+1]=h[:j]+str(int(g[y][x])+int("0"+h[j]))+h[j+1:]
g[y]=g[y][:x]+' '+g[y][x+1:]
print("\n".join(g))


Test here

# PHP, 228 204 197 194 bytes

for($a=strtr($a,o,1);$c=$a[$i];$i++)$c>0&&(($d=$a[$t=$i+strpos($a,"
")+1])>" "?$d!="/"?$d!="\\"?$d>0:$a[++$t]<"!"||$a[$t]>0:$a[--$t]<"!"||$a[$t]>0:1)&&$a[$t]=min($a[$t]+$c,9).!$a[$i]=" ";echo$a;  yields warnings in PHP 7.1. Insert (int) before $a[$t]+$c to fix.

Run with php -nr '$a="<string>";<code>' or try it online. breakdown for($a=strtr($a,o,1); # replace "o" with "1"$c=$a[$i];$i++) # loop through string$c>0                    # if character is numeric
&&(($d=$a[                  # and ...
$t=$i+                  # 3: target position = current position + 1 line
strpos($a,"\n")+1 # 2: width = (0-indexed) position of first newline +1 ])>" " # if target char is not space ?$d!="/"                # and not left slide
?$d!="\\" # and not right slide ?$d>0                   # but numeric: go
:$a[++$t]<"!"||$a[$t]>0     # right slide: if target+1 is space or ball, then go
:$a[--$t]<"!"||$a[$t]>0     # left slide: if target-1 is space or ball, then go
:1                              # space: go
)&&                     # if go:
$a[$t]=min($a[$t]+$c,9) # move ball/merge balls .!$a[$i]=" " # clear source position ; echo$a;                 # print string