Perl, 647
Este es mi primer intento en el código de golf, y estoy un poco avergonzado de que ni siquiera supere el puntaje de C #, pero pensé que sería interesante (o divertido, o simplemente masoquista) hacer todo esto como un serie de sustituciones de expresiones regulares. (También pensé que sería divertido repasar mi Perl, pero al final lamentaba profundamente no haberlo implementado en Ruby o Python).
No he hecho muchas pruebas, pero creo que debería manejar todos los casos.
La cuadrícula se ingresa a través de STDIN. Debe haber al menos una nueva línea en la entrada (es decir, una sola fila sin una nueva línea no funcionará).
%s=(d,'[|+#$vk%ZX]',u,'[|+#$^W%KX]',r,'[-G+#>k%KX]',l,'[-G+#<W%ZX]');%o=(d,'[-.*G/k\\\\Z',u,'[-.*G/W\\\\K',r,'[|.*$\\\\/kK',l,'[|.*$\\\\/ZW');for$d(d,u,r,l){$o{$d}.='123456789qwertyuio]'}%u=(d,'.|-+*$G#/Wk%\KZX',u,'.|-+*$G#/kW%\ZKX',r,'.-|+*G$#/Wk%\ZKX',l,'.-|+*G$#/kW%\KZX');@q=split//,"qwertyuio";local$/;$_=<STDIN>;for$i(1..9){$m{$i}=$q[$i-1];$m{$m{$i}}=$i;s/$i/$m{$i}/e}/.*?\n/;$l='.'x((length$&)-1);do{$c=0;for$d(d,u,r,l){%p=(d,"(?<=$s{d}$l)$o{d}",u,"$o{u}(?=$l$s{u})",r,"(?<=$s{r})$o{r}",l,"$o{l}(?=$s{l})");%h=split//,$u{$d};$c+=s!$p{$d}!$h{$&}||($v=$&,($o{$d}=~s/$v// && $s{$d}=~s/]/$m{$v}]/),$v)!es}}while($c);print/\*/?"False\n":"True\n"
Explicación: el código actualiza iterativamente la cadena de la cuadrícula a medida que los láseres pasan a través de ella. -representa un láser horizontal, |un láser vertical, láser +cruzado, Kun \espejo con un láser que rebota en la parte superior, kun /espejo con un láser que rebota en la parte inferior, Zun \espejo con un láser que rebota en la parte inferior y Wun /espejo con un láser que rebota la parte superior. %es un /espejo con láser en ambos lados, mientras que Xes un \espejo con láser en ambos lados. (Estos distinguen entre mayúsculas y minúsculas. Intenté elegir letras que parezcan algo apropiadas, por ejemplo, kyKson opciones algo obvias, pero desafortunadamente el efecto realmente no es tan útil. Realmente debería poner esta información en una tabla, pero estoy agotado en este momento).
El manejo de los portales de la misma manera (es decir, asignar a cada dígito un conjunto de caracteres adicionales en función de las posibles posiciones del láser de entrada / salida) requeriría 144 caracteres (incluido el 9 original), por lo tanto, cuando un láser golpea un portal de "entrada", Agrego el carácter del portal de "salida" al conjunto de caracteres que emiten un láser en la dirección correcta. (Esto requiere diferenciar entre los portales de entrada y salida; usé las letras qwertyuiopara esto).
Algo inexperto, con declaraciones impresas para que pueda ver las sustituciones que suceden (cada sustitución representa una "ronda" de progresión láser), y con la gbandera agregada al principal s///para que no tome tantas iteraciones:
# Throughout, d,u,r,l represents lasers going down, up, left, or right
# `sources` are the character classes representing laser "sources" (i.e. any
# character that can, on the next round, cause a laser to enter the space
# immediately adjacent to it in the proper direction)
%sources=(d,'[|+#$vk%ZX]',u,'[|+#$^W%KX]',r,'[-G+#>k%KX]',l,'[-G+#<W%ZX]');
# `open` characters will not block a laser
%open=(d,'[-.*G/k\\\\Z',u,'[-.*G/W\\\\K',r,'[|.*$\\\\/kK',l,'[|.*$\\\\/ZW');
# One of each portal is changed into the corresponding letter in `qwertyuio`.
# At the start, each portal is 'open' and none of them is a source.
for$d(d,u,r,l){$open{$d}.='123456789qwertyuio]'}
# A mapping of 'open' characters to the characters they become when a laser
# goes through them. (This is used like a hash of hashes; see the assignment
# of `%h` below.)
%update=(d,'.|-+*$G#/Wk%\KZX',
u,'.|-+*$G#/kW%\ZKX',
r,'.-|+*G$#/Wk%\ZKX',
l,'.-|+*G$#/kW%\KZX');
@q=split//,"qwertyuio";
local$/;$_=<STDIN>;
for$i(1..9){
$m{$i}=$q[$i-1];
$m{$m{$i}}=$i;
s/$i/$m{$i}/e}
print "After substituting portals:\n";
print;
print "\n";
# Find the number of characters in each line and create a string of `.`'s,
# which will be used to correlate characters above/below one another in the
# grid with each other.
/.*?\n/;
$l='.'x((length$&)-1);
do{
$changes=0;
for$d(d,u,r,l){
# `patterns` is a mapping from each direction to the regex representing
# an update that must occur (i.e. a place where a laser must progress).
# Each pattern is either a lookahead or lookbehind plus the necessary
# "open" character class.
%patterns=(d,"(?<=$sources{d}$l)$open{d}",
u,"$open{u}(?=$l$sources{u})",
r,"(?<=$sources{r})$open{r}",
l,"$open{l}(?=$sources{l})");
%h=split//,$update{$d};
# Match against the pattern for each direction. Note whether any
# matches were found.
$changes+=s!$patterns{$d}!
# If the "open" character for a map is in the `update` map, return
# the corresponding value. Otherwise, the "open" character is a
# portal.
$h{$&} || ($v=$&,
# For portals, remove the input portal from the
# proper "open" list and add the output portal to
# the proper "source" list.
($open{$d}=~s/$v// && $sources{$d}=~s/]/$m{$v}]/),
$v)
# This whole substitution should allow `.` to match
# newlines (see the definition of `$l` above), and the
# replacement must be an expression rather than a string
# to facilitate the portal logic. The `g` allows multiple
# updates per "frame"; it is left out of the golfed code.
!egs
}
# Print the next "frame".
print;
print "\n";
# Continue updating until no "open" spaces are found.
}while($changes);
# Print whether `*` is still present in the input.
print/\*/?"False\n":"True\n"