D tic tac toe जीत-चेकर के लिए एक n बनाएँ


13

N d tic tac toe गेम में कौन जीता है यह जाँचने के लिए सबसे छोटा प्रोग्राम बनाएं ।

आपका कार्यक्रम तब काम करना चाहिए जब n(चौड़ाई) और d(आयाम संख्या) इन सीमाओं में हो:

n∈[3,6]∩ℕ  ie a number from this list: 3,4,5,6
d∈[2,5]∩ℕ  ie a number from this list: 2,3,4,5

n = 3; d = 2(3 2 यानी 3 बाय 3):

[][][]
[][][]
[][][]

n = 3; d = 3(3 3 यानी 3 बाय 3 बाय 3):

[][][]
[][][]
[][][]

[][][]
[][][]
[][][]

[][][]
[][][]
[][][]

n = 6; d = 2(6 2 अर्थात 6 बाय 6):

[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]

और इसी तरह।

जीतना (यदि आपने पर्याप्त बहु-आयामी टिक टीएसी पैर की अंगुली खेली है, तो यह वही है।)

जीत हासिल करने के लिए, एक खिलाड़ी के पास एक पंक्ति के साथ सभी आसन्न वर्ग होने चाहिए। यही है, उस खिलाड़ी को nविजेता होने के लिए एक पंक्ति में आगे बढ़ना चाहिए ।

सटा हुआ:

  • प्रत्येक टाइल एक बिंदु है; उदाहरण के लिए (0,0,0,0,0) एक बिंदु हैd=5
  • आसन्न टाइलें ऐसी टाइलें हैं जैसे वे एक ही इकाई d- घन पर दोनों बिंदु हैं। दूसरे शब्दों में, टाइल्स के बीच चेबीशेव की दूरी 1 है।
  • दूसरे शब्दों में, यदि कोई बिंदु किसी बिंदु pसे सटा हुआ है q, तो प्रत्येक pएस में समन्वित qएक से अधिक नहीं द्वारा इससे भिन्न में समन्वयित होता है। इसके अतिरिक्त, कम से कम समन्वय जोड़ी पर बिल्कुल एक से भिन्न होता है।

लाइन्स:

  • लाइनों को वैक्टर और एक टाइल द्वारा परिभाषित किया गया है। एक पंक्ति समीकरण द्वारा मारा जाने वाला प्रत्येक टाइल है:p0 + t<some vector with the same number of coordinates as p0>

इनपुट :

इनपुट STDIN को होगा। इनपुट की पहली पंक्ति दो नंबर होगी, nऔर dफॉर्म में n,d

इसके बाद एक लाइन होगी जिसमें निर्देशांकों से युक्त चालों को निर्दिष्ट किया गया है। निर्देशांक को प्रपत्र में सूचीबद्ध किया जाएगा 1,1;2,2;3,3:। ऊपरी बाएं कोने की उत्पत्ति (2D के लिए 0,0) है। सामान्य स्थिति में, यह सूची ऐसी होगी 1,2,...,1,4;4,0,...,6,0;...जहां पहला नंबर बाएं-दाएं-नेस का प्रतिनिधित्व करता है, दूसरा अप-डाउन-नेस, तीसरा आयाम के माध्यम से तीसरा, आदि ध्यान दें कि पहला समन्वय Xपहली बारी है, दूसरा। है Oपहली बारी, ....

इनपुट के बाद एक नई लाइन होगी।

आउटपुट :

आउटपुट STDOUT को होगा। बस संकेत करें कि कौन जीता है अगर कोई जीता है, या यदि यह टाई है। यदि यह न तो एक टाई है और न ही एक जीत, कुछ भी उत्पादन नहीं है।

इसके अतिरिक्त, इंगित करें कि क्या कोई चाल क्लैश है, यानी यदि एक ही स्थान पर कम से कम दो चालें हैं।

यदि इनपुट समाप्त होने से पहले कोई जीत / ड्रा था, तो आपका प्रोग्राम जो चाहे कर सकता है।

