Trồng cây trong công viên - Nhanh nhất có thể!


20

Thử thách này được lấy cảm hứng từ ứng dụng này . Các trường hợp thử nghiệm được mượn từ ứng dụng đó.


Đây là một thử thách , trong đó mục tiêu là giải quyết các trường hợp thử nghiệm lớn nhất trong khoảng thời gian ít nhất. Đã cung cấp một số trường hợp thử nghiệm nhỏ hơn, để mọi người có thể kiểm tra thuật toán của họ nhanh hơn.


Bạn sẽ được cung cấp một lưới đầu vào vuông, có kích thước n-by-n trong đó 9 <= n <= 12 . Lưới này sẽ được chia thành n khu vực, trong đó các ô của mỗi khu vực có một mã định danh duy nhất (Tôi sẽ sử dụng chữ cái viết thường từ al trong văn bản ở đây, nhưng bạn có thể chọn bất cứ thứ gì bạn thích, ví dụ như số nguyên 1-12 ) .

Đầu vào có thể trông như thế này (định dạng đầu vào tùy chọn):

aabbbbbcc
adddbbbcc
adeeecccc
adddefgcc
hhhdifggg
hdddifffg
hhhiifffg
hihiifffg
iiiiiiggg

Hoặc, dễ hình dung hơn:

nhập mô tả hình ảnh ở đây

Thử thách:

Bạn phải đặt cây 2 * n trong công viên này, theo các quy tắc sau:

  • Sẽ có chính xác 2 cây trên mỗi cột và 2 cây mỗi hàng
  • Tất cả các khu vực sẽ có chính xác 2 cây.
  • Không có cây nào có thể liền kề với cây khác, theo chiều dọc, chiều ngang hoặc đường chéo

Giải pháp cho bố cục trên là:

nhập mô tả hình ảnh ở đây

Lưu ý: Chỉ có một giải pháp cho mỗi câu đố

Quy tắc bổ sung:

  • Các định dạng đầu vào và đầu ra là tùy chọn
    • Ví dụ, đầu ra có thể là một danh sách các chỉ mục, một lưới có 1/0 cho biết nếu có một cây ở vị trí đó hoặc một phiên bản sửa đổi của đầu vào nơi các cây được chỉ định
  • Thời gian thực hiện phải có tính quyết định
  • Chương trình phải kết thúc trong 1 phút tại máy tính của @ isaacg
    • Thông số kỹ thuật: 4 CPU, CPU i5-4300U @ 1.9 GHz, RAM 7.5G.
  • Trong trường hợp chương trình của bạn không thể giải quyết hai trường hợp thử nghiệm lớn nhất trong một phút thì thời gian cho lần lớn thứ hai ( n = 11 ) sẽ là điểm của bạn. Bạn sẽ thua trước một giải pháp giải quyết vụ án lớn nhất.

Các trường hợp thử nghiệm:

Tôi có thể chỉnh sửa danh sách này nếu các bài nộp dường như được tùy chỉnh để phù hợp với các trường hợp kiểm tra này.

12 giờ 12 :

--- Input ---
aaaaabccccdd
aaaaabccccdd
aaaaabbbbddd
eeeafffgbghh
eeaafffgbghh
eefffffggghh
eeefijffghhh
iieiijjjjkhh
iiiiijjjjkhk
lljjjjjjjkkk
llllllkkkkkk
llllllkkkkkk
--- Solution ---
aaaaabcccCdD
aaaaaBcCccdd
aAaaabbbbdDd
eeeaffFgBghh
eeAaFffgbghh
eefffffGgGhh
EeefijffghhH
iiEiIjjjjkhh
IiiiijjjjkHk
lljJjJjjjkkk
lLllllkkKkkk
lllLllKkkkkk

11/11/11 :

--- Input ---
aaaaaaabbcc
adddabbbbcc
edddbbbbbbc
eddddbbbbbb
effffggghhh
effffgghhii
eefffjjhhii
eeeejjjhhii
eeejjjjkiii
jjjjjjkkiii
jjjjjkkkiii
--- Solution ---
aaAaaaabbCc
adddAbBbbcc
eDddbbbbbbC
eddDdBbbbbb
effffggGhHh
eFfffGghhii
eefFfjjhHii
EeeejjjhhiI
eeEjjjjKiii
JjjjJjkkiii
jjjjjkKkIii

10 giờ 10

