प्रोग्रामिंग Tetris ब्लॉक (सचमुच)


33

खेल में टेट्रिस , वहाँ ईंटों या के 7 प्रकार के होते हैं tetr मैं minoes , जो गणितीय रूप में जाना जाता tetr minoes क्योंकि वे सभी 4 वर्ग घटकों के साथ बना रहे हैं:

टेट्रिस ईंटें

I, J, L, O, S, T और Z नाम हैं, जो उनके अनुमानित आकार के अनुरूप हैं। 90 ° घूर्णन की गणना, कुल 19 अद्वितीय आकार हैं:

I
I
I
I

IIII

 J
 J
JJ

JJJ
  J

JJ
J
J

J
JJJ

L
L
LL

  L
LLL

LL
 L
 L

LLL
L

OO
OO

 SS
SS

S
SS
 S

TTT
 T

T
TT
T

 T
TTT

 T
TT
 T

ZZ
 ZZ

 Z
ZZ
Z

चुनौती

कोड का एक आयताकार ब्लॉक लिखें जो आधार खंड के रूप में कार्य करता है जो इन 19 आकृतियों से बना है। जब इस कोड को एक आकार में व्यवस्थित किया जाता है, तो एक प्रोग्राम का गठन किया जाना चाहिए जो उस आकृति से जुड़े एकल अपरकेस अक्षर को आउटपुट करता है। यह सभी 19 आकृतियों के लिए काम करना चाहिए।

19 आकारों में से कुछ में मौजूद प्रमुख खाली क्षेत्र पूरी तरह से रिक्त स्थान ( ) के साथ भरे हुए हैं । अनुगामी खाली क्षेत्र कुछ से भरा नहीं है (इसलिए कार्यक्रम हमेशा आयताकार नहीं होते हैं)।

उदाहरण

मान लीजिए कि यह आपका कोड ब्लॉक था:

ABC
123

तब एस टेट्रिस पीस में ब्लॉक की व्यवस्था एक प्रोग्राम होगा जो प्रिंट करता है S:

   ABCABC
   123123
ABCABC
123123

ABC
123
ABCABC
123123
   ABC
   123

(ध्यान दें कि सभी प्रमुख खाली स्थान अंतरिक्ष वर्णों से भरे हुए हैं, और यह कि कोई भी रेखाएं कोई अनुगामी स्थान नहीं हैं।)

एक ही विचार सभी 6 अन्य टुकड़ों और उनके संबंधित घुमावों पर लागू होता है।

टिप्पणियाँ

  • सभी 19 अंतिम कार्यक्रमों को एक ही प्रोग्रामिंग भाषा में चलाया जाना है।
  • यदि वांछित है, तो आप सभी कार्यक्रमों के लिए एक एकल अनुगामी न्यूलाइन जोड़ सकते हैं (न केवल कुछ, सभी या कोई नहीं)।
  • आपके कोड ब्लॉक में कोई भी अक्षर (रिक्त स्थान सहित) हो सकते हैं जो लाइन टर्मिनेटर नहीं हैं ।
  • एक वैकल्पिक अनुगामी न्यूलाइन के साथ स्टैडआउट (या आपकी भाषा के निकटतम विकल्प) को पत्र आउटपुट करें।

स्कोरिंग

सबमिशन जिसका कोड ब्लॉक में सबसे छोटा क्षेत्र (चौड़ाई गुना ऊंचाई) जीतता है। यह अनिवार्य रूप से सबसे छोटा कोड जीत का मतलब है, यही कारण है कि यह टैग है । टाईब्रेकर सबसे अधिक मतदान के जवाब में जाता है।

ABC\n123उदाहरण के क्षेत्र 3 × 2 = 6 है।

टुकड़ा

एक कोड ब्लॉक को देखते हुए, यह स्निपेट सभी 19 प्रोग्राम उत्पन्न करेगा:

<script>function drawShape(X,n,v){for(var t="",e=0;e<v.length;e++)for(var l=0;l<n.length;l++){for(var r=0;r<v[e].length;r++)t+="X"===v[e][r]?n[l]:X[l];t+="\n"}return t}function go(){var X=document.getElementById("input").value;if(0!=X.length){var n=X.replace(/./g," ").split("\n");X=X.split("\n");for(var v="I (v1):|I (v2):|J (v1):|J (v2):|J (v3):|J (v4):|L (v1):|L (v2):|L (v3):|L (v4):|O:|S (v1):|S (v2):|T (v1):|T (v2):|T (v3):|T (v4):|Z (v1):|Z (v2):".split("|"),t="X\nX\nX\nX|XXXX| X\n X\nXX|XXX\n  X|XX\nX\nX|X\nXXX|X\nX\nXX|  X\nXXX|XX\n X\n X|XXX\nX|XX\nXX| XX\nXX|X\nXX\n X|XXX\n X|X\nXX\nX| X\nXXX| X\nXX\n X|XX\n XX| X\nXX\nX".split("|"),e="",l=0;l<v.length;l++)e+=v[l]+"\n\n"+drawShape(n,X,t[l].split("\n"))+"\n";e=e.substring(0,e.length-2),document.getElementById("output").value=e}}</script><style>html *{font-family: monospace;}</style>Code Block:<br><textarea id='input' rows='8' cols='64'>ABC&#010;123</textarea><br><button type='button' onclick='go()'>Go</button><br><br>All 19 Programs:<br><textarea id='output' rows='24' cols='64'></textarea>


तो लंबाई-चौड़ाई का अनुपात 2 से 3 है? या यह कोई अन्य आकार हो सकता है? इसके अलावा, कार्यक्रम को कम से कम क्या करना है? मान लें कि खाली प्रोग्राम की गिनती नहीं है, लेकिन ऐसे प्रोग्राम जो आउटपुट कुछ नहीं करते हैं।
ASCIIThenANSI

@ASCIIThenANSI किसी भी चौड़ाई और ऊंचाई ठीक हैं। मुझे लगता है कि 2 * 3 से कुछ बड़ा होना आवश्यक होगा। 19 कार्यक्रम हैं, जो ब्लॉक के प्रत्येक व्यवस्था के लिए 19 अलग टेट्रोमिनो आकार में से एक है। जब उन प्रोग्रामों में से एक चलाया जाता है, तो यह संबंधित टेट्रिस पीस लेटर को आउटपुट करता है।
केल्विन के शौक

वाह! क्या कमाल की चुनौती है! क्या यह मायने रखता है कि हम किस भाषा का उपयोग करते हैं?
theonlygusti

@theonlygusti इस साइट पर लगभग सभी प्रश्न किसी भी भाषा की अनुमति देते हैं। यह कोई अपवाद नहीं है।
केल्विन के

@ केल्विन हॉबीज हाँ, मुझे पता है; मैंने जावास्क्रिप्ट-उत्तर को चलाने के लिए स्निपेट को एक नियंत्रक के रूप में गलत समझा। जाहिरा तौर पर यह सिर्फ कोड ब्लॉक की व्यवस्था करता है।
theonlygusti

जवाबों:


16

<> <(मछली) - १२ * ३२ = ३ )४

मैं एक और अधिक सुंदर समाधान के लिए जाने की योजना बना रहा था, लेकिन मैंने किसी तरह इसे समाप्त कर दिया, जो कि बहुत ही क्रूर है:

c  0  g84*%\
c2*0  g84*%\
0  84*g84*%\
c  84*g84*%\
c2*84*g84*%\
0  88*g84*%\
c  88*g84*%\
?v         \
;>?v~~?vv   
"L" o;  >   
"S" o; >~?v 
"T" o;    > 
;  >~?v"L"o 
;     >"J"o 
?v         \
 >~?v~~?vv  
"I"  o;  >  
"J"  o; >   
    \~~?vv  
"T"  o;  >  
"Z"  o; >   
?v         \
 >?v"J"o;   
   >?v"Z"o; 
"L"o;>?!v   
"J"o;   >?v 
"T"o;     > 
?v?v"I"o;  >
   >"L"o;   
 >?v"T"o;   
   >?v"O"o; 
     >"S"o; 

यह बहुत सरल है, यह पाठ के लिए एक 3x3 वर्ग में कोड की जांच करता है और यह देखने के लिए परिणामों का उपयोग करता है कि कौन सा tetrimino कोड के आकार से मेल खाता है। मैं इसे अभी तक गोल्फ के लिए बहुत प्रयास नहीं किया था।

यहाँ कोड आज़माएँ (स्निपेट का उपयोग करने के बाद इसे टेट्रीमिनो की तरह आकार देने के लिए)

यहाँ Z (v1) आकार में कोड का उदाहरण


14

C (gcc) , 26x20 = 520 25x19 = 475 23x17 = 391

