공원에 나무 심기-최대한 빨리!


20

이 도전은 이 앱에서 영감을 얻은 것입니다 . 테스트 사례는 해당 앱에서 차용됩니다.


이는 문제이며, 가장 큰 테스트 사례를 최소한의 시간 안에 해결하는 것이 목표입니다. 사람들이 알고리즘을 더 빠르게 테스트 할 수 있도록 더 작은 테스트 사례가 제공됩니다.


크기가 n x n 인 정사각형 입력 그리드가 제공되며 여기서 9 <= n <= 12 입니다. 이 그리드는 각 영역의 셀에 고유 식별자가있는 n 개의 영역 으로 나뉩니다 ( 여기에서 텍스트 에서 al의 소문자를 사용 하지만 정수 1-12 와 같이 원하는 것을 선택할 수 있습니다 ) .

입력은 다음과 같습니다 (선택적 입력 형식).

aabbbbbcc
adddbbbcc
adeeecccc
adddefgcc
hhhdifggg
hdddifffg
hhhiifffg
hihiifffg
iiiiiiggg

또는 더 쉽게 시각화 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

도전:

다음 규칙에 따라이 공원에 2 * n 나무 를 배치 해야합니다.

  • 정확히가 있어야한다 2 열당 나무, 그리고 2 행마다 나무
  • 모든 지역에는 정확히 2 그루의 나무 가 있어야합니다 .
  • 수직, 수평 또는 대각선으로 다른 나무에 인접한 나무는 없습니다.

위의 레이아웃에 대한 해결책은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

참고 : 각 퍼즐에는 하나의 솔루션 만 있습니다.

추가 규칙 :

  • 입력 및 출력 형식은 선택 사항입니다
    • 예를 들어 출력은 인덱스 목록, 해당 위치에 트리가 있는지를 나타내는 1/0이 있는 그리드 또는 트리가 표시된 입력의 수정 된 버전 일 수 있습니다.
  • 실행 시간은 결정적이어야합니다.
  • 프로그램은 @isaacg의 컴퓨터에서 1 분 안에 끝나야합니다
    • 사양 : CPU 4 개, i5-4300U CPU @ 1.9GHz, 7.5G RAM.
  • 프로그램이 1 분마다 두 개의 가장 큰 테스트 사례를 해결할 수없는 경우 두 번째로 큰 시간 ( n = 11 )이 점수가됩니다. 가장 큰 경우를 해결하는 솔루션을 잃게됩니다.

테스트 사례 :

제출물이 이러한 테스트 사례에 맞게 사용자 정의 된 것으로 보이면이 목록을 편집 할 수 있습니다.

12x12 :

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

11x11 :

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

10x10

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

9x9

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

"입력 및 출력 형식은 선택 사항이지만 동일해야합니다."무슨 의미입니까? 영역을 출력하지 않고 나무와 나무가 아닌 나무에 대해 1과 0을 포함하는 목록을 출력 할 수 없습니까?
치명적인

@Fatalize, 편집했습니다. 나는 당신이 제안한대로 인덱스 목록이나 1/0으로 그리드를 출력하는 것이 좋은 생각이라고 생각합니다.
Stewie Griffin

1
정보 (정확하게 계산하는 경우) : 12 * 12 그리드에 24 개의 나무를 배치하기위한 구성은 3647375398569086976입니다 (1) : There shall be exactly 2 trees per column, and 2 trees per row.
user202729

"큰 문제가되지 않아야합니다" : 개인적으로 생각합니다. 내 현재 구현은 ~ 150ms의 첫 번째 테스트 사례와 5 초의 세 번째 테스트 사례를 해결하지만 합리적인 시간 내에 마지막 사례 ( '11x11 만')를 해결하지 못합니다. 1 분 이내에 완료하려면 훨씬 더 적극적인 정방향 정리 (따라서 상당한 양의 추가 코드)가 필요할 수 있습니다.
Arnauld

1
@ Arnauld, 최대 테스트 사례이므로 최대 값을 11로 변경했습니다. 솔루션을 유효하고 경쟁적인 제출물로 게시 할 수 있지만 코드 길이에 관계없이 모든 테스트 사례를 해결하는 솔루션을 게시하는 경우에는 이기지 못합니다. 공정한?
Stewie Griffin

답변:


7

자바 스크립트 (ES6), 271 바이트

문자 배열로 입력을받습니다. 각 행에서 트리의 위치를 ​​설명하는 비트 마스크 (정수)의 배열을 반환합니다. 여기서 최하위 비트는 가장 왼쪽 위치입니다.

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]

형식화 및 의견

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

테스트 사례

이 스 니펫에는 결과를보다 읽기 쉬운 형식으로 표시하는 추가 기능이 포함되어 있습니다. 마지막 테스트 사례를 해결하기에는 너무 느립니다.

예상 런타임 : ~ 5 초


OP의 메모 :이 제출은 챌린지가 코드 골프 챌린지 일 때 이루어졌습니다. 따라서 현재이기는 기준에 최적화되어 있지 않아도 완벽하게 유효합니다!
Stewie Griffin

타이밍 : 11x11에서 1 분 이상 걸립니다.
isaacg 2016 년

우리는 피클에 있습니다. 어쩌면 당신은 도울 수 있습니다. 사소한 더 큰 퍼즐 인스턴스를 생성하는 방법을 생각할 수 있습니까?
isaacg 2016 년

7

C, 공식 시간 : 12x12의 경우 5ms

#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;
}

-O3-fopenmp플래그를 사용하여 GCC 7로 컴파일되었습니다 . OpenMP가 설치된 모든 버전의 GCC에서 비슷한 결과를 가져야합니다.

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