--- Input ---
aaaaabccdd
aeaabbbccd
aeaabfbgcd
eeeaafggcd
eeeaafghcd
eeeiifghcd
ieiiigghcd
iiijighhcd
jjjjighhcd
jjjggghhdd
--- Solution ---
aaAaabccdD
aeaaBbBccd
aEaabfbgcD
eeeaaFgGcd
eEeAafghcd
eeeiiFghCd
IeiIigghcd
iiijigHhCd
JjJjighhcd
jjjgGghHdd

9 tháng 9

--- Input ---
aabbbbbcc
adddbbbcc
adeeecccc
adddefgcc
hhhdifggg
hdddifffg
hhhiifffg
hihiifffg
iiiiiiggg
--- Solution ---
aAbBbbbcc
adddbbBcC
adEeEcccc
AdddefgCc
hhhDiFggg
hDddifffG
hhhiIfFfg
HiHiifffg
iiiiiIgGg
--- Input ---
aaabbbccc
aaaabbccc
aaaddbcce
ffddddcce
ffffddeee
fgffdheee
fggfhhhee
iggggheee
iiigggggg
--- Solution ---
aaAbBbccc
AaaabbcCc
aaaDdBcce
fFddddcCe
fffFdDeee
fGffdheeE
fggfHhHee
IggggheeE
iiIgggGgg

"Các định dạng đầu vào và đầu ra là tùy chọn, nhưng phải giống nhau" Điều đó có nghĩa là gì? Tôi không thể đưa ra danh sách các danh sách chứa 1 và 0 cho cây và không phải cây mà không quan tâm đến việc xuất ra các khu vực?
Gây tử vong vào

@Firthize, chỉnh sửa. Tôi nghĩ rằng việc đưa ra một danh sách các chỉ số hoặc một lưới có 1/0 như bạn đề xuất là một ý tưởng tốt.
Stewie Griffin

1
Thông tin (nếu tôi tính toán chính xác): Có 3647375398569086976 cấu hình để đặt 24 cây trong lưới 12 * 12 chỉ thỏa mãn (1): There shall be exactly 2 trees per column, and 2 trees per rowvì vậy, một lực lượng vũ phu có lẽ là không thể.
dùng202729