परीक्षण के मामले (कोई भी किसी भी अधिक सुझाव देना चाहते हैं?):

इनपुट:

4,3
0,0,0;1,1,1;1,0,1;2,0,2;0,0,1;2,0,0;2,0,1;3,0,2;3,0,1

उदाहरण आउटपुट:

X wins

एक और संभावित आउटपुट (स्पष्टीकरण की आवश्यकता है):

1

आप आयामों की टोपोलॉजी को कैसे परिभाषित कर रहे हैं n> 3 यह निर्धारित करने के लिए कि एक विकर्ण के साथ एक सीधी रेखा क्या है? उदाहरण के लिए, क्या किसी भी 3 आसन्न कोने के माध्यम से कोई रेखा 3? बोर्ड पर एक जीत का गठन करती है? क्या प्रत्येक 3² प्लेन के मध्य वर्ग किसी दूसरे प्लेन के हर बिंदु से जुड़े होते हैं जो एन-क्यूब पर इसके साथ एक किनारा साझा करता है?
कॉमिन्टेन

1
@Comintern है कि कैसे (मैं शायद स्पष्टीकरण butchered। निश्चित रूप से सरल हो सकता है)।
जस्टिन

ध्यान दें: आपने आसन्न टाइलों के लिए जो परिभाषाएँ दी हैं, वे समतुल्य नहीं हैं (अर्थात यह मैनहट्टन की दूरी एक के बराबर नहीं है)।
हावर्ड

इसके अलावा आपको परिभाषित करना चाहिए कि यह nविजेता होने के लिए एक पंक्ति में कदम रखता है। (इन टिप्पणियों को सैंडबॉक्स में पोस्ट नहीं करने के लिए खेद है, लेकिन मेरे पास इसे देखने के लिए समय भी नहीं था क्योंकि यह सैंडबॉक्सिंग के तुरंत बाद पोस्ट किया गया था।)
हावर्ड

1
मुझे लगता है कि प्रोलॉग में एक बहुत छोटा समाधान होना चाहिए ...
नैट एल्ड्रेड

जवाबों:


3

अजगर, 745 578 वर्ण

import sys
x=[]
o=[]
t=1
b=","
k=map
def m(c):
 m=x if t else o
 c=k(int,c.split(b))
 if c in o+x:
  print b
  sys.exit()
 m.append(c)
 r=0
 for p in m:
  r=w(p,m)
 return r
def w(p,m):
 for q in m:
  d=max(k(lambda x,y:abs(x-y),p,q))
  if d==u:
   if e(p,q,m):
    return 1
 return 0
def e(p,q,m):
 v=k(lambda p,q:(p-q)/u,q,p)
 l=p
 for i in range(1,n):
  y=k(lambda j,h:j+h,l,v)
  if y not in m:
   return 0
  l=y
 if not l==q:
  return 0
 return 1
q=sys.stdin.readline
d=q()
v=q()
z=d.split(b)
(n,d)=k(int,z)
a=v.split(";")
u=n-1
for c in a:
 r=m(c)
 if r:
  print t
 t=not t

मैंने कुछ बदलाव किए और इसे काफी कम कर दिया। ध्यान दें कि True की वापसी का मतलब है कि x जीता है, झूठी का अर्थ है y जीता, और, का अर्थ है कि एक अमान्य कदम बनाया गया था।


कुछ चीजें: import *करने के लिए बदल जाते हैं import*1ट्रू के लिए उपयोग करें , और 0गलत (हटाने Tऔर F) के लिए। return -1हो सकता है return-1(रिक्त स्थान हटाने की जाँच करें)। एकल चार तरीकों में अपने तरीकों का नाम बदलें। अधिक अनुकूलन के लिए युक्तियाँ देखें ।
जस्टिन

ओह, धन्यवाद, मुझे नहीं पता था कि आप उन चीजों में से कुछ कर सकते हैं (अर्थात्, वापसी और -1 के बीच की जगह को हटा दें)
foota

