पर्ल, 147 बाइट्स (गैर प्रतिस्पर्धा, प्रति सेकंड 10 सेकंड से अधिक समय लगता है)
के लिए +4 शामिल है -0p
कार्यक्रम खेलता है X। यह एक आदर्श खेल खेलेंगे।
STDIN पर बोर्ड इनपुट करें, उदाहरण के लिए:
tictaclatin.pl
-X-O
-X--
X-X-
O--O
^D
Ouptut एक ही बोर्ड होगा, जिसकी Xजगह सभी Oऔर इसके विपरीत होंगे। खाली स्थान एक संख्या से भरा होगा जो परिणाम का संकेत देगा यदि X वहां खेलता है, 1जिसका अर्थ है कि परिणाम एक जीत, 2एक ड्रॉ और 3एक नुकसान होगा। एक समाप्त खेल उलटे रंगों के साथ एक ही स्थिति देता है।
इस उदाहरण में आउटपुट होगा:
1O1X
1O33
O3O3
X33X
Xयदि वह शीर्ष और बाईं ओर 3 स्थानों में खेलता है तो स्थिति उसके लिए एक जीत है । अन्य सभी चालें हार जाती हैं।
यह भ्रामक आउटपुट वास्तव में सुविधाजनक है यदि आप जानना चाहते हैं कि एक कदम के बाद खेल कैसे जारी है। चूंकि कार्यक्रम हमेशा खेलता है, Xआपको स्वैप करना है Xऔर Oइसके लिए चालें देखना है O। उदाहरण के लिए यह बहुत स्पष्ट है कि Xशीर्ष बाएं में खेलकर जीतता है, लेकिन Xशीर्ष के साथ तीसरे स्थान पर खेलने पर क्या होगा ? बस आउटपुट को कॉपी करें, Oआपके द्वारा चुनी गई चाल के स्थान पर और -फिर से सभी अन्य नंबरों को प्रतिस्थापित करें, इसलिए यहां:
-OOX
-O--
O-O-
X--X
जिसके परिणामस्वरूप:
3XXO
3X33
X3X3
O33O
जाहिर है कि हर कदम Oको हारना चाहिए, इसलिए अगर वह शीर्ष पर रहे तो वह कैसे हारेंगे? फिर Oसे ऊपर बाईं ओर रखकर और अंकों को बदलकर ऐसा करें -:
OXXO
-X--
X-X-
O--O
देते हुए:
XOOX
1O33
O3O3
X33X
तो X के पास अपनी जीत के लिए जाने का एक ही तरीका है:
XOOX
OO--
O-O-
X--X
देते हुए
OXXO
XX33
X3X3
O33O
के लिए स्थिति Oनिराशाजनक बनी हुई है। अब यह देखना आसान है कि हर कदम Xतुरंत जीतने की अनुमति देता है। चलो कम से कम एक पंक्ति में 3 हे के लिए जाने की कोशिश करें:
OXXO
XX--
X-X-
O-OO
देते हुए:
XOOX
OO13
O3O3
X3XX
Xकेवल जीतने वाला कदम निभाता है (ध्यान दें कि यह XXXOतीसरे स्तंभ के साथ आता है :
XOOX
OOO-
O-O-
X-XX
यहाँ उत्पादन है:
OXXO
XXX-
X-X-
O-OO
क्योंकि खेल पहले ही समाप्त हो चुका था। आप तीसरे कॉलम पर जीत देख सकते हैं।
वास्तविक कार्यक्रम tictaclatin.pl:
#!/usr/bin/perl -0p
y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/sx;$@<=>0||s%-%$_="$`O$'";$$_||=2+do$0%eg&&(/1/||/2/-1)
रिक्त बोर्ड पर लागू यह 9506699 पदों का मूल्यांकन करता है जो मेरे कंप्यूटर पर 30 जीबी और 41 मिनट लगते हैं। परिणाम है:
2222
2222
2222
2222
इसलिए हर शुरुआती कदम ड्रॉ होता है। तो खेल एक ड्रा है।
चरम मेमोरी उपयोग ज्यादातर रिकर्सियन का उपयोग करने के कारण होता है do$0। एक सादे फ़ंक्शन का उपयोग करके इस 154 बाइट संस्करण का उपयोग करने के लिए 3Gb और 11 मिनट की आवश्यकता होती है:
#!/usr/bin/perl -0p
sub f{y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/sx;$@<=>0||s%-%$_="$`O$'";$$_||=2+&f%eeg&&(/1/||/2/-1)}f
जो अधिक मुस्कराता है (लेकिन अभी भी बहुत कुछ है, कुछ अभी भी स्मृति लीक होना चाहिए)।
कई स्पीडअप के संयोजन से यह 160 बाइट संस्करण (5028168 स्थिति, 4 मिनट और खाली बोर्ड के लिए 800M) हो जाता है:
#!/usr/bin/perl -0p
sub f{y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/osx;$@<=>0||s%-%$_="$`O$'";$a{$_}//=&f+1or return 1%eeg&&/1/-1}f
कि 0एक जीत के लिए पिछले एक का उपयोग करता है (एक साथ भ्रमित नहीं O), 1एक ड्रॉ के लिए और 2एक नुकसान के लिए। इस एक का उत्पादन भी अधिक भ्रामक है। यह रंग स्वैप के बिना एक जीत के मामले में एक्स के लिए जीतने की चाल में भरता है, लेकिन अगर इनपुट गेम पहले ही जीता गया था, तब भी रंग स्वैप नहीं करता है और किसी भी चाल में नहीं भरता है।
बेशक सभी संस्करण तेज़ हो जाते हैं और कम मेमोरी का उपयोग करते हैं क्योंकि बोर्ड भरता है। जैसे ही 2 या 3 मूव किए गए, तेज़ संस्करणों को 10 सेकंड से कम समय में एक चाल उत्पन्न करनी चाहिए।
सिद्धांत रूप में यह 146 बाइट संस्करण भी काम करना चाहिए:
#!/usr/bin/perl -0p
y/XO/OX/,$@=-$@while/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^/sx,--$|;$@<=>0||s%-%$_="$`O$'";$$_||=2+do$0%eg&&(/1/||/2/-1)
लेकिन मेरी मशीन पर यह एक पर्ल बग को ट्रिगर करता है और कोर को डंप करता है।
सभी संस्करण सिद्धांत रूप में अभी भी काम करेंगे यदि 6 बाइट स्थिति कैशिंग द्वारा किया गया $$_||=हटा दिया जाता है, लेकिन यह इतना समय और मेमोरी का उपयोग करता है कि यह केवल लगभग भरे हुए बोर्डों के लिए काम करता है। लेकिन सिद्धांत रूप में कम से कम मेरे पास 140 बाइट समाधान है।
आप डाल दिया $\=बस से पहले: (3 बाइट्स लागत) $@<=>0: उसके बाद प्रत्येक उत्पादन बोर्ड पूरे बोर्ड की स्थिति के बाद किया जाएगा 1के लिए Xजीत, 0ड्रॉ के लिए और -1कम करने के लिए।
यहाँ एक इंटरेक्टिव ड्राइवर है जो ऊपर बताए गए सबसे तेज़ संस्करण पर आधारित है। गेम खत्म होने पर ड्राइवर के पास कोई तर्क नहीं है इसलिए आपको खुद को रोकना होगा। गोल्फ कोड हालांकि जानता है। अगर सुझाए गए कदम के साथ -कुछ भी नहीं बदला है तो खेल खत्म हो जाता है।
#!/usr/bin/perl
sub f{
if ($p++ % 100000 == 0) {
local $| = 1;
print ".";
}
y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/osx;$@<=>0||s%-%$_="$`O$'";$a{$_}//=&f+1or return 1%eeg&&/1/-1}
# Driver
my $tomove = "X";
my $move = 0;
@board = ("----\n") x 4;
while (1) {
print "Current board after move $move ($tomove to move):\n ABCD\n";
for my $i (1..4) {
print "$i $board[$i-1]";
}
print "Enter a move like B4, PASS (not a valid move, just for setup) or just press enter to let the program make suggestions\n";
my $input = <> // exit;
if ($input eq "\n") {
$_ = join "", @board;
tr/OX/XO/ if $tomove eq "O";
$p = 0;
$@="";
%a = ();
my $start = time();
my $result = f;
if ($result == 1) {
tr/OX/XO/ if $tomove eq "O";
tr/012/-/;
} else {
tr/OX/XO/ if $tomove eq "X";
tr/012/123/;
}
$result = -$result if $tomove eq "O";
my $period = time() - $start;
print "\nSuggested moves (evaluated $p positions in $period seconds, predicted result for X: $result):\n$_";
redo;
} elsif ($input =~ /^pass$/i) {
# Do nothing
} elsif (my ($x, $y) = $input =~ /^([A-D])([1-4])$/) {
$x = ord($x) - ord("A");
--$y;
my $ch = substr($board[$y],$x, 1);
if ($ch ne "-") {
print "Position already has $ch. Try again\n";
redo;
}
substr($board[$y],$x, 1) = $tomove;
} else {
print "Cannot parse move. Try again\n";
redo;
}
$tomove =~ tr/OX/XO/;
++$move;
}