Find the right path

13

1

Given a list of paths, output the correct path.

Example of path:

    /\
----+/
    |
  • - and | are horizontal and vertical paths.
  • / and \ are 90° turns.
  • + is treated as a - or a | depending of the current direction.

Paths may go in any direction and a character may be used in multiple paths.

Input will be like this:

       /--\
A------+--+--#
B------/  \--:
C------------#
D------------#
  • A, B, C and D are path starts
  • # is a wall (the path is bad)
  • : is the end (the path is correct)

So here the output will be B.

You can assume:

  • : and # will always be reached from the left.
  • The character at the right of the start of a path will always be -.
  • Paths will always be well formed.
  • # and : will always be in the same column.
  • There will always be only one : and 4 paths.

Test cases

A------#
B------#
C------#
D------:
=>
D
A-\ /---:
B-+-/ /-#
C-+---+-#
D-+---/
  \-----#
=>
B
  /-\
A-+\\---#
B-/\-\/-#
C----++-#
D----+/
     \--:
=>
A
A-\
B-+\
C-++\/----#
D-+++//---:
  \++-//--#
   \+--//-#
    \---/
=>
A
  /-\
A-+-/-\
B-+-+-\--#
C-+-/ |/-#
D-\---++-#
  \---+/
      \--:
=>
B

Since this is , the shortest answer win.

TuxCrafting

Posted 2016-08-28T10:31:28.783

Reputation: 4 547

Will there ever be two paths incident on the same / or \? – Martin Ender – 2016-08-28T10:34:45.717

@MartinEnder Yes – TuxCrafting – 2016-08-28T10:38:29.370

Oh, it's in the last test case. Might be worth mentioning explicitly. – Martin Ender – 2016-08-28T10:40:11.550

Will the : always be reached from the left or could it be reached from the top or bottom as well? In other words could there be characters other than # or : in the last column? – Martin Ender – 2016-08-28T10:53:07.123

@MartinEnder : and # will always be reached from the left – TuxCrafting – 2016-08-28T11:01:21.523

Are the letters required to be in the left column? – feersum – 2016-08-28T11:47:30.623

@feersum Yes they are – TuxCrafting – 2016-08-28T11:53:18.943

1SILOS answer please? – Rohan Jhunjhunwala – 2016-08-28T17:07:42.890

May I assume an input that is space padded so it forms a rectangle (all lines have equal length) ? May I assume # and : are always on the last column ? May I assume that the letters are always in the first column ? May I assume that the starts/goals are the only things on the last/first column (except spaces) – Ton Hospel – 2016-08-29T09:09:30.260

@TonHospel 1) No 2) 3) 4) Yes – TuxCrafting – 2016-08-29T09:10:52.640

Answers

14

Slip, 47 bytes

`a(?,[`-+]*((`/<|`\>)[`|+]*(`/>|`\<)[`-+]*)*`:)

Test it here.

Yay for undocumented features...

Explanation

Slip is basically a two dimensional regex syntax and by default Slip programs print the subset of the input that they matched. In this case I'm simply matching a valid path. To prevent printing the entire path, I'm usng the undocumented (?,...) groups which simply indicate that the characters matched inside should be omitted from the output.

As for the regex, unfortunately, there's some duplication because \ and / need to be treated differently depending on whether we're moving horizontally or vertically. On the plus side, since we know that the path starts and ends horizontally, we know that there's an even number of \ or / in every path, so that we can match two of them at a time.

`a             # Match a letter.
(?,            # Match but don't include in output...
  [`-+]*       #   Match a horizontal piece of path, consisting of - or +.
  (            #   Match 0 or more vertical segments...
    (`/<|`\>)  #     Match a / and turn left, or a \ and turn right.
    [`|+]*     #     Match a vertical piece of path, consisting of | or +.
    (`/>|`\<)  #     Match a / and turn right, or a \ and turn left.
    [`-+]*     #     Match a horizontal piece of path, consisting of - or +.
  )*
  `:           #   Match a : to ensure that this is the correct path.
)

Martin Ender

Posted 2016-08-28T10:31:28.783

Reputation: 184 808

9+1 for happy code :) – betseg – 2016-08-28T11:10:02.050

6

Python, 221 bytes