मैंने आपके कोड पर थोड़ा सा गोल्फिंग किया (जो सभी मान्य नहीं हो सकता है)। परिणाम यहां है: ideone.com/Ld2jAH । कृपया अपने उत्तर के माध्यम से फिर से जाएं और कोड को जितना संभव हो उतना छोटा करें। सुझावों अजगर के लिए सवाल बहुत उपयोगी है
जस्टिन

@ फूटा आप if l<>q:इसके बजाय कर सकते हैं if not l==q:
mbomb007

3

उत्तर नहीं - जावा

मैं यह देखने के लिए उत्सुक था कि किसी दिए गए n को जीतने के लिए कितने अलग-अलग तरीके हैं, इसलिए मैंने उन सभी को सूचीबद्ध करने के लिए यह कोड लिखा।

import java.util.*;

public class MultiDTTT {
    static Set<Win> wins = new HashSet<Win>();
    static final int d = 3;
    static final int n = 3;
    static final char maxChar = (char)(n-1) + '0'; 

    public static void main(String[] args) throws Exception {
        String pad = "";
        for(int i=0; i<d; i++) pad = pad + "0";
        for(int i=0; i<Math.pow(n,d); i++) {
            String s = Integer.toString(i,n);
            s = pad.substring(s.length()) + s;
            buildWin(s,"",0);
        } 
        System.out.println(wins.size());
        for(Win w : wins) System.out.println(w.toString());
    }

    static void buildWin(String s, String p,int i) {
        if(i<d) {
            if(s.charAt(i) == '0') {
                buildWin(s,p+"u",i+1);
                buildWin(s,p+"s",i+1);
            }
            else if(s.charAt(i) == maxChar) {
                buildWin(s,p+"d",i+1);
                buildWin(s,p+"s",i+1);
            }
            else {
                buildWin(s,p+"s",i+1);
            }
        }
        else {
            if(p.contains("u") || p.contains("d")) wins.add(new Win(s,p));
        }
    }

    static class Win {
        String start;
        String pattern;
        Set<String> list = new HashSet<String>();

        Win(String s, String p) {
            start = s;
            pattern = p;
            char[] sc = s.toCharArray();
            for(int i=0; i<n; i++) {
                list.add(new String(sc));
                for(int j=0; j<d; j++) {
                    switch (p.charAt(j)) {
                        case 'u':
                            sc[j]++;
                            break;
                        case 'd':
                            sc[j]--;
                            break;
                        case 's':
                            break;
                    }
                }
            }
        }

        public String toString() {
            String s = ""; //start + ", " + pattern + "\n    ";
            for(String ss : list) s = s + ss + " ";
            return s;
        }

        public boolean equals(Object x) {
            return (x instanceof Win) && this.list.equals(((Win)x).list);
        }
        public int hashCode(){
            return list.hashCode();
        }
    }
}

मैंने इसे n, d = 2..3,2..3 पर हाथ से परीक्षण किया और यह काम करता प्रतीत होता है ... इसके बाद जीतने के संभावित तरीकों की संख्या नीचे दिखाए गए अनुसार तेज़ी से बढ़ती है:

n       1       2       3       4       5       6
d                           
1       1       1       1       1       1       1
2       1       6       8       10      12      14
3       1       28      49      76      109     148
4       1       120     272     520     888     1400
5       1       496     1441    3376    6841    12496
6       1       2016    7448    21280   51012   107744

सभी विनिंग सेट उत्पन्न करने के बाद, मैं जीतने वाले सेटों के खिलाफ दिए गए इनपुट की जांच करने के लिए कार्यक्रम का विस्तार कर सकता हूं, लेकिन निश्चित रूप से, यह तरीका कभी भी गोल्फ नहीं जीत पाएगा। इसलिए मैं यहां रुकने के लिए तैयार था - इसके अलावा ऐसा लग रहा था कि मैं n और d के फ़ंक्शन के रूप में जीतने के तरीकों की संख्या के लिए एक बंद-फॉर्म समाधान पा सकता हूं ... यह जीतने के तरीकों की संख्या है = 0.5 ((n + 2) ^ डी - एन ^ डी)।


2

