Encuentra el camino correcto

13

Dada una lista de rutas, genera la ruta correcta.

Ejemplo de ruta:

    /\
----+/
    |
  • -y |son caminos horizontales y verticales.
  • /y \son 90 ° vueltas.
  • +se trata como a -o como |dependiente de la dirección actual.

Las rutas pueden ir en cualquier dirección y un personaje puede usarse en múltiples rutas.

La entrada será así:

       /--\
A------+--+--#
B------/  \--:
C------------#
D------------#
  • A, B, CY Dson aperturas de ruta
  • # es un muro (el camino es malo)
  • : es el final (el camino es correcto)

Así que aquí estará la salida B.

Puedes asumir:

  • :y #siempre se alcanzará desde la izquierda.
  • El personaje a la derecha del inicio de una ruta siempre será -.
  • Los caminos siempre estarán bien formados.
  • #y :siempre estará en la misma columna.
  • Siempre habrá solo uno :y 4 caminos.

Casos de prueba

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

Como se trata de , gana la respuesta más corta.

TuxCrafting
fuente
¿Habrá alguna vez dos caminos incidentes en el mismo /o \?
Martin Ender
@MartinEnder Sí
TuxCrafting
Oh, está en el último caso de prueba. Vale la pena mencionarlo explícitamente.
Martin Ender
¿ :Se alcanzará siempre desde la izquierda o también se podría llegar desde arriba o abajo? En otras palabras, ¿podría haber caracteres distintos #o :en la última columna?
Martin Ender
1
SILOS respuesta por favor?
Rohan Jhunjhunwala

Respuestas:

14

Slip , 47 bytes

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

Pruébalo aquí.

Yay para características indocumentadas ...

Explicación

Slip es básicamente una sintaxis de expresiones regulares bidimensionales y, por defecto, los programas Slip imprimen el subconjunto de la entrada que coinciden. En este caso, simplemente estoy haciendo coincidir una ruta válida. Para evitar imprimir toda la ruta, estoy usando los (?,...)grupos no documentados que simplemente indican que los caracteres coincidentes en el interior deben omitirse de la salida.

En cuanto a la expresión regular, desafortunadamente, hay cierta duplicación porque \y /debe tratarse de manera diferente dependiendo de si nos estamos moviendo horizontal o verticalmente. En el lado positivo, dado que sabemos que el camino comienza y termina horizontalmente, sabemos que hay un número par \o /en cada camino, por lo que podemos hacer coincidir dos de ellos a la vez.

`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
fuente
99
+1 para código feliz:)
betseg
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

La primera sangría es solo un espacio, en el bucle while es una pestaña.

Loovjo
fuente
2

Javascript (ES6), 117104 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`:`)

Casos de prueba:

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
fuente
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}}

Pruébelo en repl.it: https://repl.it/CyJv

Sin golf

->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
  }
}
Jordán
fuente
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;}}}}

Sin golf:

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;
            }
        }
    }
}

Este es mi primer golf de Perl, así que las sugerencias son bienvenidas :)

Riley
fuente