"Không nên là một vấn đề lớn" : Cá nhân tôi nghĩ rằng đó là. Việc triển khai hiện tại của tôi giải quyết trường hợp thử nghiệm đầu tiên trong ~ 150ms và lần thứ 3 trong 5 giây nhưng không giải quyết được trường hợp cuối cùng (chỉ là '11x11) trong bất kỳ khoảng thời gian hợp lý nào. Nó có thể sẽ yêu cầu một số công việc cắt tỉa mạnh mẽ hơn nhiều - và do đó, một lượng mã bổ sung đáng kể - để hoàn thành trong vòng 1 phút.
Arnauld

1
@Arnauld, tôi đã thay đổi tối đa thành 11 vì đó là trường hợp thử nghiệm lớn nhất. Bạn có thể đăng giải pháp của mình (dưới dạng bài dự thi hợp lệ), nhưng sẽ không thắng nếu ai đó đăng giải pháp giải quyết tất cả các trường hợp kiểm tra, bất kể độ dài mã. Hội chợ?
Stewie Griffin

Câu trả lời:


7

JavaScript (ES6), 271 byte

Đưa đầu vào như một mảng các mảng ký tự. Trả về một mảng bitmasks (số nguyên) mô tả vị trí của các cây trên mỗi hàng, trong đó bit quan trọng nhất là vị trí ngoài cùng bên trái.

f=(a,p=0,r=[S=y=0],w=a.length)=>a.some((R,y)=>a.some((_,x)=>r[y]>>x&1&&(o[k=R[x]]=-~o[k])>2),o=[])?0:y<w?[...Array(1<<w)].some((_,n)=>(k=n^(x=n&-n))<=x*2|k&-k^k|n&(p|p/2|p*2)||r.some((A,i)=>r.some((B,j)=>A&B&n&&i<y&j<i))?0:(w=r[y],f(a,r[y++]=n,r),r[--y]=w,S))&&S:S=[...r]

Định dạng và nhận xét

f = (                                           // given:
  a,                                            //   - a = input matrix
  p = 0,                                        //   - p = previous bitmask
  r = [                                         //   - r = array of tree bitmasks
        S = y = 0 ],                            //   - S = solution / y = current row
  w = a.length                                  //   - w = width of matrix
) =>                                            //
  a.some((R, y) => a.some((_, x) =>             // if there's at least one area with more
    r[y] >> x & 1 && (o[k = R[x]] = -~o[k]) > 2 // than two trees:
  ), o = []) ?                                  //
    0                                           //   abort right away
  :                                             // else:
    y < w ?                                     //   if we haven't reached the last row:
      [...Array(1 << w)].some((_, n) =>         //     for each possible bitmask n:
        (k = n ^ (x = n & -n)) <= x * 2 |       //       if the bitmask does not consist of
        k & - k ^ k |                           //       exactly two non-consecutive bits,
        n & (p | p / 2 | p * 2) ||              //       or is colliding with the previous
        r.some((A, i) => r.some((B, j) =>       //       bitmask, or generates more than two
          A & B & n && i < y & j < i            //       trees per column:
        )) ?                                    //
          0                                     //         yield 0
        :                                       //       else:
          (                                     //
            w = r[y],                           //         save the previous bitmask
            f(a, r[y++] = n, r),                //         recursive call with the new one
            r[--y] = w,                         //         restore the previous bitmask
            S                                   //         yield S
          )                                     //
      ) && S                                    //     end of some(): return false or S
    :                                           //   else:
      S = [...r]                                //     this is a solution: save a copy in S

Các trường hợp thử nghiệm

Đoạn mã này bao gồm một chức năng bổ sung để hiển thị kết quả ở định dạng dễ đọc hơn. Nó là quá chậm để giải quyết trường hợp thử nghiệm cuối cùng.

Thời gian chạy dự kiến: ~ 5 giây.


Lưu ý của OP: Bài nộp này được thực hiện khi thử thách là một thử thách chơi gôn. Do đó, nó hoàn toàn hợp lệ, mặc dù nó không được tối ưu hóa cho tiêu chí chiến thắng hiện tại!
Stewie Griffin

Thời gian: Mất hơn một phút trên 11x11.
isaacg

Chúng tôi đang ở trong một dưa chua, có lẽ bạn có thể giúp đỡ. Bạn có thể nghĩ ra bất kỳ cách nào để tạo ra các trường hợp câu đố lớn hơn không cần thiết không?
isaacg

7

C, thời gian chính thức: 5ms cho 12x12

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <omp.h>

#define valT char
#define posT int

#ifndef _OPENMP
#  warning Building without OpenMP support
#  define omp_get_max_threads() 1
#  define omp_get_num_threads() 1
#  define omp_get_thread_num() 0
#endif

#define MIN_THREADED_SIZE 11

static void complete(posT n, valT *workspace) {
    const posT s = n * 3 + 2;

    const valT *regions = workspace;
    valT *output = &workspace[n*2+1];

    for(posT y = 0; y < n; ++ y) {
        for(posT x = 0; x < n; ++ x) {
//          putchar(output[y*s+x] ? '*' : '-');
            putchar(regions[y*s+x] + (output[y*s+x] ? 'A' : 'a'));
        }
        putchar('\n');
    }

    _Exit(0);
}

static void solveB(const posT n, valT *workspace, valT *pops, const posT y) {
    const posT s = n * 3 + 2;

    const valT *regions = workspace;
    const valT *remaining = &workspace[n];
    valT *output = &workspace[n*2+1];

    for(posT r = 0; r < n; ++ r) {
        if(pops[r] + remaining[r] < 2) {
            return;
        }
    }

    for(posT t1 = 0; t1 < n - 2; ++ t1) {
        posT r1 = regions[t1];
        if(output[t1+1-s]) {
            t1 += 2;
            continue;
        }
        if(output[t1-s]) {
            ++ t1;
            continue;
        }
        if((pops[t1+n] | pops[r1]) & 2 || output[t1-1-s]) {
            continue;
        }
        output[t1] = 1;
        ++ pops[t1+n];
        ++ pops[r1];
        for(posT t2 = t1 + 2; t2 < n; ++ t2) {
            posT r2 = regions[t2];
            if(output[t2+1-s]) {
                t2 += 2;
                continue;
            }
            if(output[t2-s]) {
                ++ t2;
                continue;
            }
            if((pops[t2+n] | pops[r2]) & 2 || output[t2-1-s]) {
                continue;
            }
            output[t2] = 1;
            ++ pops[t2+n];
            ++ pops[r2];
            if(y == 0) {
                complete(n, &workspace[-s*(n-1)]);
            }
            solveB(n, &workspace[s], pops, y - 1);
            output[t2] = 0;
            -- pops[t2+n];
            -- pops[r2];
        }
        output[t1] = 0;
        -- pops[t1+n];
        -- pops[r1];
    }
}

static void solve(const posT n, valT *workspace) {
    const posT s = n * 3 + 2;

    valT *regions = workspace;
    valT *remaining = &workspace[n];
    valT *pops = &workspace[n*s];
//  memset(&remaining[n*s], 0, n * sizeof(valT));

    for(posT y = n; (y --) > 0;) {
        memcpy(&remaining[y*s], &remaining[(y+1)*s], n * sizeof(valT));
        for(posT x = 0; x < n; ++ x) {
            valT r = regions[y*s+x];
            valT *c = &remaining[y*s+r];
            valT *b = &pops[r*3];
            if(*c == 0) {
                *c = 1;
                b[0] = y - 1;
                b[1] = x - 1;
                b[2] = x + 1;
            } else if(x < b[1] || x > b[2] || y < b[0]) {
                *c = 2;
            } else {
                b[1] = b[1] > (x - 1) ? b[1] : (x - 1);
                b[2] = b[2] < (x + 1) ? b[2] : (x + 1);
            }
        }
//      memset(&output[y*s], 0, (n+1) * sizeof(valT));
    }
    memset(pops, 0, n * 2 * sizeof(valT));

    posT sz = (n + 1) * s + n * 3;
    if(n >= MIN_THREADED_SIZE) {
        for(posT i = 1; i < omp_get_max_threads(); ++ i) {
            memcpy(&workspace[i*sz], workspace, sz * sizeof(valT));
        }
    }

#pragma omp parallel for if (n >= MIN_THREADED_SIZE)
    for(posT t1 = 0; t1 < n - 2; ++ t1) {
        valT *workspace2 = &workspace[omp_get_thread_num()*sz];
        valT *regions = workspace2;
        valT *output = &workspace2[n*2+1];
        valT *pops = &workspace2[n*s];

        posT r1 = regions[t1];
        output[t1] = pops[t1+n] = pops[r1] = 1;
        for(posT t2 = t1 + 2; t2 < n; ++ t2) {
            posT r2 = regions[t2];
            output[t2] = pops[t2+n] = 1;
            ++ pops[r2];
            solveB(n, &regions[s], pops, n - 2);
            output[t2] = pops[t2+n] = 0;
            -- pops[r2];
        }
        output[t1] = pops[t1+n] = pops[r1] = 0;
    }
}

int main(int argc, const char *const *argv) {
    if(argc < 2) {
        fprintf(stderr, "Usage: %s 'grid-here'\n", argv[0]);
        return 1;
    }

    const char *input = argv[1];
    const posT n = strchr(input, '\n') - input;
    const posT s = n * 3 + 2;

    posT sz = (n + 1) * s + n * 3;
    posT threads = (n >= MIN_THREADED_SIZE) ? omp_get_max_threads() : 1;
    valT *workspace = (valT*) calloc(sz * threads, sizeof(valT));
    valT *regions = workspace;

    for(posT y = 0; y < n; ++ y) {
        for(posT x = 0; x < n; ++ x) {
            regions[y*s+x] = input[y*(n+1)+x] - 'a';
        }
    }

    solve(n, workspace);

    fprintf(stderr, "Failed to solve grid\n");
    return 1;
}

Được biên dịch với GCC 7 bằng cách sử dụng -O3-fopenmpcờ. Nên có kết quả tương tự trên mọi phiên bản GCC có cài đặt OpenMP.

gcc-7 Trees.c -O3 -fopenmp -o Trees

Định dạng đầu vào và đầu ra được đưa ra trong câu hỏi.

Trên máy tính của tôi này có 0.009s 0.008s 0.005s cho ví dụ 12x12, và 0.022s 0.020s 0.019s để chạy tất cả các ví dụ. Trên máy tính điểm chuẩn, isaacg báo cáo 5ms cho ví dụ 12x12 bằng cách sử dụng phiên bản gốc (không có luồng) của mã.

Sử dụng:

./Trees 'aaabbbccc
aaaabbccc
aaaddbcce
ffddddcce
ffffddeee
fgffdheee
fggfhhhee
iggggheee
iiigggggg'

Chỉ cần một người giải quyết vũ phu đơn giản, làm việc trên một hàng tại một thời điểm. Nó chạy ở tốc độ tốt bằng cách nhận ra sớm các tình huống không thể (ví dụ: không còn ô nào trong khu vực, nhưng ít hơn 2 cây trong vùng).

Bản cập nhật đầu tiên cải thiện các lần truy cập bộ đệm bằng cách đặt các dữ liệu liên quan gần nhau trong bộ nhớ và làm cho các phép tính có thể còn lại trong phân đoạn có thể thông minh hơn một chút (hiện tại có thể thực tế là các cây không thể liền kề nhau). Nó cũng trích xuất vòng lặp ngoài cùng để ít trường hợp đặc biệt hơn cần thiết trong phần nóng nhất của thuật toán.

Bản cập nhật thứ hai làm cho vòng lặp ngoài cùng chạy song song trên các bộ xử lý có sẵn (sử dụng OpenMP), giúp tăng tốc độ tuyến tính. Điều này chỉ được kích hoạt cho n> = 11, vì chi phí hoạt động của các luồng sinh sản vượt trội hơn lợi ích cho các lưới nhỏ hơn.


Thời gian chính thức: 5ms cho 12x12. Nếu bất cứ ai khác đến gần, chúng tôi sẽ cần các trường hợp thử nghiệm lớn hơn.
isaacg

Chúng tôi đang ở trong một dưa chua, có lẽ bạn có thể giúp đỡ. Bạn có thể nghĩ ra bất kỳ cách nào để tạo ra các trường hợp câu đố lớn hơn không cần thiết không?
isaacg

@isaacg Vâng từ ví dụ minh họa, có vẻ như các lưới ban đầu được tạo ra bằng cách đặt cây trước (trong mô hình hiệp sĩ với các thay đổi nhỏ trong ví dụ đó, nhưng tôi đoán bất kỳ mẫu nào có 2 cây trên mỗi hàng & cột sẽ hoạt động) sau đó khớp các vùng xung quanh chúng sao cho mỗi vùng chứa 2 cây. Có vẻ như đó là một phương pháp đủ đơn giản để con người tuân theo các lưới lớn tùy ý.
Dave

Trên thực tế, nhìn lại, đó không phải là mô hình hiệp sĩ với những thay đổi nhỏ, mà là mô hình bao bọc trong đó mỗi cây được bù (1,2) so với trước. Khi bạn có một mẫu, bạn có thể hoán vị các hàng và cột để tạo ra các giải pháp ít cấu trúc hơn, miễn là nó không để các cây liền kề.
Dave

5

Java (OpenJDK 8) , Thời gian chính thức: 1.2s trên 12x12

chỉnh sửa: không còn mã golf

import java.util.*;

// Callable method, takes an int[][] and modifies it
static void f(int[][] areas){
    List<List<BitSet>> areaBitSets = new ArrayList<>();
    List<List<BitSet>> areaTreeBitSets = new ArrayList<>();
    for(int i = 0; i < areas.length; i++){
        areaBitSets.add(new ArrayList<BitSet>());
        areaTreeBitSets.add(new ArrayList<BitSet>());
    }

    // Add a bitset to our list representing each possible square, grouped by area
    for(int i=0; i < areas.length; i++){
        for(int j=0; j < areas.length; j++){
            BitSet b = new BitSet();
            b.set(i*areas.length + j);
            areaBitSets.get(areas[i][j]).add(b);
        }
    }

    // Fold each set onto itself so each area bitset has two trees
    for(int i=0; i < areas.length; i++){
        for(int j=0; j<areaBitSets.get(i).size()-1; j++){
            for(int k=j+1; k <areaBitSets.get(i).size(); k++){
                if(canFoldTogether(areaBitSets.get(i).get(j),areaBitSets.get(i).get(k), areas.length)){
                    BitSet b = (BitSet)areaBitSets.get(i).get(j).clone();
                    b.or(areaBitSets.get(i).get(k));
                    areaTreeBitSets.get(i).add(b);
                }
            }
        }
    }

    // Starting with area 0 add each area one at a time doing Cartesian products
    Queue<BitSet> currentPossibilities = new LinkedList<>();
    Queue<BitSet> futurePossibilities = new LinkedList<>();
    currentPossibilities.addAll(areaTreeBitSets.get(0));

    for(int i=1; i < areaTreeBitSets.size(); i++){
        while(!currentPossibilities.isEmpty()){
            BitSet b= (BitSet)currentPossibilities.poll().clone();

            for(BitSet c: areaTreeBitSets.get(i)){
                if(canFoldTogether(b,c,areas.length)){
                    BitSet d=(BitSet)b.clone();
                    d.or(c);
                    futurePossibilities.add(d);
                }
            }
        }
        currentPossibilities.addAll(futurePossibilities);
        futurePossibilities.clear();
    }

    // Get final output and modify the array
    BitSet b = currentPossibilities.poll();
    for(int i=0; i<areas.length*areas.length; i++){
        areas[i/areas.length][i%areas.length] = b.get(i)?1:0;
    }
}

// Helper method which determines whether combining two bitsets
// will still produce a valid output
static boolean canFoldTogether(BitSet a, BitSet b, int size){

    // See if there are trees too close to each other
    int c=-1;
    while((c=a.nextSetBit(c+1))>=0){
        int d=-1;
        while((d=b.nextSetBit(d+1))>=0){
            int r1=c/size;
            int r2=d/size;
            int c1=c%size;
            int c2=d%size;

            int rDifference = r1>r2 ? r1-r2 : r2-r1;
            int cDifference = c1>c2 ? c1-c2 : c2-c1;
            if(rDifference<2 && cDifference<2)
                return false;
        }
    }

    // Check for row and column cardinality
    BitSet f,g;
    for(int i=0; i<size; i++){
        f = new BitSet();
        f.set(i*size,(i+1)*size);
        g=(BitSet)f.clone();
        f.and(a);
        g.and(b);
        f.or(g);
        if(f.cardinality()>2){
            return false;
        }


        f=new BitSet();
        for(int j = 0; j<size; j++){
            f.set(j*size+i);
        }
        g=(BitSet)f.clone();
        f.and(a);
        g.and(b);
        f.or(g);
        if(f.cardinality()>2){
            return false;
        }
    }

    return true;
}

Hãy thử trực tuyến!

Liên kết TIO dành cho trường hợp thử nghiệm 12x12. TIO báo cáo 2.429s cho thời gian chạy.

Lấy một mảng các số nguyên làm đầu vào và sửa đổi mảng để chứa 1s cho cây và 0 cho các cây không.

Điều này chạy cho tất cả các testcase. Testcase lớn nhất chạy trên máy của tôi trong chưa đầy một giây, mặc dù tôi có một máy khá mạnh mẽ

Mã kiểm tra cho 12x12, có thể sửa đổi cho người khác

public static void main(String[] args){
    int[][] test = {{0,  0,  0,  0,  0,  1,  2,  2,  2,  2,  3,  3}, 
            {0,  0,  0,  0,  0,  1,  2,  2,  2,  2,  3,  3}, 
            {0,  0,  0,  0,  0,  1,  1,  1,  1,  3,  3,  3}, 
            {4,  4,  4,  0,  5,  5,  5,  6,  1,  6,  7,  7}, 
            {4,  4,  0,  0,  5,  5,  5,  6,  1,  6,  7,  7}, 
            {4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  7,  7}, 
            {4,  4,  4,  5,  8,  9,  5,  5,  6,  7,  7,  7}, 
            {8,  8,  4,  8,  8,  9,  9,  9,  9,  10,  7,  7}, 
            {8,  8,  8,  8,  8,  9,  9,  9,  9,  10,  7,  10}, 
            {11,  11,  9,  9,  9,  9,  9,  9,  9,  10,  10,  10}, 
            {11,  11,  11,  11,  11,  11,  10,  10,  10,  10,  10,  10}, 
            {11,  11,  11,  11,  11,  11,  10,  10,  10,  10,  10,  10}};

    long l = System.currentTimeMillis();
    f(test);
    System.out.println("12x12: " + (System.currentTimeMillis() - l) + "ms");

    for(int[] t : test){
        System.out.println(Arrays.toString(t));
    }

}

Sản xuất cái này trên máy của tôi:

12x12: 822ms
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1]
[0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0]
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0]