def P(s,c=""):
 l=s.split("\n")
 v=[0,-1]
 p=[(i,l[i].index(":"))for i in range(len(l))if":"in l[i]][0]
 while c in"-:|+/\\":
    p=map(sum,zip(p,v))
    c=l[p[0]][p[1]]
    v=v[::1-(c=="\\")*2]
    if"/"==c:v=[-v[1],-v[0]]
 return c

The first indention is just one space, in the while loop it's a tab.

Loovjo

Posted 2016-08-28T10:31:28.783

Reputation: 7 357

2

Javascript (ES6), 117 104 bytes

p=>(r=d=>(c="\\/ABCD".indexOf(p[x+=[-1,-w,w,1][d]])+1)>2?p[x]:r(d^c))(0,w=p.indexOf`
`+1,x=p.indexOf`:`)

Test cases:

let f =
p=>(r=d=>(c="\\/ABCD".indexOf(p[x+=[-1,-w,w,1][d]])+1)>2?p[x]:r(d^c))(0,w=p.indexOf`
`+1,x=p.indexOf`:`)

var p0 = 'A------#\nB------#\nC------#\nD------:',
    p1 = 'A-\\ /---:\nB-+-/ /-#\nC-+---+-#\nD-+---/  \n  \\-----#',
    p2 = '  /-\\    \nA-+\\\\---#\nB-/\\-\\/-#\nC----++-#\nD----+/  \n     \\--:',
    p3 = 'A-\\        \nB-+\\       \nC-++\\/----#\nD-+++//---:\n  \\++-//--#\n   \\+--//-#\n    \\---/  ',
    p4 = '  /-\\     \nA-+-/-\\   \nB-+-+-\\--#\nC-+-/ |/-#\nD-\\---++-#\n  \\---+/  \n      \\--:';

console.log(p0, '=>', f(p0));
console.log(p1, '=>', f(p1));
console.log(p2, '=>', f(p2));
console.log(p3, '=>', f(p3));
console.log(p4, '=>', f(p4));

Arnauld

Posted 2016-08-28T10:31:28.783

Reputation: 111 334

1

Ruby, 140 bytes

->s{(?A..?D).find{|l,c|x=h=1
v=0
y=s[/.*#{l}/m].count$/
(v,h=c==?/?[-h,-v]:c==?\\?[h,v]:[v,h]
y+=v
x+=h)until(c=s.lines[y][x])=~/(:)|#/
$1}}

Try it on repl.it: https://repl.it/CyJv

Ungolfed

->s{
  (?A..?D).find {|l,c|
    x = h = 1
    v = 0
    y = s[/.*#{l}/m].count $/

    ( v, h = c == ?/ ? [-h,-v] : c == ?\\ ? [h,v] : [v,h]
      y += v
      x += h
    ) until (c = s.lines[y][x]) =~ /(:)|#/

    $1
  }
}

Jordan

Posted 2016-08-28T10:31:28.783

Reputation: 5 001

0

Perl 211 Bytes

sub f{for($s=-1;++$s<~~@_;){if($_[$s][0]ne' '){$r=$s;$c=$m=0;$n=1;while($_[$r][$c]ne'#'){if($_[$r][$c]eq':'){return$_[$s][0];}($m,$n)=$_[$r][$c]eq'/'?(-$n,-$m):$_[$r][$c]eq'\\'?($n,$m):($m,$n);$r+=$m;$c+=$n;}}}}

Ungolfed:

sub q{
    for($start = -1; ++$start <~~@_;) {
        if($_[$start][0] ne ' ') {
            $row = $start;
            $col = $rowMove = 0;
            $colMove = 1;
            while($_[$row][$col] ne '#') {
                if($_[$row][$col] eq ':') {
                    return $_[$start][0];
                }
                ($rowMove, $colMove) =  $_[$row][$col] eq '/' ? (-$colMove,-$rowMove) : 
                                        $_[$row][$col] eq '\\' ? ($colMove,$rowMove) : 
                                        ($rowMove, $colMove);
                $row += $rowMove;
                $col += $colMove;
            }
        }
    }
}

This is my first Perl golf, so suggestions are welcome :)

Riley

Posted 2016-08-28T10:31:28.783

Reputation: 11 345