A Mere Bagatelle

13

1

The challenge

Given a bagatelle board like the one below:

|                    |
|    /\            / |
|      \            /|
|  \      \ /\    \  |
|   \   /       \    |
|\     /   /  \      |
|   \            / \ |
|    \               |
|  \    / \ /\    \  |
|\     /   /  \     /|
|                /   |
|    /\         /  / |
|              /     |
|\     /   /  /      |
|                    |
----------------------

your task is to turn a list of 'throws' into a score.

The board will always be 20 characters (plus 2 edges) wide, but of variable height. Each 'throw' is a number representing where the ball falls into the board, starting at 0 for the far left up to 19 for the far right. Each ball will fall straight down unless it encounters a / or a \. Encountering a / shifts the ball one column to the left, and a \ shifts the ball one column to the right. After being shifted, the ball continues straight down as before. The score for a throw is dependant on where the ball hits the bottom of the board.

The scores for each finishing position are as follows:

|                    |
----------------------
 01234567899876543210

and are the same for all boards. The first and last rows will always be empty. The ball is guaranteed to reach the bottom regardless of where it is dropped from, so there will be no boards where it can get trapped by \/,\| or |/ combinations.

Input

Input will be on STDIN, and will consist of the board followed by a blank line followed by a space separated list of numbers representing the throws.

Output

Ouput should be the total score for the given game.

A couple of examples

Input

|                    |
| \                  |
|  \                 |
|   \                |
|    \               |
|     \              |
|      \             |
|       \            |
|        \           |
|         \          |
|          \         |
|           \        |
|            \       |
|             \      |
|              \     |
|               \    |
|                \   |
|                 \  |
|                    |
|                    |
----------------------

1 4 2 19 0 2 4 3 17 13 16

Output

9

Input

|                    |
| \                / |
|  \              /  |
|   \            /   |
|    \          /    |
|     \        /     |
|      \      /      |
|       \    /       |
|        \  /        |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
----------------------

15 10 3 8 18 19 0 6 7 10

Output

72

Input

|                    |
| ////////////////// |
| \\\\\\\\\\\\\\\\\\ |
| ////////////////// |
| \\\\\\\\\\\\\\\\\\ |
| ////////////////// |
| \\\\\\\\\\\\\\\\\\ |
| ////////////////// |
| \\\\\\\\\\\\\\\\\\ |
| ////////////////// |
| \\\\\\\\\\\\\\\\\\ |
|                    |
----------------------

1 4 18 17 14 2 0 19 15

Output

18

Test scripts

I've used some test scripts written by Joey and Ventero (I hope they don't mind...) to create some tests for this task:-

Usage: ./test [your program and its arguments]

This is codegolf - shortest solution wins.

Gareth

Posted 2011-08-29T17:02:13.207

Reputation: 11 678

You could have my generating script for them as well :-). I eventually wanted to make that public but as long as it still needs tweaking for many tasks I didn't want to do that. – Joey – 2011-08-29T17:11:10.683

@Joey A generating script would be a useful tool to have available. – Gareth – 2011-08-29T17:42:45.807

Both sets of test should be fixed now. – Gareth – 2011-08-29T18:45:49.527

Answers

3

GolfScript, 60 59 chars

n/{},)\);{1>:x,,{.x=31%4%(+}%}%[10,.-1%+]+0@[~]{2${=}/+}/\;

I was so tempted to write a solution which works by redefining the symbols /, \, and space, but it's actually quite expensive (especially once you can no longer use the original \).

31%4%( is nicked from Keith Randall's solution and maps the ASCII codes for space, /, and \ to 0, -1, 1 respectively. (See edit history).

Peter Taylor

Posted 2011-08-29T17:02:13.207

Reputation: 41 901

1Surprisingly long for GolfScript. :-) How did you get it to work with the test script though? All I got was errors when I tried ./test ruby golfscript.rb peter.gs? I threw some tests at it as piped input instead. – Gareth – 2011-08-29T19:44:37.463

./test-bagatelle.sh \which golfscript.rb` bagatelle2.gs` – Peter Taylor – 2011-08-29T20:08:46.620

4

Python 2, 147 132 130 chars

import sys
s=0
l=list(sys.stdin)
for t in l[-1].split():
 p=int(t)+1
 for r in l[:-3]:p-=" /".find(r[p])
 s+=min(p-1,20-p)
print s

cemper93

Posted 2011-08-29T17:02:13.207

Reputation: 670

Did you run it against the test script? ;-) – Gareth – 2011-09-01T21:16:23.323

No, just against the examples in the question. I'll try the test script. [...] I see that it gives wrong results now. It used to work earlier, I'll search for that bug. – cemper93 – 2011-09-01T22:21:13.700

Ohh, it's because i thought it to be clever to use a triangle wave instead of the range and reversal I used earlier (and Keith still uses). This doesn't work because I need the 9 twice, though. Hmm - I'll see whether I can find a trick around that, my triangle wave is a mess anyway (can't even remember why there are brackets around the twenty, and the first ten is meant to be a nine). – cemper93 – 2011-09-01T22:28:01.370

Okay, fixed now. Next time I test my stuff a little more ;) – cemper93 – 2011-09-01T22:42:56.710

No problem, I often manage to break my answers with excessive shrinking. – Gareth – 2011-09-01T22:51:06.680

2Maybe s+=min(p,19-p)? – Keith Randall – 2011-09-02T03:07:20.553

2for r in l[:-3]:p-=" /".find(r[p]) should save a few chars – gnibbler – 2011-09-02T03:55:28.203

1Thank you two. Especially gnibbler's trick is truly awesome - but it cannot hurt to know a shorter tri function, too ;) – cemper93 – 2011-09-02T11:23:18.163

1@gnibbler That's a genius trick. – Gareth – 2011-09-02T12:03:30.467

119-p+1 == 20-p – Lowjacker – 2011-09-02T21:29:19.603

3

Python, 165 159 chars

import sys
A=list(sys.stdin)
C=range(10)
C+=C[::-1]
for L in A[-4::-1]:C=[C[i+ord(L[i+1])%31%4-1]for i in range(20)]
print sum(C[int(x)]for x in A[-1].split())

It starts with a row of scores and works its way from the bottom up, computing what the scores would be for balls starting at each row.

Keith Randall

Posted 2011-08-29T17:02:13.207

Reputation: 19 865

list(sys.stdin) instead of readlines() – gnibbler – 2011-09-01T09:11:27.583

3

Ruby, 123 117 115 107 99 98 97

*b,_,_,n=*$<
p eval n.split.map{|k|i=k.to_i+1
b.map{|l|i-='\ /'.index(l[i])-1}
[i-1,20-i].min}*?+

Lowjacker

Posted 2011-08-29T17:02:13.207

Reputation: 4 466

1Why use rescue? Can't you chop off two lines from b in the initial assignment? – migimaru – 2011-09-05T17:56:30.507

@migimaru: Indeed. But I have to chop off three lines, not two. – Lowjacker – 2011-09-05T22:30:23.600

Right. I meant two more lines. Sorry. – migimaru – 2011-09-06T00:27:35.467

1you can use i-='\ /'... instead to save one more char – gnibbler – 2011-09-06T05:36:13.110