Lưu ý của OP: Bài nộp này được thực hiện khi thử thách là một thử thách chơi gôn. Do đó, nó hoàn toàn hợp lệ, mặc dù nó không (chỉ) được tối ưu hóa cho tiêu chí chiến thắng hiện tại!
Stewie Griffin

@StewieGriffin cảm ơn vì nhận xét. Khi tôi có cơ hội tôi sẽ làm việc để dọn dẹp nó vì nó không còn là môn đánh gôn nữa và xem liệu tôi có thể tối ưu hóa nó ở tốc độ nào không
PunPun1000

Thời gian chính thức: 1,2 giây trên 12x12.
isaacg

Chúng tôi đang ở trong một dưa chua, có lẽ bạn có thể giúp đỡ. Bạn có thể nghĩ ra bất kỳ cách nào để tạo ra các trường hợp câu đố lớn hơn không cần thiết không?
isaacg

4

Clingo , ms 7 ms cho 12 × 12, 116 byte

{t(X,Y):c(X,Y,Z)}=2:-Z=1..n.
:-X=1..n,{t(X,1..n)}!=2.
:-Y=1..n,{t(1..n,Y)}!=2.
:-t(X,Y),t(X+1,Y;X+1,Y+1;X,Y+1;X-1,Y+1).

(Dòng mới là tùy chọn và không được tính.)

