14
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$
    – Joey
    Aug 29, 2011 at 17:11
  • \$\begingroup\$ @Joey A generating script would be a useful tool to have available. \$\endgroup\$
    – Gareth
    Aug 29, 2011 at 17:42
  • \$\begingroup\$ Both sets of test should be fixed now. \$\endgroup\$
    – Gareth
    Aug 29, 2011 at 18:45

4 Answers 4

4
\$\begingroup\$

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
\$\endgroup\$
10
  • 2
    \$\begingroup\$ Maybe s+=min(p,19-p)? \$\endgroup\$ Sep 2, 2011 at 3:07
  • 2
    \$\begingroup\$ for r in l[:-3]:p-=" /".find(r[p]) should save a few chars \$\endgroup\$
    – gnibbler
    Sep 2, 2011 at 3:55
  • 1
    \$\begingroup\$ Thank you two. Especially gnibbler's trick is truly awesome - but it cannot hurt to know a shorter tri function, too ;) \$\endgroup\$
    – cemper93
    Sep 2, 2011 at 11:23
  • 1
    \$\begingroup\$ @gnibbler That's a genius trick. \$\endgroup\$
    – Gareth
    Sep 2, 2011 at 12:03
  • 1
    \$\begingroup\$ 19-p+1 == 20-p \$\endgroup\$
    – Lowjacker
    Sep 2, 2011 at 21:29
3
\$\begingroup\$

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).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Surprisingly 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. \$\endgroup\$
    – Gareth
    Aug 29, 2011 at 19:44
  • \$\begingroup\$ ./test-bagatelle.sh `which golfscript.rb` bagatelle2.gs \$\endgroup\$ Aug 29, 2011 at 20:08
3
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ list(sys.stdin) instead of readlines() \$\endgroup\$
    – gnibbler
    Sep 1, 2011 at 9:11
3
\$\begingroup\$

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}*?+
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Why use rescue? Can't you chop off two lines from b in the initial assignment? \$\endgroup\$
    – migimaru
    Sep 5, 2011 at 17:56
  • \$\begingroup\$ @migimaru: Indeed. But I have to chop off three lines, not two. \$\endgroup\$
    – Lowjacker
    Sep 5, 2011 at 22:30
  • \$\begingroup\$ Right. I meant two more lines. Sorry. \$\endgroup\$
    – migimaru
    Sep 6, 2011 at 0:27
  • 1
    \$\begingroup\$ you can use i-='\ /'... instead to save one more char \$\endgroup\$
    – gnibbler
    Sep 6, 2011 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.