Perl, 647
Bu benim ilk kez kod-golf denemem ve biraz utandım C # puanı bile geçmedim, ama her şeyi bir şey gibi yapmanın ilginç (veya eğlenceli veya sadece mazoşist) olacağını düşündüm. regex ikameleri dizisi. (Perl'i tazelemenin eğlenceli olacağını düşündüm, ama sonunda Ruby veya Python'da uygulamadığıma pişman oldum.)
Çok fazla test yapmadım, ama sanırım her durumda halletmesi gerektiğini .
Şebeke STDIN üzerinden girilir. Girişte en az bir yeni satır olmalı (örn. Yeni satır olmadan tek satır çalışmayacaktır).
%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"
Açıklama: Kod, lazerlerin içinden geçen ızgara dizgisini yinelemeli olarak günceller. -
yatay lazer temsil eder, |
dikey bir lazer, +
çapraz lazerler, K
bir \
lazer üst, çarparak ayna k
, bir /
lazer alt, çarparak ayna Z
, bir \
alt sıçrayan bir lazerle aynası ve W
bir /
lazer çarparak ayna üst. %
Bir olduğu /
süre, her iki tarafta lazerlerle ayna X
bir olan \
her iki tarafta lazerlerle ayna. (Bunlar büyük / küçük harfe duyarlıdır. Biraz uygun görünen mektuplar seçmeye çalıştım - örneğin k
veK
biraz belirgin seçimlerdir - ancak ne yazık ki etkisi gerçekten o kadar da yardımcı değil. Bu bilgiyi gerçekten bir tabloya koymalıyım ama şu anda çok yoruldum.)
Portalların aynı şekilde kullanılması (yani her bir basamağa, olası giriş / çıkış lazer konumlarına bağlı olarak ekstra karakter kümesinin atanması), 144 karakter (orijinal 9 dahil), yani bir lazer bir "giriş" portalına çarptığında, "Çıkış" portal karakterini, doğru yönde bir lazer yayan karakter kümesine ekliyorum. (Bu, giriş ve çıkış portalları arasında ayrım yapılmasını gerektirir; bunun için harfleri kullandım qwertyuio
.)
Biraz golf oynamayı bıraktığımda, baskı ifadeleriyle, yerine geçenleri görebiliyorsunuz (her bir ikame lazerin ilerlemesinin bir "turunu temsil ediyor)" ve anaya g
eklenen bayrak s///
çok fazla yineleme yapmaz.
# 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"