सी ++ 794 849 चर

#include <algorithm>
#include <iostream>
#include <cmath>
#include <string>
#define _ return
#define Y int
#define Z(a) cout<<#a
#define W(a,b,c) for(a=c;a++<b;)
using namespace std;Y n,d,A[5],P[6],T=1,x[7776]={},i,j,k,a,z,p=pow(n,d);char c;bool B;string s;Y K(){a=P[j];W(k,i,0)a/=n;_ a%n;}Y M(){j=0;z=K();W(j,n,1){if(K()!=z){_ 1;}}_ 0;}Y N(){W(j,n,0)if(K()!=n-1-j)_ 1;_ 0;}Y O(){W(j,n,0)if(K()!=j)_ 1;_ 0;}Y S(){z=0;W(i,d,0){z*=n;z+=A[i];}_ z;}Y C(){a=z=0;W(i,p,0){if(s[i]-'0'){P[z]=i;++z;if(a){if(x[i]!=a)_ 0;}else a=x[i];}}_ a;}Y L(){W(i,d,0)if(M()*N()*O())_ 0;_ 1;}Y main(){cin>>n>>c>>d;while(1){W(i,d,0)B=cin>>A[i]>>c;if(x[S()]){Z(!);_ 0;}x[S()]=T;T*=-1;if(!B)break;}W(i,p,0)i<n?s+="1":s+="0";do if(C()&&L()){C()==1?Z(X):Z(O);_ 0;}while(prev_permutation(s.begin(),s.end()));_ 0;}

आउटपुट है: "X" (X जीतता है), "O" (O जीतता है), या "!" (अवैध चाल प्रयास)।

यह बस बिंदुओं को एक रेखीय सरणी में मैप करता है और आकार n के सभी संभावित सबसेट को चेक करता है, पहले X या O पर स्थिर रहने के लिए और फिर एक लाइन में होने के लिए। एक पंक्ति में होने की जांच करने के लिए, प्रत्येक सबसेट में बिंदुओं के निर्देशांक की एक बार में जांच की जाती है; उन्हें प्रत्येक को या तो 0 से n-1 तक बढ़ाना होगा, n-1 से घटकर या स्थिर होना चाहिए। अंक को रैखिक सरणी में स्वाभाविक रूप से आदेश दिया जाता है, इसलिए यह किसी दिए गए सेट के लिए बढ़ते या घटते हुए समन्वय को कॉल करने के लिए समझ में आता है।

पहले संस्करण में एक गंभीर गलती को इंगित करने के लिए हावर्ड के लिए धन्यवाद।

Quincunx के साथ एकजुटता में, मुझे यह इंगित करना होगा कि यदि C ++ उत्तर जीतता है तो यह एक देशद्रोही होगा


1
मुझे लगता है कि जब आप कह सकते हैं कि लाइन में होने से अंकगणितीय प्रगति होती है, तो यह दूसरे तरीके से नहीं चलती है (जैसे 0,2,4 मानक 3,2 टिक टीएसी पैर की अंगुली के लिए एक समाधान नहीं होगा)।
हावर्ड

@ हावर्ड, धन्यवाद। मैंने सुधार किया है। अब मुझे गोल्फ को खत्म करने में बहुत देर हो गई है, लेकिन मैं इसे ठीक कर पाया (मुझे लगता है)।
एरिक ट्रेसलर

आप अलग-अलग आउटपुट का उपयोग करके इसे आगे गोल्फ कर सकते हैं। आपको वास्तव में X winsया कहने की ज़रूरत नहीं है O wins। जब तक आप अपने उत्तर में समझाते हैं कि यह आउटपुट 1या 2(या कुछ भिन्नता) के लिए पूरी तरह से वैध है । जैसा कि मैंने कहा (जोर दिया): " इंगित करें कि कौन जीता"।
जस्टिन

किया हुआ। और अगर मैं सीख सकता हूं कि टर्नरी ऑपरेटर कैसे काम करता है, तो मैं कुछ पात्रों को बचा सकता हूं।
एरिक टेसलर

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