কেবল ক্রস সহ টিক-ট্যাক-টো


32

ভূমিকা

গেমটি টিক-ট্যাক-টু প্রত্যেকেই জানেন, তবে এই চ্যালেঞ্জের মধ্যে আমরা কিছুটা মোড়কে পরিচয় করিয়ে দিতে যাচ্ছি। আমরা কেবল ক্রস ব্যবহার করতে যাচ্ছি । প্রথম ব্যক্তি যিনি একটি সারিতে তিনটি ক্রস রেখেছেন তিনি হেরে যান। একটি আকর্ষণীয় সত্য যে কেউ হারানোর আগে ক্রসগুলির সর্বোচ্চ পরিমাণ 6 এর সমান :

X X -
X - X
- X X

তার মানে 3 x 3 বোর্ডের জন্য সর্বাধিক পরিমাণ 6 । সুতরাং এন = 3 এর জন্য আমাদের 6 আউটপুট করা দরকার।

অন্য উদাহরণ, এন = 4, বা একটি 4 এক্স 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
সুতরাং আপনার লিঙ্ক করা পৃষ্ঠায় সূত্রগুলি ব্যবহার করার জন্য প্রশ্নটি কেবল
উত্সাহিত করেছে


7
@ এনিকায়েল যতদূর আমি দেখতে পাচ্ছি, ওইআইএস নিবন্ধটিতে কেবল নিম্ন সীমা রয়েছে।
মার্টিন এন্ডার

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 এর জন্য এক মিনিটের মধ্যেই শেষ করেন না।

এন <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

সিজেএম ( 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

@ থমাসকওয়া, ওহ, এটি এখনও তাত্পর্যপূর্ণ তবে আমি মনে করি এটি দক্ষ হিসাবে যুক্তিযুক্ত কারণ এটি আমাকে OEIS ক্রমটি 3 টি শর্ত দ্বারা প্রসারিত করার অনুমতি দিয়েছে।
পিটার টেলর

@ থমাসকওয়া, সুনির্দিষ্টভাবে বলতে গেলে এটি 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 */
}

সম্পাদনা: অব্যবহৃত প্যারামিটার হিসাবে int ভেরিয়েবলগুলি ঘোষণা করুন; y স্থানাংক সরান, কেবল সূচক ব্যবহার করুন; বৈশ্বিকের পরিবর্তে প্যারামিটার তালিকায় পরিবর্তনশীল স্থানান্তরিত করুন, অযথা প্যারামিটারগুলিতে স্থান দিন s(); লুপগুলির জন্য একত্রিত করুন, অপ্রয়োজনীয় বন্ধনীগুলি সরান; প্রতিস্থাপন &&সঙ্গে *, ||সঙ্গে +; ম্যাক্রো-ইফাই 3-ইন-এ-সারি চেক


এটা কত ধীর?
লুভজো

@ লভজো আমার পিসিতে এটি দ্রুত করার জন্য কিছু ছোট পরিবর্তন দিয়ে চেষ্টা করলেন, এন = 5 এর জন্য 15 মিমি, এন = 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-2; এবং পরিবর্তন b[x]++করে b[x++]++এবং পরে প্রতিস্থাপন x==n*n-1করে x==n*n, x+1সাথে xএবং xসাথে x-1
পিটার টেলর

4

সি 263 264 283 309

সম্পাদনা করুন কয়েক বাইট সংরক্ষিত ধন্যবা @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 -> 26 10 সেকেন্ডে
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;বৈধ যদি । (আমার এখনই সি সংকলক অ্যাক্সেস নেই)।
পিটার টেলর

1
@ পিটারটেলর আমি এটির চেহারা দেব ... কেবল ট্রাইবোনাকি শব্দটি আমাকে ভয় দেখায়
দেখিয়ে চলেছে

আপনার হার্ড-কোডিংয়ের 999অর্থ আপনি সেই অংশটিকে উপেক্ষা করতে চাইবেন। যদিও সম্ভবত আপনার এটিকে হার্ড-কোডড না করা উচিত, যাতে নীতিগতভাবে আপনি 11 বা 12 এর চেয়ে বড় ইনপুটগুলি মোকাবেলা করতে পারেন।
পিটার টেলর

@ পিটারটেলর বিট গণনা করার জন্য সি তে আমার একটি বিটকাউন্ট পদ্ধতি থাকলে এটি দুর্দান্ত কাজ করবে। তবে সেই প্রাথমিক ফ্যাসে আমি বি-তে বিট গণনাটিই কমপুট করি, কেবল ভি
তে

2

রুবি, 263 বাইট

এটিও একটি নিখুঁত শক্তি সমাধান এবং কোল ক্যামেরনের সি উত্তর হিসাবে একই সমস্যার মুখোমুখি, তবে এটি রুবি এবং সি এর চেয়েও ধীর গতিযুক্ত নয় তবে আরে, এটি সংক্ষিপ্ত।

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) x বার y এর ith বিট দেয়, যেখানে negativeণাত্মক সূচকগুলি 0 প্রদান করে যাতে পরিসর স্থির থাকতে পারে (কোনও সীমানা পরীক্ষা করা যায় না) এবং শৃঙ্খলিত হলে কম প্যারেনেসিস থাকতে পারে
  • সীমানা চেক করা হয়নি বলে এটি প্রত্যেকের জন্য 81 * 4 = 324 নিদর্শন পরীক্ষা করে সম্ভাব্য সর্বাধিকের , যার ফলে N = 3 আমার ল্যাপটপটি 9 সেকেন্ড নেয় এবং N = 5 আমার পক্ষে এটি শেষ হতে খুব বেশি সময় নেয়
  • স্থান সংরক্ষণের জন্য টি / এফ-এর জন্য 1/0-তে বুলিয়ান যুক্তি ব্যবহৃত হয়, উদাহরণস্বরূপ (*) হল &&, (1-x) হয় (এক্স নয়) ইত্যাদি etc.
  • যেহেতু এটি অ্যারের পরিবর্তে পূর্ণসংখ্যার পরীক্ষা করে, (ডিভ পি 1 এল) == (ডিভি পি 2 এল) এটি নিশ্চিত করার জন্য প্রয়োজনীয় যে বিভিন্ন সারি জুড়ে কোনও প্যাটার্ন পরীক্ষা করা হয়নি, যেখানে এল সারির দৈর্ঘ্য এবং 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]]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.