पर्ल, 647
कोड-गोल्फ में यह मेरा पहला प्रयास है, और मैं थोड़ा शर्मिंदा हूं कि मैंने सी # स्कोर को भी नहीं हराया, लेकिन मुझे लगा कि यह दिलचस्प होगा (या मजेदार, या सिर्फ मर्दाना) पूरी बात को एक के रूप में करना रेगेक्स प्रतिस्थापन की श्रृंखला। (मैंने यह भी सोचा कि मेरे पर्ल पर ब्रश करना मजेदार होगा, लेकिन अंत तक मुझे रूबी या पायथन में इसे लागू नहीं करने का गहरा अफसोस था।)
मैंने बहुत परीक्षण नहीं किया है, लेकिन मुझे लगता है कि इसे हर मामले को संभालना चाहिए।
ग्रिड STDIN के माध्यम से इनपुट है। इनपुट में कम से कम एक न्यूलाइन होनी चाहिए (यानी न्यूलाइन के बिना एक ही पंक्ति काम नहीं करेगी)।
%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"
स्पष्टीकरण: कोड पुनरावृत्ति ग्रिड स्ट्रिंग को अद्यतन करता है क्योंकि लेजर इसके माध्यम से गुजरता है। -एक क्षैतिज लेजर, का प्रतिनिधित्व करता है |एक ऊर्ध्वाधर लेजर, +पार लेजर, Kएक \एक लेजर शीर्ष, से बाउंस के साथ दर्पण kएक /एक लेजर नीचे, बंद उछल साथ दर्पण Zएक \एक लेजर दूर नीचे उछल साथ दर्पण, और Wएक /दर्पण एक लेजर से बाउंस के साथ शिखर। %एक है /, जबकि, दोनों पक्षों पर लेज़रों के साथ दर्पण Xएक है \दोनों पक्षों पर लेज़रों के साथ दर्पण। (ये मामला संवेदनशील है। मैंने उन पत्रों को लेने की कोशिश की, जो कुछ हद तक उचित लगते हैं - उदाहरण के लिए, kऔरKकुछ हद तक स्पष्ट विकल्प हैं - लेकिन दुर्भाग्य से प्रभाव वास्तव में मददगार नहीं है। मुझे वास्तव में इस जानकारी को एक तालिका में रखना चाहिए, लेकिन मैं अभी समाप्त हो रहा हूं।)
उसी तरह से हैंडलिंग पोर्टल्स (यानी प्रत्येक अंक को संभावित इनपुट / आउटपुट लेजर पदों के आधार पर अतिरिक्त वर्णों का एक सेट सौंपने) को 144 अक्षरों (मूल 9 सहित) की आवश्यकता होगी, इसलिए, इसके बजाय, जब एक लेजर "इनपुट" पोर्टल को हिट करता है, मैं "आउटपुट" पोर्टल चरित्र को उन पात्रों के सेट में जोड़ता हूं जो उचित दिशा में लेजर का उत्सर्जन करते हैं। (यह इनपुट और आउटपुट पोर्टल्स के बीच अंतर करने की आवश्यकता है; मैंने इसके लिए अक्षरों का उपयोग किया है qwertyuio।)
थोड़े अन-गोल्फ, प्रिंट स्टेटमेंट के साथ, ताकि आप घटित होने वाली बारीकियों को देख सकें (प्रत्येक प्रतिस्थापन लेजर-प्रगति के एक "दौर" का प्रतिनिधित्व करता है), और gध्वज के साथ मुख्य जोड़ा जाता है s///ताकि यह बहुत सारे पुनरावृत्तियों को न ले:
# 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"