Chạy với clingo plant.lp - -c n=<n>nơi <n>là kích thước lưới. Định dạng đầu vào là một danh sách các c(X,Y,Z).báo cáo cho mỗi tế bào ( X, Y) màu Z, với 1 ≤ X, Y, Zn, cách nhau bằng khoảng trắng không bắt buộc. Đầu ra bao gồm t(X,Y)cho mỗi cây tại ( X, Y).

Thời gian là khá vô nghĩa vì về cơ bản nó chỉ là thời gian khởi động, vì vậy hãy xem đây là một cuộc bỏ phiếu cho các trường hợp thử nghiệm lớn hơn.

Bản giới thiệu

$ clingo plant.lp -c n=12 - <<EOF
> c(1,1,1). c(2,1,1). c(3,1,1). c(4,1,1). c(5,1,1). c(6,1,2). c(7,1,3). c(8,1,3). c(9,1,3). c(10,1,3). c(11,1,4). c(12,1,4).
> c(1,2,1). c(2,2,1). c(3,2,1). c(4,2,1). c(5,2,1). c(6,2,2). c(7,2,3). c(8,2,3). c(9,2,3). c(10,2,3). c(11,2,4). c(12,2,4).
> c(1,3,1). c(2,3,1). c(3,3,1). c(4,3,1). c(5,3,1). c(6,3,2). c(7,3,2). c(8,3,2). c(9,3,2). c(10,3,4). c(11,3,4). c(12,3,4).
> c(1,4,5). c(2,4,5). c(3,4,5). c(4,4,1). c(5,4,6). c(6,4,6). c(7,4,6). c(8,4,7). c(9,4,2). c(10,4,7). c(11,4,8). c(12,4,8).
> c(1,5,5). c(2,5,5). c(3,5,1). c(4,5,1). c(5,5,6). c(6,5,6). c(7,5,6). c(8,5,7). c(9,5,2). c(10,5,7). c(11,5,8). c(12,5,8).
> c(1,6,5). c(2,6,5). c(3,6,6). c(4,6,6). c(5,6,6). c(6,6,6). c(7,6,6). c(8,6,7). c(9,6,7). c(10,6,7). c(11,6,8). c(12,6,8).
> c(1,7,5). c(2,7,5). c(3,7,5). c(4,7,6). c(5,7,9). c(6,7,10). c(7,7,6). c(8,7,6). c(9,7,7). c(10,7,8). c(11,7,8). c(12,7,8).
> c(1,8,9). c(2,8,9). c(3,8,5). c(4,8,9). c(5,8,9). c(6,8,10). c(7,8,10). c(8,8,10). c(9,8,10). c(10,8,11). c(11,8,8). c(12,8,8).
> c(1,9,9). c(2,9,9). c(3,9,9). c(4,9,9). c(5,9,9). c(6,9,10). c(7,9,10). c(8,9,10). c(9,9,10). c(10,9,11). c(11,9,8). c(12,9,11).
> c(1,10,12). c(2,10,12). c(3,10,10). c(4,10,10). c(5,10,10). c(6,10,10). c(7,10,10). c(8,10,10). c(9,10,10). c(10,10,11). c(11,10,11). c(12,10,11).
> c(1,11,12). c(2,11,12). c(3,11,12). c(4,11,12). c(5,11,12). c(6,11,12). c(7,11,11). c(8,11,11). c(9,11,11). c(10,11,11). c(11,11,11). c(12,11,11).
> c(1,12,12). c(2,12,12). c(3,12,12). c(4,12,12). c(5,12,12). c(6,12,12). c(7,12,11). c(8,12,11). c(9,12,11). c(10,12,11). c(11,12,11). c(12,12,11).
> EOF
clingo version 5.1.0
Reading from plant.lp ...
Solving...
Answer: 1
c(1,1,1) c(2,1,1) c(3,1,1) c(4,1,1) c(5,1,1) c(6,1,2) c(7,1,3) c(8,1,3) c(9,1,3) c(10,1,3) c(11,1,4) c(12,1,4) c(1,2,1) c(2,2,1) c(3,2,1) c(4,2,1) c(5,2,1) c(6,2,2) c(7,2,3) c(8,2,3) c(9,2,3) c(10,2,3) c(11,2,4) c(12,2,4) c(1,3,1) c(2,3,1) c(3,3,1) c(4,3,1) c(5,3,1) c(6,3,2) c(7,3,2) c(8,3,2) c(9,3,2) c(10,3,4) c(11,3,4) c(12,3,4) c(1,4,5) c(2,4,5) c(3,4,5) c(4,4,1) c(5,4,6) c(6,4,6) c(7,4,6) c(8,4,7) c(9,4,2) c(10,4,7) c(11,4,8) c(12,4,8) c(1,5,5) c(2,5,5) c(3,5,1) c(4,5,1) c(5,5,6) c(6,5,6) c(7,5,6) c(8,5,7) c(9,5,2) c(10,5,7) c(11,5,8) c(12,5,8) c(1,6,5) c(2,6,5) c(3,6,6) c(4,6,6) c(5,6,6) c(6,6,6) c(7,6,6) c(8,6,7) c(9,6,7) c(10,6,7) c(11,6,8) c(12,6,8) c(1,7,5) c(2,7,5) c(3,7,5) c(4,7,6) c(5,7,9) c(6,7,10) c(7,7,6) c(8,7,6) c(9,7,7) c(10,7,8) c(11,7,8) c(12,7,8) c(1,8,9) c(2,8,9) c(3,8,5) c(4,8,9) c(5,8,9) c(6,8,10) c(7,8,10) c(8,8,10) c(9,8,10) c(10,8,11) c(11,8,8) c(12,8,8) c(1,9,9) c(2,9,9) c(3,9,9) c(4,9,9) c(5,9,9) c(6,9,10) c(7,9,10) c(8,9,10) c(9,9,10) c(10,9,11) c(11,9,8) c(12,9,11) c(1,10,12) c(2,10,12) c(3,10,10) c(4,10,10) c(5,10,10) c(6,10,10) c(7,10,10) c(8,10,10) c(9,10,10) c(10,10,11) c(11,10,11) c(12,10,11) c(1,11,12) c(2,11,12) c(3,11,12) c(4,11,12) c(5,11,12) c(6,11,12) c(7,11,11) c(8,11,11) c(9,11,11) c(10,11,11) c(11,11,11) c(12,11,11) c(1,12,12) c(2,12,12) c(3,12,12) c(4,12,12) c(5,12,12) c(6,12,12) c(7,12,11) c(8,12,11) c(9,12,11) c(10,12,11) c(11,12,11) c(12,12,11) t(1,7) t(1,9) t(2,3) t(2,11) t(3,5) t(3,8) t(4,10) t(4,12) t(5,5) t(5,8) t(6,2) t(6,10) t(7,4) t(7,12) t(8,2) t(8,6) t(9,4) t(9,11) t(10,1) t(10,6) t(11,3) t(11,9) t(12,1) t(12,7)
SATISFIABLE

