Let's play ASCII mini-golf

4

Let's play code golf... by playing golf.

Input

Your input will be a string consisting of #'s, an o, an @, and .'s. For example:

......@..
.....##..
.........
......o..

. - playable golf course (all shots must end on one of these)
# - a barrier (shots cannot go through this)
o - the starting position of your golf ball
@ - the hole

How to Play ASCII Golf

You start at the o. Here is a valid shot from point A to point B:

1) This shot is straight line that can be drawn between A and B (no curved shots).

A....
....B

2) The line AB may not intersect with a # (barrier), e.g.:

A.#.B

It may, however, be tangent to a barrier:

A#
.B

3) (For clarity) You may not bounce shots off barriers or the edge of the golf course.

Output

Print to stdout (or an acceptable equivalent) the minimum number of shots to get the ball into the hole @. If it is not possible, print -1.

Examples

o....@

=> 1

o.#.@

=> -1

o..#
..#@

=> 2 (you can pass through the vertices of a #, but not the edges)

o#...#
.#.#.#
...#.@

=> 4

AMACB

Posted 2016-05-20T01:13:32.643

Reputation: 657

Question was closed 2016-05-22T00:44:01.923

6Can’t your “6” example be done in 4 shots (south 1, southeast 1, northeast 2, southeast 2)? – Anders Kaseorg – 2016-05-20T03:51:48.087

In the worst case you would need to write/golf a pathfinder algorithm like A* or something similar. Which may be quite difficult/challenging for some languages. – Rolf ツ – 2016-05-20T08:25:15.020

@AndersKaseorg Good point, fixed. – AMACB – 2016-05-20T12:56:45.463

What would ..@ \no#. mean? – Leaky Nun – 2016-05-20T13:07:06.793

Can you do this in 1 shot? o### / #..# / ###@ (3 rows) – aditsu quit because SE is EVIL – 2016-05-20T17:52:19.640

i think that op must define which particular cases make a ball rebouncing off an egde. – Abr001am – 2016-05-20T20:32:55.263

@AndersKaseorg why can it not be 3 ? south 2, n-e 3, etc .. – Abr001am – 2016-05-20T20:43:17.770

@aditsu No, because the line would intersect the edge of a #. – AMACB – 2016-05-21T00:21:55.333

@Agawa001 The question is clear: “You may not bounce shots off barriers or the edge of the golf course.” And no, there’s no 3 shot solution. – Anders Kaseorg – 2016-05-21T03:32:02.057

What about this: o.## / ##.@ ? 1 shot? – aditsu quit because SE is EVIL – 2016-05-21T04:58:44.580

@aditsu. Yes, because the line from o to @ only intersects the vertices of the #'s – AMACB – 2016-05-21T15:30:51.273

What? On hold? I'm pretty clear about the challenge now, but it took a couple of comments to make sure. @AMACB you should probably explain the exact trajectory of the ball and shape of the barriers more clearly. If not, maybe I can edit the question later. – aditsu quit because SE is EVIL – 2016-05-22T07:28:01.683

I don't have time right now, but I will try to get to it soon. – AMACB – 2016-05-22T17:17:00.747

Answers

3

Python 2, 469

Pretty long, but it's a start:

R=range
def l(c,x,y,z,t):
 f=abs(z-x);g=1-2*(z<x);p=abs(t-y);q=1-2*(t<y);v=r=0
 for i in R(f):
  w=f+(2*i+1)*p
  for j in R(v,(w-1)/2/f+1):r|='.'>c[x+g*i][y+q*j]
  v=w/2/f
 for j in R(v,p+1):r|='.'>c[z][y+q*j]
 return r
def f(c):
 a="".join(c);n=len(c[0]);b=len(a);d=[[9**9*l(c,i/n,i%n,j/n,j%n)+1for i in R(b)]for j in R(b)]
 for k in R(b):
  for i in R(b):
   for j in R(b):
    t=d[i][j]=min(d[i][j],d[i][k]+d[k][j])
    if"o@"==a[i]+a[j]:r=t
 return-1if r>9**9else r

Function f takes a list of strings and returns the number of shots.

Test suite:

def test(s,r):
 print"ok"if f(s.split())==r else"fail"

test("o # @", -1)
test("......@.. .....##.. ......... ......o..", 2)
test("o....@", 1)
test("o.#.@", -1)
test("o..# ..#@", 2)
test("o#...# .#.#.# ...#.@", 4)
test("o### #..# ###@", 3)
test("o.## ##.@", 1)
test("...o .@#.", 2)

aditsu quit because SE is EVIL

Posted 2016-05-20T01:13:32.643

Reputation: 22 326