#ifndef M            //
#define M(a,b)a##b   //
#define W(z,x)M(z,x) //
char*s,*S[]={"!!!!c",//
"8M !7! M8 878","77",//
"7!!MO887","788OM!!7"//
,"N7!78","7N87!"},r[5//
],*p=r;i=7;main(){for//
(;i--;)strstr(S[i],r)//
&&putchar("ITOJLSZ"[i//
]);}                 //
#endif               //
__attribute__((      //
constructor(__LINE__)//
))W(f,__LINE__)(){s= //
"                     \
";*p++=strlen(s)+12;}//

मुझे हाल ही में जीएनयू के फ़ंक्शन विशेषताओं के बारे में बताया गया था, और सबसे दिलचस्प constructorविशेषता यह थी, जो इस समस्या के लिए मेरे पहले के दृष्टिकोण में एक और अधिक गोलमटोल तरीके से जो मैं कर रहा था, उसके अधिक जटिल कार्यान्वयन के लिए अनुमति देता है।

विचार का जोर पहले की तरह ही है: एक स्ट्रिंग बनाएं और इसे सूची में खोजें ताकि यह पता लगाया जा सके कि किस कोड को ब्लॉक किया गया है। यह फ़ंक्शन को कॉल करके किया जाता है, प्रत्येक एक स्ट्रिंग में एक चरित्र जोड़ रहा है। जटिलता थी और बनी हुई है कि कार्यों की संख्या बदलती रहती है।

किसी फ़ंक्शन को परिभाषित करना attribute((constructor(x)))इसे बनाता है ताकि फ़ंक्शन को पहले main()दर्ज किया xजा सके , वैकल्पिक होने के साथ प्राथमिकता (कम इसका मतलब यह पहले चलाया जाता है)। यह फ़ंक्शन पॉइंटर्स की आवश्यकता को हटा देता है, जो हमें एक मैक्रो, कुछ घोषणाओं और कॉलिंग चेन को छोड़ने की अनुमति देता है।

__LINE__प्राथमिकता के लिए उपयोग करना iffy है, क्योंकि प्राथमिकता के स्तर 0-100 आरक्षित हैं। हालाँकि, यह त्रुटियों में परिणाम नहीं करता है, केवल चेतावनियाँ, और गोल्फ खेलते समय वे बहुत खुश होते हैं, इसलिए कुछ और क्या है?

यह प्राथमिकताओं का उपयोग नहीं करने के लिए एक और कॉलम बंद करने में मदद करेगा, लेकिन निष्पादन के क्रम को परिभाषित नहीं किया गया है। (वे इस मामले में उलट हैं, लेकिन अन्य परीक्षण अनिर्णायक हैं।)

यहाँ एल v2 का उदाहरण

पुराना, अधिक पोर्टेबल, दृष्टिकोण

#ifndef M              //
#define M(a,b) a##b    //
#define W(z,x)M(z,x)   //
#define F W(f,__LINE__)//
#define A W(a,__LINE__)//
char r[5],*S[]={"####k"//
,";<<US##;",";##SU<<;",//
";;",";T<;#","<S #;# S"//
"< <;<","T;#;<"},*s,*p=//
r;i;typedef(*T)();T a17//
,a36,a55,a74;main(){for//
(a17(),a36&&a36(),a55&&//
a55(),a74&&a74();i--;) //
strstr(S[i],r)&&putchar//
("ILJOZTS"[i]);}i=7;   //
#endif                 //
F();T A=F;F(){s=       //
"                       \
";*p++=strlen(s)+12;}  //

मेरी पसंदीदा समस्याओं में से एक मैंने इस साइट पर हल की है।

मुझे लगा कि प्रत्येक ब्लॉक किसी न किसी तरह से अपने स्वयं के निर्देशकों को विभाजित करेगा। पंक्तियों के साथ आसान है __LINE__, और एक क्षैतिज शाब्दिक की लंबाई का उपयोग करके क्षैतिज रूप से आसन्न ब्लॉकों की संख्या पाई जा सकती है, जैसे:

char*s=//char*s=//
"       ""       "
;        ;        

परिणामी स्ट्रिंग की लंबाई लें और एक उचित संख्या से विभाजित करें और आपके पास चौड़ाई है। अफसोस की बात है, इस विधि से ब्लॉक से पहले कोई भी खाली जगह अदृश्य है। मुझे अभी भी संदेह है कि स्ट्रिंग्स का समाधान होगा, क्योंकि व्हॉट्सएप का अर्थ स्ट्रिंग्स के बाहर बहुत ही कम है, a+++bबनाम जैसी चीजों में a+ ++b। मैंने संक्षेप में ऐसा कुछ माना, लेकिन कुछ उपयोगी नहीं आ सका। एक और संभावना यह है कि पहचानकर्ताओं को एक साथ "चिपके" होने दिया जाए जहां ब्लॉक मिले:

A  BA  B

मुझे आश्चर्य नहीं होगा अगर यह अभी भी एक दिलचस्प समाधान के लिए बना सकता है।

अपनी सादगी के बावजूद, मुझे स्ट्रिंग समाधान खोजने में काफी समय लगा, जो इस खंड खंड पर आधारित है:

s=//
"  \
";//

यदि फ़्रेग्मेंट का कोई क्षैतिज पड़ोसी नहीं है, तो दूसरी पंक्ति की न्यूलाइन बैकस्लैश द्वारा बच जाती है, जिससे लंबाई की एक स्ट्रिंग बन जाती है। 2. यदि, हालांकि, इसमें पड़ोसी है, तो बैकस्लैश इसके बजाय लाइन के शुरू होने पर क्वेश्चन मार्क से बच जाएगा। अगले ब्लॉक के 2:

s=//s=//
"  \"  \
";//";//

यह 5 की स्ट्रिंग "\" का निर्माण करेगा।

अधिक महत्वपूर्ण बात, यह ब्लॉक से पहले खाली जगह का पता लगाने के लिए भी अनुमति देता है:

    s=//
    "  \
    ";//

फिर से, नईलाइन बच जाती है, और बाईं ओर खाली ब्लॉक का व्हाट्सएप लंबाई 6 के परिणामी स्ट्रिंग "" में शामिल है।

कुल मिलाकर एक पंक्ति पर ब्लॉक के सात अलग-अलग विन्यास हैं जिनके बारे में हमें चिंता करने की ज़रूरत है, और वे सभी अद्वितीय लंबाई के तार बनाते हैं:

2 "  "
---
s=//
"  \
";//

5 "  \"  "
---
s=//s=//
"  \"  \
";//";//

6 "      "
---
    s=//
    "  \
    ";//

9 "  \"      "
----
    s=//s=//
    "  \"  \
    ";//";//

10 "          "
---
        s=//
        "  \
        ";//

8 "  \"  \"  "
---
s=//s=//s=//
"  \"  \"  \
";//";//";//

11 "  \"  \"  \"  "
----
s=//s=//s=//s=//
"  \"  \"  \"  \
";//";//";//";//

अंतिम ब्लॉकों में निश्चित रूप से इतनी कम लंबाई नहीं होगी, लेकिन सिद्धांत ब्लॉक आकार की परवाह किए बिना समान है। यह भी बोनस है कि चौड़ाई का पता लगाने के लिए एक अलग तंत्र अनावश्यक है। परिणाम स्ट्रिंग के लिए इस स्ट्रिंग की लंबाई के अनुरूप एक चरित्र जोड़कर, 19 कॉन्फ़िगरेशन में से प्रत्येक एक अद्वितीय स्ट्रिंग प्राप्त करता है, जिसे सभी ब्लॉक चलाने के बाद केवल एक उपयुक्त सूची की तुलना में आवश्यकता होती है।

एक बार यह हल हो जाने के बाद, अगली बड़ी समस्या यह थी कि ब्लॉकों की प्रत्येक पंक्ति को "कैसे" देखा जाए। सी में, हम बहुत सीमित हैं जो कार्यों के बाहर किया जा सकता है। हमें भी main()दिखाई देने की आवश्यकता है, लेकिन केवल एक बार। उत्तरार्द्ध आसानी से कुछ #defineएस द्वारा प्राप्त किया जाता है , लेकिन अगर हम चाहते हैं कि बाद के ब्लॉक का कोड अंदर हो main(), तो यह समस्या कैसे पता करें कि अंतिम समापन घुंघराले ब्रैकेट को कब रखा जाए। आखिरकार, हम नहीं जानते कि वास्तव में ब्लॉक की कितनी पंक्तियों का उपयोग किया जाएगा। इसलिए हमें main()स्थिर और किसी तरह बाकी को गतिशील होने की आवश्यकता है।

यदि अन्य ब्लॉक-पंक्तियों को स्व-समाहित किया जाना है, तो उन्हें कार्य करने की आवश्यकता है, लेकिन हमें यह सुनिश्चित करने की आवश्यकता है कि प्रत्येक फ़ंक्शन का एक नाम है जो अद्वितीय है, जबकि कॉल करने योग्य होने के लिए पर्याप्त रूप से अनुमानित भी है main()। हमें यह जानने के लिए भी एक तंत्र की आवश्यकता है कि कौन से कार्य वास्तव में कहलाने के लिए हैं। अद्वितीय नाम बनाना हेल्पर मैक्रोज़ द्वारा हल किया जाता है:

#define M(a,b) a##b     //
#define W(z,x)M(z,x)    //
#define F W(f,__LINE__) //
#define A W(a,__LINE__) //

कॉलिंग Fएक पहचानकर्ता बनाएगी जिसका नाम f से शुरू होता है और लाइन नंबर के साथ समाप्त होता है। Aऐसा ही करता है, लेकिन एक उपसर्ग के साथ, जिसका उपयोग समाधान के दूसरे भाग के लिए किया जाता है, जो फ़ंक्शन पॉइंटर्स है। हम चार ऐसे संकेत देते हैं:

typedef(*T)();T a17,a36,a55,a74;

चूंकि इन्हें वैश्विक चर के रूप में घोषित किया गया है, इसलिए इन्हें आसानी से NULL में सेट कर दिया गया है। बाद में, प्रत्येक ब्लॉक-पंक्ति में निम्नलिखित कोड कोड होगा:

F();T A=F;F()

यह पहले एक फ़ंक्शन की घोषणा करेगा, उस फ़ंक्शन को इंगित करने के लिए उपयुक्त फ़ंक्शन पॉइंटर को परिभाषित करेगा (हम केवल ग्लोबल्स को एक बार परिभाषित कर सकते हैं, लेकिन पहले की घोषणा को परिभाषा के रूप में नहीं गिना गया था, भले ही यह NULL के लिए प्रारंभ हुआ हो), और फिर वास्तविक को परिभाषित करें। समारोह। यह main()किसी भी फ़ंक्शन पॉइंटर को कॉल करने की अनुमति देता है जो गैर-NULL (a17 कभी भी NULL नहीं होगा):

a17(),a36&&a36(),a55&&a55(),a74&&a74()

ऐसा करने से स्ट्रिंग का निर्माण होगा r, जिसे तब स्ट्रिंग की तालिका में देखा जाता है और यदि पाया जाता है, तो उपयुक्त अक्षर आउटपुट है।

केवल शेष चाल यह है कि जब भी अस्पष्टता से बचा जा सकता है, या अतिव्यापी तार को भ्रमित किया जा सकता है, तब मैच के लिए तार की सूची को छोटा कर दिया गया था।

यहाँ एल v2 का उदाहरण


6

x86 ओपकोड (.com), 86 82 बाइट्स

परीक्षक:

org 100h
macro e {
db $F6,$04,$DF,$78,$13,$75,$08,$00,$C0,$40,$83,$C6,$52,$EB,$F1,$88
db $C2,$00,$D0,$00,$D0,$46,$EB,$E8,$05,$02,$40,$73,$ED,$E8,$26,$00
db $50,$08,$43,$4D,$2C,$0C,$1C,$15,$A5,$14,$10,$13,$3F,$27,$20,$0F
db $51,$1D,$29,$49,$49,$4A,$4A,$4A,$4A,$4C,$4C,$4C,$4C,$4F,$53,$53
db $54,$54,$54,$54,$5A,$5A,$5F,$AE,$75,$FD,$8A,$55,$12,$B4,$02,$CD
db $21,$C3
}

macro n { db 82 dup $20 }

macro s { db 10 }

n
e
s
n
e
s
e
e  

स्रोत:

BOF:    ;mov bx, 100h
p:      test [si], byte $DF
        js _a ; exist
        jnz _b ; newline
_z:     add al, al
        inc ax
q:      add si, EOF-BOF
        jmp p
_b:     mov dl, al
        add al, dl
        add al, dl
        inc si
        jmp p
_a:     add ax, 4002h
        jnc q
        call y
        db 80,8,67,77,44,12,28,21,165,20,16,19,63,39,32,15,81,29,41
        db 'IIJJJJLLLLOSSTTTTZZ'
y:      pop di
        scasb
        jnz y+1
        mov dl,[di+18]
        mov ah,2
        int $21
        ret
EOF:

Win7dos में चलाएँ जहाँ init AX = 0, SI = 100, BX = 0 संदर्भ है


यदि आप कुछ हद तक समर्थित वातावरणों की संख्या को कम करने में सहज हैं, तो आप SI = 100 h मान सकते हैं और उस रजिस्टर को BX के बजाय अनुक्रमित करने के लिए उपयोग कर सकते हैं mov bx, 100h, जिससे प्रारंभ में 3 बाइट्स बचाए जा सकें।
गैस्ट्रोपनर

@gastropner किया और एक बिंदु तय किया जहाँ मैंने नोटिस नहीं किया
l4m2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.