Simulate a (gravity-based) billiard-ball-type computer

The Machine

A billiard-ball type machine is composed of only the symbols \ _ / along with upper- and lower-case letters, spaces, and the number 1.

\ and / are ramps. A ball coming from above will be deflected to either the right or left side, respectively. For both ramps, if a ball comes from either side, it will be deflected downward.

_ is a logic element. The logic performed by it is the most un-billiard-like part of the computer. First, a ball coming from the left or right continues in the same direction. A ball coming from above will be stopped. Then, after the end of its execution (see Running the Machine below), if the number of balls crossing/landing on it is positive even number, then a single ball is released from the bottom of the element.

A space does nothing. Any balls coming from any direction fall straight down due to gravity.

Lowercase letters are inputs. All inputs will either be a single 1 or 0.

Uppercase letters are outputs. The number outputted will be the number of billiard balls that hit its location.

The number 1 releases a extra billiard-ball at that location. It represents a logical 1.

All characters besides \_/ cause any ball coming from any direction to fall straight down due to gravity.

Balls never combine, split, or collide. They are only created when released from an input, a _, or a 1. They are only destroyed when they fall straight down onto a _.

Example machine-

1 a
\_/ b
\_/
\/
/\ /
_  _
A  B


There will never be any blank lines in a machine, but the _'s may make it appear that there is a blank line.

Running the Machine

A machine is run in layers, or rows. All billiard-ball movement on the top layer is performed before anything happens on the second layer.

The machine

ab
\_A
C


is run as follows:

First, it prompts for the input a in the form a:. The user will then input a 1 or 0 (followed by enter). It repeats this for the input b. This is the end of the first layer. I am going to assume that the user entered a 1 for both inputs.

It then traces out the path of the first ball (from a), which goes along the \, across the _, into the A, and falls down to the spot under the A. It then traces out the path for the second ball (from b), which goes straight down onto the _ and terminates. This is the end of the second layer.

Now, before the third layer, since the _ has had two balls cross over it, it releases one ball. The output A has had one ball cross over it, so it outputs A:1.

For the third layer, it traces the path of the first ball (from the _), which goes though the C and falls straight down. The second ball (which fell through the A) also falls straight down.

Now, before the fourth layer, since the output C had one ball travel over it, it outputs C:1.

Since the fourth layer is blank, the program terminates.

The total result should look like

a:1     (the user entered the one)
b:1     (same here)
A:1
C:1


The Goal

Your goal is to take a machine from STDIN and simulate it by taking inputs and printing output as needed to STDOUT. The first part of the input to your program will consist of the machine to be run, followed by a blank line. Any input letters encountered should cause your program to prompt for input in the form of the input name followed by a colon. Any output should be shown in the form of the output name, followed by a colon, followed by the number of balls passing over that spot.

This is golf.

Examples

A wire crossing

ab
\/
AB


An XOR gate

ab1
\_/
C


1 a
\_/ b
\_/
\/
/\
_ __/
\_/
\/c
\\_/
_S1
\  \/
__/
/
_
\__
C

• In your first example, why does the first ball fall down under the A? Is there an unwritten rule that balls stop when they pass onto a character which isn't \_/? Oct 17, 2011 at 7:41
• @PeterTaylor Yes, I should add that all letter behave as an empty space when it comes to affecting the ball, and gravity pulls the ball down. Oct 17, 2011 at 10:26
• Do you, by any chance, mean 'flipper', not 'billard'? Oct 20, 2011 at 0:49
• MAKE DIS AN ESOLANG Feb 8, 2017 at 13:59
• @AlexL. Also relevant: Marbelous Feb 10, 2017 at 13:41

JavaScript (392 423)

Assumes machine is set in a variable called m, then alerts the final output.

l=m.split(q='\n');o='';for(r=Array(z=l[i=0].length);i<l.length;i++){L=l[i];n=Array(z);for(c=0;c<z;n[c]=N,r[c++]=R){C=L[c];N=~~n[c];R=~~r[c];if(C>''){N+=x=~~prompt(C);R+=x;o+=C+': '+x+q}else if(C=='\\'||C=='/'){for(d=c+(g=C=='/'?-1:1);L[d]=='_';r[d]+=R,d+=g);if(L[d]>'@'&L[d]<'[')r[d]+=r[c];n[d]=~~n[d]+R}else if(C<'2')N+=R+=~~C;else if(C!='_')o+=C+': '+R+q}for(c=0;c<z;c++)if(L[c]=='_')n[c]+=(r[c]%2)?0:r[c]>0;r=n}alert(o)


Sample source (runs adder machine, see history for less golfed sources): http://jsfiddle.net/96yLj/12/

Spoilers:

- r tracks the # of balls across current row, n tracks # of balls across next row.
- Algorithm: process each row character by character, but process _'s last.
- Algorithm: \ -> follow _ and increase r until non-_. Same for / but in reverse direction. At the end increase n for gravity pulling balls down. g holds direction.
- if(L[d]>'@'&L[d]<'[')r[d]+=r[c]; is for the bug mentioned in Edit 1. The reason we can't just say r[d]+=r[c]; is because \_/ will double-count balls when processing /
- else if(C<'2') handles both cases '1' and ' ', which ~~C turns into 1 and 0, respectively.

Edit 1: Fix bug with ball running over _ not included in A for sample code.

• Note that I always ignore STDIN and STDOUT requirements because they are uninteresting restrictions. I am using prompt for input and alert` for output which is pretty standard for JavaScript :-) Oct 24, 2011 at 14:44