टिक-टैक-टो केवल क्रॉस के साथ


32

परिचय

गेम टिक-टैक-टो को सभी जानते हैं, लेकिन इस चुनौती में, हम थोड़ा ट्विस्ट लाने जा रहे हैं। हम केवल क्रॉस का उपयोग करने जा रहे हैं । पहला व्यक्ति जो एक पंक्ति में तीन पार करता है वह हार जाता है। एक दिलचस्प तथ्य यह है कि किसी को हारने से पहले क्रॉस की अधिकतम राशि 6 के बराबर होती है :

X X -
X - X
- X X

इसका मतलब है कि 3 x 3 बोर्ड के लिए, अधिकतम राशि 6 है । तो एन = 3 के लिए, हमें 6 आउटपुट की आवश्यकता है।

एन = 4, या 4 x 4 बोर्ड के लिए एक और उदाहरण:

X X - X
X X - X
- - - -
X X - X

यह एक इष्टतम समाधान है, आप देख सकते हैं कि क्रॉस की अधिकतम राशि 9 के बराबर है । 12 x 12 बोर्ड के लिए एक इष्टतम समाधान है:

X - X - X - X X - X X -
X X - X X - - - X X - X
- X - X - X X - - - X X
X - - - X X - X X - X -
- X X - - - X - - - - X
X X - X X - X - X X - -
- - X X - X - X X - X X
X - - - - X - - - X X -
- X - X X - X X - - - X
X X - - - X X - X - X -
X - X X - - - X X - X X
- X X - X X - X - X - X

इसका परिणाम 74 है

काम

कार्य सरल है, 0 से अधिक पूर्णांक दिया गया है, क्रॉस की अधिकतम मात्रा को आउटपुट करता है जिसे पंक्ति, स्तंभ या तिरछे साथ एक पंक्ति में तीन एक्स के आसन्न के साथ नहीं रखा जा सकता है।

परीक्षण के मामलों

N     Output
1     1
2     4
3     6
4     9
5     16
6     20
7     26
8     36
9     42

अधिक जानकारी https://oeis.org/A181018 पर देखी जा सकती है ।

नियम

  • यह , इसलिए कम से कम बाइट्स जीत के साथ जमा करना!
  • आप एक समारोह या एक कार्यक्रम प्रदान कर सकते हैं।

7
तो सवाल सिर्फ आपके द्वारा जुड़े पृष्ठ में सूत्रों का उपयोग करने के लिए उबलता है ...
18

2
मठ पर संबंधित पोस्ट।
AdmBorkBork

7
@nicael जहाँ तक मैं देख सकता हूँ, OEIS लेख में केवल निम्न सीमाएँ हैं।
मार्टिन एंडर

6
इसे सबसे तेज़ कोड चुनौती के रूप में देखना अच्छा होगा।
ल्यूक

4
कोडगोल्फ समाधान नहीं है, लेकिन मैं पिछले कुछ दिनों से "दृश्य" के साथ खेल रहा हूं। आप यहाँ jsfiddle तक पहुँच सकते हैं: jsfiddle.net/V92Gn/3899 यह यादृच्छिक परिवर्तन के माध्यम से समाधान खोजने का प्रयास करता है। यदि यह "सही" उत्तर ढूंढता है तो यह बंद नहीं होगा, लेकिन यह नीचे दिए गए उत्तरों की तुलना में बहुत जल्दी सही समाधानों में से कई को प्राप्त कर सकता है।
स्टाइलट्रेन

जवाबों:


11

पायथ, 57 51 49 बाइट्स

L.T.e+*]Ykbbsef!s.AMs.:R3ssmyBdsm_BdCBcTQsD^U2^Q2

@ पीटरटायलर के सीजेएम समाधान की तरह, यह ब्रूट-बल है, इसलिए यह ओ (एन 2 2 एन 2 ) समय में चलता है । ऑनलाइन दुभाषिया n = 4 के लिए एक मिनट के भीतर समाप्त नहीं होता है।

इसे N <4 के लिए यहाँ आज़माएँ ।

विकर्ण फ़ंक्शन का प्रयास करें ।

L.T.e+*]Ykbb         y(b): diagonals of b (with some trailing [])
s e                  sum of the last (with most ones) array such that
f                    filter lambda T:
 ! s .AM                none of the 3 element sublists are all ones               
   s .:R3               all 3 element sublists
   s s                  flatten
   myBd                 add the diagonals
   sm_B d               add the vertically flipped array and transpose
   CBcTQ                array shaped into Q by Q square, and its transpose
 sD ^U2 ^Q2             all binary arrays of length Q^2 sorted by sum