Models       : 1+
Calls        : 1
Time         : 0.009s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time     : 0.000s

Để làm cho định dạng đầu vào / đầu ra dễ xử lý hơn, đây là các chương trình Python để chuyển đổi từ và sang định dạng được đưa ra trong thử thách.

Đầu vào

import sys
print(' '.join("c({},{},{}).".format(x + 1, y + 1, ord(cell) - ord('a') + 1) for y, row in enumerate(sys.stdin.read().splitlines()) for x, cell in enumerate(row)))

Đầu ra

import re
import sys
for line in sys.stdin:
    c = {(int(x), int(y)): int(z) for x, y, z in re.findall(r'\bc\((\d+),(\d+),(\d+)\)', line)}
    if c:
        t = {(int(x), int(y)) for x, y in re.findall(r'\bt\((\d+),(\d+)\)', line)}
        n, n = max(c)
        for y in range(1, n + 1):
            print(''.join(chr(ord('aA'[(x, y) in t]) + c[x, y] - 1) for x in range(1, n + 1)))
        print()

Có vẻ như chúng tôi đang cần một trường hợp thử nghiệm lớn hơn. Btw, bạn sẽ chiến thắng phiên bản golf của câu hỏi này - chỉ cần 2 giây thay đổi thành 1 giây.
Dave

Thời gian chính thức là 18 mili giây trên 12x12, tôi xin lỗi. Lỗi chính tả 1 ký tự, đó là rắc rối với chữ viết tắt.
isaacg

Chúng tôi đang ở trong một dưa chua, có lẽ bạn có thể giúp đỡ. Bạn có thể nghĩ ra bất kỳ cách nào để tạo ra các trường hợp câu đố lớn hơn không cần thiết không?
isaacg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.