입력 및 출력 형식은 질문에 나와 있습니다.

내 컴퓨터 에서는 12x12 예제의 경우 0.009s 0.008s 0.005s , 모든 예제를 실행하는 데 0.022s 0.020s 0.019s가 필요합니다 . 벤치 마크 시스템에서 isaacg는 12x12 예제에 대해 원래 (스레드되지 않은) 코드 버전을 사용하여 5ms를보고합니다.

용법:

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

한 번에 한 행씩 작업하는 단순한 무차별 솔버입니다. 불가능한 상황을 조기에 인식하여 좋은 속도로 실행됩니다 (예 : 지역 셀이 남아 있지 않지만 지역에서 2 개 미만의 나무).

첫 번째 업데이트는 관련 데이터를 메모리에 가깝게 배치하여 캐시 적중을 개선하고 세그먼트에서 남은 세그먼트 계산을 조금 더 스마트하게 만듭니다 (현재 트리가 인접 할 수 없다는 사실을 설명합니다). 또한 가장 바깥 쪽 루프를 추출하여 알고리즘의 가장 인기있는 부분에 필요한 경우가 더 적습니다.

두 번째 업데이트는 사용 가능한 프로세서 (OpenMP 사용)에서 가장 바깥 쪽 루프를 병렬로 실행하여 선형 속도 향상을 제공합니다. 스폰 스레드의 오버 헤드가 더 작은 그리드의 이점보다 크기 때문에 n> = 11에 대해서만 활성화됩니다.


공식 타이밍 : 12x12의 경우 5ms 다른 사람이 가까워지면 더 큰 테스트 사례가 필요합니다.
isaacg 2016 년

우리는 피클에 있습니다. 어쩌면 당신은 도울 수 있습니다. 사소한 더 큰 퍼즐 인스턴스를 생성하는 방법을 생각할 수 있습니까?
isaacg 2016 년

@isaacg 그림의 예에서 보듯이 원래 그리드는 나무를 먼저 배치하여 (이 예제에서는 약간 변경 된 기사 패턴이지만 행과 열 당 2 개의 나무가있는 패턴은 작동 할 것입니다.) 각 지역에 2 개의 나무가 있습니다. 그런 식으로 인간이 임의로 큰 격자를 따라갈 수있는 간단한 방법이어야합니다.
Dave

실제로 다시 살펴보면 약간의 변화가있는 기사 패턴이 아니라 각 트리가 이전과 오프셋 (1,2)되는 줄 바꿈 패턴입니다. 패턴이 있으면 행과 열을 치환하여 트리를 인접하게 두지 않는 한 구조화 된 솔루션을 만들 수 있습니다.
Dave

5

Java (OpenJDK 8) , 공식 타이밍 : 12x12의 1.2 초

편집 : 더 이상 코드 골프

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;
}

온라인으로 사용해보십시오!

TIO 링크는 12x12 테스트 사례를위한 것입니다. TIO는 런타임에 2.429를보고합니다.

정수 배열을 입력으로 취해 트리의 경우 1, 비트 리의 경우 0을 포함하도록 배열을 수정합니다.

이것은 모든 테스트 케이스에서 실행됩니다. 가장 강력한 테스트 케이스는 1 초 이내에 내 컴퓨터에서 실행되지만 꽤 강력한 컴퓨터가 있습니다.

12x12의 테스트 코드는 다른 사용자를 위해 수정할 수 있습니다

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));
    }

}

내 컴퓨터에서 이것을 생성합니다.

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]

OP의 메모 :이 제출은 챌린지가 코드 골프 챌린지 일 때 이루어졌습니다. 따라서 현재의이기는 기준에 최적화되지는 않았지만 완벽하게 유효합니다!
Stewie Griffin

의견을 보내 주셔서 감사합니다. 기회가된다면 코드 골프가 아니기 때문에 일부를 정리하고 일부 속도로 최적화 할 수 있는지
알아볼

공식 타이밍 : 12x12에서 1.2 초
isaacg 2016 년

우리는 피클에 있습니다. 어쩌면 당신은 도울 수 있습니다. 사소한 더 큰 퍼즐 인스턴스를 생성하는 방법을 생각할 수 있습니까?
isaacg 2016 년

4

Clingo , 12 × 12의 경우 ms 7ms, 116 바이트

{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).

줄 바꿈은 선택 사항이며 계산되지 않습니다.

그리드 크기가 clingo plant.lp - -c n=<n>어디에 있는지 실행하십시오 <n>. 입력 형식의 목록은 c(X,Y,Z).각각의 셀에 대한 구문 ( X, Y) 컬러 Z1 ≤와 X, Y, Zn, 선택적 공백으로 분리된다. t(X,Y)( X, Y) 에 각 트리에 대한 출력이 포함됩니다 .

시간은 기본적으로 시작 시간이므로 의미가 없으므로 더 큰 테스트 사례에 대한 투표로 간주하십시오.

데모

$ 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

입 / 출력 형식을보다 쉽게 ​​처리 할 수 ​​있도록 도전 과제에 지정된 형식으로 변환하는 Python 프로그램이 있습니다.

입력

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)))

산출

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()

더 큰 테스트 사례가 필요한 것 같습니다. Btw, 당신 은이 질문골프 버전을 이길 것입니다 – 2를 1로 바꾸면됩니다.
Dave

12x12의 공식 타이밍은 18 밀리 초입니다. 죄송합니다. 1 자 오타, 그것은 약어의 문제입니다.
isaacg 2016 년

우리는 피클에 있습니다. 어쩌면 당신은 도울 수 있습니다. 사소한 더 큰 퍼즐 인스턴스를 생성하는 방법을 생각할 수 있습니까?
isaacg 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.