13

CJam ( 58 56 बाइट्स)

2q~:Xm*{7Yb#W=}:F,Xm*{ee{~0a@*\+}%zS*F},_Wf%:z&Mf*1fb:e>

यह अविश्वसनीय रूप से धीमा है और बहुत सारी मेमोरी का उपयोग करता है, लेकिन यह आपके लिए है।

विच्छेदन

2q~:Xm*        e# Read input into X and find Cartesian product {0,1}^X
{7Yb#W=}:F,    e# Filter with a predicate F which rejects arrays with a 111
Xm*            e# Take the Cartesian product possible_rows^X to get possible grids
{              e# Filter out grids with an anti-diagonal 111 by...
  ee{~0a@*\+}% e#   prepending [0]*i to the ith row
  zS*F         e#   transposing, joining on a non-1, and applying F
},
_Wf%:z         e# Copy the filtered arrays and map a 90 degree rotation
&              e# Intersect. The rotation maps horizontal to vertical and
               e# anti-diagonal to diagonal, so this gets down to valid grids
Mf*            e# Flatten each grid
1fb            e# Count its 1s
:e>            e# Select the maximum

Θ(aX)a1.83928675Θ(aX2)Θ(aX4)


O(Xa3X)

public class A181018 {
    public static void main(String[] args) {
        for (int i = 1; i < 14; i++) {
            System.out.format("%d:\t%d\n", i, calc(i));
        }
    }

    private static int calc(int n) {
        if (n < 0) throw new IllegalArgumentException("n");
        if (n < 3) return n * n;

        // Dynamic programming approach: given two rows, we can enumerate the possible third row.
        // sc[i + rows.length * j] is the greatest score achievable with a board ending in rows[i], rows[j].
        int[] rows = buildRows(n);
        byte[] sc = new byte[rows.length * rows.length];
        for (int j = 0, k = 0; j < rows.length; j++) {
            int qsc = Integer.bitCount(rows[j]);
            for (int i = 0; i < rows.length; i++) sc[k++] = (byte)(qsc + Integer.bitCount(rows[i]));
        }

        int max = 0;
        for (int h = 2; h < n; h++) {
            byte[] nsc = new byte[rows.length * rows.length];
            for (int i = 0; i < rows.length; i++) {
                int p = rows[i];
                for (int j = 0; j < rows.length; j++) {
                    int q = rows[j];
                    // The rows which follow p,q cannot intersect with a certain mask.
                    int mask = (p & q) | ((p << 2) & (q << 1)) | ((p >> 2) & (q >> 1));
                    for (int k = 0; k < rows.length; k++) {
                        int r = rows[k];
                        if ((r & mask) != 0) continue;

                        int pqrsc = (sc[i + rows.length * j] & 0xff) + Integer.bitCount(r);
                        int off = j + rows.length * k;
                        if (pqrsc > nsc[off]) nsc[off] = (byte)pqrsc;
                        if (pqrsc > max) max = pqrsc;
                    }
                }
            }

            sc = nsc;
        }

        return max;
    }

    private static int[] buildRows(int n) {
        // Array length is a tribonacci number.
        int c = 1;
        for (int a = 0, b = 1, i = 0; i < n; i++) c = a + (a = b) + (b = c);

        int[] rows = new int[c];
        int i = 0, j = 1, val;
        while ((val = rows[i]) < (1 << (n - 1))) {
            if (val > 0) rows[j++] = val * 2;
            if ((val & 3) != 3) rows[j++] = val * 2 + 1;
            i++;
        }

        return rows;
    }
}

कुशल दृष्टिकोण क्या चलता है?
जून को lirtosiast

@ThomasKwa, ओह, यह अभी भी घातीय है, लेकिन मुझे लगता है कि इसे कुशल कहना उचित है क्योंकि इसने मुझे 3 शब्दों द्वारा OEIS अनुक्रम का विस्तार करने की अनुमति दी है।
पीटर टेलर

@ThomasKwa, सटीक होना, यह O(n a^n)कहाँ है a ~= 5.518
पीटर टेलर

4

सी, 460 456 410 407 362 351 318 बाइट्स

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

#define r return
#define d(x,y)b[x]*b[x+y]*b[x+2*(y)]
n,*b;s(i){for(;i<n*(n-2);++i)if(d(i%(n-2)+i/(n-2)*n,1)+d(i,n)+(i%n<n-2&&d(i,n+1)+d(i+2,n-1)))r 1;r 0;}t(x,c,l,f){if(s(0))r 0;b[x]++;if(x==n*n-1)r c+!s(0);l=t(x+1,c+1);b[x]--;f=t(x+1,c);r l>f?l:f;}main(c,v)char**v;{n=atol(v[1]);b=calloc(n*n,4);printf("%d",t(0,0));}

परीक्षण के मामलों

$ ./a.out 1
1$ ./a.out 2
4$ ./a.out 3
6$ ./a.out 4
9$ ./a.out 5
16$

Ungolfed

n,*b; /* board size, board */

s(i) /* Is the board solved? */
{
    for(;i<n*(n-2);++i) /* Iterate through the board */
            if(b[i%(n-2)+i/(n-2)*n]&&b[i%(n-2)+i/(n-2)*n+1]&&b[i%(n-2)+i/(n-2)*n+2] /* Check for horizontal tic-tac-toe */
                    || b[i] && b[i+n] && b[i+2*n] /* Check for vertical tic-tac-toe */
                    || (i%n<n-2
                            && (b[i] &&b [i+n+1] && b[i+2*n+2] /* Check for diagonal tic-tac-toe */
                                    || b[i+2*n] && b[i+n+1] && b[i+2]))) /* Check for reverse diagonal tic-tac-toe */
                    return 1;
    return 0;
}

t(x,c,l,f) /* Try a move at the given index */
{
    if(s(0)) /* If board is solved, this is not a viable path */
            return 0;
    b[x]++;
    if(x==n*n-1) /* If we've reached the last square, return the count */
            return c+!s(0);

    /* Try it with the cross */
    l=t(x+1,c+1);

    /* And try it without */
    b[x]--;
    f=t(x+1,c);

    /* Return the better result of the two */
    return l>f?l:f;
}

main(c,v)
char**v;
{
    n=atol(v[1]); /* Get the board size */
    b=calloc(n*n,4); /* Allocate a board */
    printf("%d",t(0,0)); /* Print the result */
}

संपादित करें: अप्रयुक्त मापदंडों के रूप में अंतर चर घोषित करें; y समन्वय हटाएं, बस सूचकांक का उपयोग करें; वैश्विक के बजाय पैरामीटर सूची में चर को स्थानांतरित करें, को पारित अनावश्यक मापदंडों को ठीक करें s(); छोरों के लिए गठबंधन, अनावश्यक कोष्ठक को हटा दें; की जगह &&के साथ *, ||के साथ +; मैक्रो- ify में एक पंक्ति की जाँच करें


कितना धीमा है?
लोवोजो

@Lovjo ने अपने पीसी पर कुछ छोटे बदलावों के साथ इसे तेज करने की कोशिश की, n = 5 के लिए 15ms, n = 6 के लिए 12 सेकंड (इनपुट +1, समय * 800)!
edc65

@ edc65 यह मेरा अनुभव था। 5 से अधिक कुछ भी प्रदर्शन नाटकीय रूप से धीमा था। मैं 6 से अधिक इनपुट की कोशिश कर के साथ परेशान नहीं था
कोल कैमरून

मैंने 7 से शुरुआत की जब मैंने अपनी टिप्पणी पोस्ट की। हम देखेंगे
edc65

आप के साथ कुछ और आकर्षण निचोड़ कर सकते हैं #define d(x,y)b[x]*b[x+y]*b[x+y+y]; के सभी उदाहरणों sको बदलने और बदलने की शुरुआत करके ; और बदलकर करने के लिए और उसके बाद की जगह के साथ , के साथ , और साथ । s(i,m){for(m=n-2;n-2b[x]++b[x++]++x==n*n-1x==n*nx+1xxx-1
पीटर टेलर

4

सी 263 264 283 309

संपादित करें कुछ बाइट्स ने thx @Peter टेलर को बचाया - जितना मुझे आशा थी उससे कम। तब 2 बाइट्स कुछ और मेमोरी आवंटित करते थे, अब मैं बड़े आकार की कोशिश कर सकता हूं, लेकिन इसमें बहुत समय लगता है।

नोट स्पष्टीकरण जोड़ते समय, मुझे पता चला कि मैं आर सरणी में ग्रिड रखने के लिए बाइट्स बर्बाद कर रहा हूं - ताकि आप पाए गए समाधान को देख सकें ... यह इस चुनौती के लिए अनुरोध नहीं किया गया है !!
मैंने इसे गोल्फ संस्करण में हटा दिया

एक गोल्फ सी कार्यक्रम जो वास्तव में उचित समय में n = 1..10 का उत्तर पा सकता है।

s,k,n,V[9999],B[9999],i,b;K(l,w,u,t,i){for(t=u&t|u*2&t*4|u/2&t/4,--l; i--;)V[i]&t||(b=B[i]+w,l?b+(n+2)/3*2*l>s&&K(l,b,V[i],u,k):b>s?s=b:0);}main(v){for(scanf("%d",&n);(v=V[i]*2)<1<<n;v%8<6?B[V[k]=v+1,k++]=b+1:0)V[k]=v,b=B[k++]=B[i++];K(n,0,0,0,k);printf("%d",s);}

मेरा इम्तिहान:

7 -> 10 में 26 सेकंड
8 -> 36 में 18 सेकंड
9 -> 42 में 1162 सेकंड

कम गोल्फ और समझाने की कोशिश कर रहा है

#include <stdio.h>

int n, // the grid size
    s, // the result
    k, // the number of valid rows 
    V[9999], // the list of valid rows (0..to k-1) as bitmasks
    B[9999], // the list of 'weight' for each valid rows (number of set bits)
    R[99],  // the grid as an array of indices pointing to bitmask in V
    b,i; // int globals set to 0, to avoid int declaration inside functions

// recursive function to fill the grid
int K(
  int l, // number of rows filled so far == index of row to add
  int w, // number of crosses so far
  int u, // bit mask of the preceding line (V[r[l-1]])
  int t, // bit mask of the preceding preceding line (V[r[l-2]])
  int i) // the loop variables, init to k at each call, will go down to 0
{
  // build a bit mask to check the next line 
  // with the limit of 3 crosses we need to check the 2 preceding rows
  t = u&t | u*2 & t*4 | u/2 & t/4; 
  for (; i--; )// loop on the k possibile values in V
  {
    R[l] = i; // store current row in R
    b = B[i] + w; // new number of crosses if this row is accepted
    if ((V[i] & t) == 0) // check if there are not 3 adjacent crosses
      // then check if the score that we can reach from this point
      // adding the missing rows can eventually be greater
      // than the current max score stored in s
      if (b + (n + 2) / 3 * 2 * (n - l - 1) > s)
        if (l > n-2) // if at last row
          s = b > s ? b : s; // update the max score
        else  // not the last row
          K(l + 1, b, V[i], u, k); // recursive call, try to add another row
  }
}

int main(int j)
{
  scanf("%d", &n);

  // find all valid rows - not having more than 2 adjacent crosses
  // put valid rows in array V
  // for each valid row found, store the cross number in array B
  // the number of valid rows will be in k
  for (; i<1 << n; V[k] = i++, k += !b) // i is global and start at 0
    for (b = B[k] = 0, j = i; j; j /= 2) 
      b = ~(j | -8) ? b : 1, B[k] += j & 1;
  K(0,0,0,0,k); // call recursive function to find the max score
  printf("%d\n", s);
}

यह अनिवार्य रूप से मेरे जावा कार्यक्रम के समान है लेकिन गहराई-पहले की बजाय चौड़ाई-पहले है। मुझे लगता है कि आपको मेरी buildRowsविधि को चित्रित करके कम से कम एक दर्जन पात्रों को बचाने में सक्षम होना चाहिए ; शायद 20 के रूप में कई अगर for(scanf("%d",&n);(v=2*V[i++])<1<<n;v%8<6&&V[++j]=v+1)v&&V[++j]=v;वैध है। (मेरे पास अभी C कंपाइलर तक पहुंच नहीं है)।
पीटर टेलर

1
@PeterTaylor मैं इसे एक रूप दूंगा ... सिर्फ आदिवासी शब्द मुझे डरा रहा है
edc65

आपके हार्ड-कोडेड का 999मतलब है कि आप उस हिस्से को अनदेखा करना चाहेंगे। यद्यपि हो सकता है कि आपको वास्तव में इसे हार्ड-कोडेड नहीं बनाना चाहिए, ताकि सिद्धांत रूप में आप 11 या 12 की तुलना में बड़े इनपुट का सामना कर सकें
पीटर टेलर

@PeterTaylor अगर मैं बिट्स की गणना करने के लिए C में एक .bitCount विधि रखता तो बहुत अच्छा होता। लेकिन उस प्रारंभिक प्रसंग में मैं बी में थोड़ी गिनती ही नहीं कर रहा हूँ, न केवल वी में बिट मास्क
edc65

2

रूबी, 263 बाइट्स

यह भी एक ब्रूट फोर्स सॉल्यूशन है और कोल कैमरून के C उत्तर के समान ही समस्याओं का सामना करता है, लेकिन यह भी धीमा है क्योंकि यह रूबी नहीं है और C नहीं है। लेकिन हे, यह छोटा है।

c=->(b){b.transpose.all?{|a|/111/!~a*''}}
m=->(b,j=0){b[j/N][j%N]=1
x,*o=b.map.with_index,0
c[b]&&c[b.transpose]&&c[x.map{|a,i|o*(N-i)+a+o*i}]&&c[x.map{|a,i|o*i+a+o*(N-i)}]?(((j+1)...N*N).map{|i|m[b.map(&:dup),i]}.max||0)+1:0}
N=$*[0].to_i
p m[N.times.map{[0]*N}]

परीक्षण के मामलों

$ ruby A181018.rb 1
1
$ ruby A181018.rb 2
4
$ ruby A181018.rb 3
6
$ ruby A181018.rb 4
9
$ ruby A181018.rb 5
16

Ungolfed

def check_columns(board)
  board.transpose.all? do |column|
    !column.join('').match(/111/)
  end
end

def check_if_unsolved(board)
  check_columns(board) && # check columns
    check_columns(board.transpose) && # check rows
    check_columns(board.map.with_index.map { |row, i| [0] * (N - i) + row + [0] * i }) && # check decending diagonals
    check_columns(board.map.with_index.map { |row, i| [0] * i + row + [0] * (N - i) }) # check ascending diagonals
end

def maximum_crosses_to_place(board, index=0)
  board[index / N][index % N] = 1 # set cross at index
  if check_if_unsolved(board)
    crosses = ((index + 1)...(N*N)).map do |i|
      maximum_crosses_to_place(board.map(&:dup), i)
    end
    maximum_crosses = crosses.max || 0
    maximum_crosses + 1
  else
    0
  end
end

N = ARGV[0].to_i
matrix_of_zeros = N.times.map{ [0]*N }

puts maximum_crosses_to_place(matrix_of_zeros)

1

हास्केल, 143 बाइट्स

कुछ मायनों में ऐसा नहीं किया जाता है, लेकिन मुझे बहुत मज़ा आया:

  • क्योंकि क्षैतिज "जीतने" पैटर्न के लिए जाँच करना अलग-अलग पंक्तियों में लागू होने पर अमान्य हो जाता है, N <3 रिटर्न 0 का इनपुट
  • "सरणियाँ" पूर्णांक बिट्स में अनपैक्ड हैं, इसलिए आसानी से गणना योग्य हैं
  • ((i! x) y) ith बिट को x बार y देता है, जहाँ नकारात्मक सूचक 0 वापस आते हैं, इसलिए श्रेणी स्थिर हो सकती है (कोई सीमा नहीं जाँच) और जंजीर होने पर कम कोष्ठक
  • क्योंकि सीमाओं की जाँच नहीं की जाती है, यह हर संभव अधिकतम के लिए 81 * 4 = 324 पैटर्न की जाँच करता है , जिसके कारण N = 3 मेरे लैपटॉप को 9 सेकंड ले रहा है और N = 5 को मुझे समाप्त होने में बहुत समय लग रहा है।
  • 1/0 पर बूलियन तर्क का उपयोग अंतरिक्ष को बचाने के लिए T / F के लिए किया जाता है, उदाहरण के लिए (*) is &&, (1-x) is (not x), आदि।
  • चूँकि यह सरणियों के बजाय पूर्णांक की जाँच करता है, (div p1 L) == (div P2 L) यह सुनिश्चित करने के लिए आवश्यक है कि विभिन्न पंक्तियों में पैटर्न की जाँच नहीं की जाती है, जहाँ L पंक्ति की लंबाई और p1 है, P2 स्थितियाँ हैं
  • एक संभावित अधिकतम का मूल्य इसका हेमिंग वजन है

यहाँ कोड है:

r=[0..81]
(%)=div
s=sum
i!x|i<0=(*0)|0<1=(*mod(x%(2^i))2)
f l=maximum[s[i!x$1-s[s[1#2,l#(l+l),(l+1)#(l+l+2),(1-l)#(2-l-l)]|p<-r,let  a#b=p!x$(p+a)!x$(p+b)!x$s[1|p%l==(p+mod b l)%l]]|i<-r]|x<-[0..2^l^2]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.