N 여왕 여왕


21

여왕과 기사를 포함하는 잘 알려진 N- 퀸 문제의 변형이 있으며 "상당히 더 어렵다" 1 . 문제는 다음과 같습니다.

체스 판에 같은 수의 기사 ♞와 여왕 ♛를 놓아 조각이 다른 조각을 공격하지 않도록해야합니다. 보드에 놓을 수있는 최대 개수는 몇 개이며, 몇 가지 방법으로 할 수 있습니까?

챌린지에서는 3에서 32 사이 의 입력 n 이 제공됩니다 (언어에 가장 적합한 방식으로). 주어진 n 에 대해 위의 문제에 대한 해결책이 0 개 이상있을 수 있습니다. 해결책이 없으면 아무것도 출력 / 반환 하지 않아야합니다 ( nil , empty string , false , ...). 그렇지 않으면 두 가지 결과를 제공해야합니다.

  1. 크기 n에 대한 솔루션 보드 (아래 참조) 는 공격을받지 않고 여왕이나 기사 체스 조각을 추가 할 수 없습니다. 같은 수의 여왕과 기사가 있어야합니다 .
  2. 입력을받지 않고 (i) 동일한 크기의 동일한 크기 n에 대해 다른 솔루션 (또는 아무것도 없음 ) 과 (ii) 다음 솔루션에 대한 다른 프로그램을 제공하는 프로그램의 소스 ...).

참고 :

  • 일련의 프로그램은 동일한 보드를 두 번 반환해서는 안되며, 크기 n 의 문제에 대한 가능한 모든 솔루션을 포함해야 하며 결국 종료해야합니다 (출력 없음).
  • 두 개의 값을 반환하거나 하나를 반환하고 다른 값을 인쇄하거나 두 개의 반환 값을 인쇄 할 수 있습니다.
  • 그러나 보드와 다음 프로그램을 모두 인쇄하는 경우 보드가 다음 프로그램의 일부로 간주되어서는 안됩니다 (보드를 주석으로 인쇄하거나 표준 출력 및 오류 스트림을 모두 사용하는 것이 좋습니다).
  • 반환 값으로 프로그램은 클로저가 아닌 문자열이어야합니다.

보드 형식

  • 보드는 n 크기의 제곱입니다 .
  • 보드 셀은 비어 있거나 여왕 또는 기사가 될 수 있습니다.
  • 각 셀 종류에 대해 고유 한 값을 선택해야합니다 (즉, 보드를 인쇄 할 때 Q, N 이외의 다른 기호를 사용할 수 있음).
  • 문자열이 아닌 보드를 반환하는 경우 보드 의 n 2 값 (예 : 행렬, 벡터 또는 행 / 열 주요 순서의 목록) 의 순서지정된 모음 이어야합니다 .
  • 보드를 인쇄하는 경우 사각형으로 인쇄하거나 선으로 인쇄 할 수 있습니다. 예를 들어, 크기가 4 인 솔루션 보드는 다음과 같이 인쇄 할 수 있습니다 (필요하지 않은 공간, 재량에 따라 기호).

    Q - - -
    - - - -
    - - - -
    - - N -
    

    느낌이 들면 다음과 같이 출력 할 수도 있습니다.

    ♛ · · ·
    · · · ·
    · · · ·
    · · ♞ ·
    

    ...하지만 이것으로 충분합니다 :

    Q-------------N-
    

    대칭 솔루션이 있기 때문에 행 주요 또는 열 주요 순서로 셀을 반복하는 것은 중요하지 않습니다. 예를 들어, n = 4에 대한 솔루션은 다음과 같습니다.

    Q------N--------
    Q----------N----
    Q------------N--
    Q-------------N-
    -Q----------N---
    -Q------------N-
    -Q-------------N
    --Q---------N---
    --Q----------N--
    --Q------------N
    ---QN-----------
    ---Q----N-------
    ---Q---------N--
    ---Q----------N-
    ---NQ-----------
    ----Q------N----
    ----Q----------N
    N------Q--------
    -------QN-------
    -------Q----N---
    ---N----Q-------
    -------NQ-------
    --------Q------N
    N----------Q----
    ----N------Q----
    -----------QN---
    -N----------Q---
    --N---------Q---
    -------N----Q---
    -----------NQ---
    N------------Q--
    --N----------Q--
    ---N---------Q--
    N-------------Q-
    -N------------Q-
    ---N----------Q-
    -N-------------Q
    --N------------Q
    ----N----------Q
    --------N------Q
    

n = 5에 대한 해를 행렬로 볼 수도 있습니다 . 보드가 포함되어 #, qn다른 종류의 빈 셀이있는 기호는, (내 대답은 아래 참조). Sleafar의 답변에서와 같이 n = 6에 2836 보드 를 계산합니다 (바이트 수를 줄일 때 버그가 발생했지만 지금은 수정되었습니다).

내 코드에서 하나 이상의 버그를 발견 한 Sleafar에게 감사드립니다.

점수

바이트 단위의 최단 코드가 이깁니다.

첫 번째 프로그램의 크기 인 n을 측정 합니다.


1 . Roger KW Hui의 Queens and Knights (솔루션 포함)


4
어쩌면 이것에 현상금을 넣어야 할 수도 있습니다. 솔직히 말해서 문제는 퀴네 부분이 없으면 충분하지 않습니다.
mbomb007

Q, N 및-이외의 기호를 사용하여 Queens and Knights를 나타내며 구별되지 않는 한 비울 수 있습니까?
Fatalize

@Fatalize 예, 물론
coredump

1
@coredump 함수의 내용을 읽는 것을 의미했습니다. 그리고 이것을 "예, 여러분은 자신의 소스 코드 및 / 또는 기능 내용을 읽을 수 있습니다"라고 생각합니다. (내 솔루션은 그것에 의존하므로 ...)
wizzwizz4

1
@coredump 문제를 올바르게 이해하면 n = 6에 대한 참조 솔루션에 잘못된 항목이 포함됩니다 (예 : -------------------------N--------Q-더 많은 조각을 추가 할 수 있기 때문에 유효하지 않음 :) Q--------N---------------N--------Q-.
Sleafar

답변:


2

그루비, 515 바이트

X=0;Y="N="+args[0]+";M=N*N;S=[];def f(b,i,j,v){(i..<j).findAll{k->!(0..<M).any{l->w=b[l];r=(k.intdiv(N)-l.intdiv(N)).abs();c=(k%N-l%N).abs();s=v+w;w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))}}.collect{a=b.clone();a[it]=v;[it,a]}};def r(b,q,n){f(b,q,M,1).each{i->f(i[1],n,M,2).each{j->if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){r(j[1],i[0],j[0])}else{S.add(j[1])}}}};r(new int[M],0,0);if(x<S.size()){sprintf('//%s%cX=%d;Y=%c%s%c;print(Eval.xy(X,Y,Y))',S[x].toString(),10,x+1,34,y,34)}else{''}";print(Eval.xy(X,Y,Y))

테스팅

명령 행 인수로 n 을 제공하십시오 .

groovy qak.groovy 4

출력의 첫 번째 줄은 항상 주석 (0 = 빈, 1 = 여왕, 2 = 기사)의 솔루션이며 두 번째 줄의 코드는 다음과 같습니다.

//[1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]
X=1;Y="N=4;M=N*N;S=[];def f(b,i,j,v){(i..<j).findAll{k->!(0..<M).any{l->w=b[l];r=(k.intdiv(N)-l.intdiv(N)).abs();c=(k%N-l%N).abs();s=v+w;w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))}}.collect{a=b.clone();a[it]=v;[it,a]}};def r(b,q,n){f(b,q,M,1).each{i->f(i[1],n,M,2).each{j->if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){r(j[1],i[0],j[0])}else{S.add(j[1])}}}};r(new int[M],0,0);if(x<S.size()){sprintf('//%s%cX=%d;Y=%c%s%c;print(Eval.xy(X,Y,Y))',S[x].toString(),10,x+1,34,y,34)}else{''}";print(Eval.xy(X,Y,Y))

다음 스크립트는 자동 테스트에 사용될 수 있습니다 ( n 은 인수로 다시 제공됨).

#!/bin/bash
set -e
test -n "$1"
groovy qak.groovy "$1" > t
while test -s t; do
    head -n1 t
    groovy t > t2
    mv t2 t
done

솔루션을 최대한 작게 만들려고했기 때문에 속도매우 느립니다 (자세한 내용은 아래 참조). 이 버전에서는 n = 4 만 테스트하여 퀀 화가 작동하는지 확인했습니다.

결과

n = 4 : 40 솔루션 ( 변환 된 형식 )
n = 5 : 172 솔루션 ( 변환 된 형식 )
n = 6 : 2836 솔루션 ( 변환 된 형식 )

연산

이것은 약간 ungolfed 비 Quine 버전의 솔루션입니다.

N=args[0] as int
M=N*N
S=[]

/**
 * Generate a list of valid posibilities to place a new piece.
 * @param b Starting board.
 * @param i Start of the index range to check (inclusive).
 * @param j End of the index range to check (exclusive).
 * @param v Value of the new piece (1=queen, 2=knight).
 * @return A pair with the index of the new piece and a corresponding board for each possibility.
 */
def f(b,i,j,v){
    (i..<j).findAll{k->
        !(0..<M).any{l->
            w=b[l]
            r=(k.intdiv(N)-l.intdiv(N)).abs()
            c=(k%N-l%N).abs()
            s=v+w
            w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))
        }
    }.collect{
        a=b.clone();a[it]=v;[it,a]
    }
}

/**
 * Recursively look for solutions.
 * @param b Starting board.
 * @param q Start of the index range to check for queens.
 * @param n Start of the index range to check for knights.
 */
def r(b,q,n){
    f(b,q,M,1).each{i->
        f(i[1],n,M,2).each{j->
            if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){
                r(j[1],i[0],j[0])
            }else{
                S.add(j[1])
            }
        }
    }
}

r(new int[M],0,0)
S.each{println(it)}

Quineification

코드 크기를 작게 유지하기 위해 매우 간단한 접근 방식을 사용했습니다.

X=0;Y="...";print(Eval.xy(X,Y,Y))

변수 X 는 다음에 인쇄 할 솔루션의 색인을 보유합니다. Y 는 위의 알고리즘의 수정 된 사본을 보유하고 있는데, 이는 모든 솔루션 을 계산 한 다음 그 중 하나만 선택 하는 데 사용 되므로 속도가 느립니다. 이 솔루션의 장점은 추가 코드가 많이 필요하지 않다는 것입니다. Y에 저장된 코드 는 Eval 클래스의 도움으로 실행됩니다 (진정한 키인은 필요하지 않음).

수정 된 코드가 가리키는 솔루션 인쇄 X를 , 증가 X을 하고 자신의 복사본을 추가합니다 :

//[...]
X=1;Y="...";print(Eval.xy(X,Y,Y))

또한 두 번째 단계의 코드로 모든 솔루션을 출력하려고 시도했지만 n = 6의 경우 Groovy가 처리하기에는 너무 많은 코드가 생성되었습니다.


좋은 대답, 잘 했어
coredump

6

커먼 리스프, 737

자기 답

(lambda(n &aux(d 1))#2=(catch'$(let((s(* n n))(c d))(labels((R(w % @ b ! &aux r h v a)(loop for u from % below s do(setf h(mod u n)v(floor u n)a #4=(aref b u))(when(< 0(logand a w)4)(and(= 6 w)!(throw'! t))(let((b(copy-seq b))(o 5))(loop for(K D)on'(-1 -2 -1 2 1 -2 1 2)for y =(+ K v)for x =(+(or D -1)h)for u =(and(< -1 y n)(< -1 x n)(+(* y n)x))if u do #1=(if(< #4#4)(setf #4#(logand #4#o(if(= w o)3 0)))))(#8=dotimes(y N)(#8#(x N)(let((u(+(* y n)x))(o 6))(if(or(= x h)(= y v)(=(abs(- h x))(abs(- v y))))#1#))))(setf #4#w r(or(cond((= w 5)(R 6 @ U b !))((R 5 @ U b())t)((catch'!(R 5 0 0 b t))t)(t(and(=(decf c)0)(incf d)(or(format t"~%(lambda(&aux(n ~A)(d ~A))~%~S)"n d'#2#)(throw'$ B)))t))r)))))r))(R 5 0 0(fill(make-array s)3)())))))

함수 객체를 반환하는 REPL에 위의 내용을 붙여 넣습니다.

#<FUNCTION (LAMBDA (N &AUX (D 1))) {1006D1010B}>

그것을 호출하십시오 (별은 마지막 반환 값에 바인딩됩니다).

QN> (funcall * 4)

표준 출력에 다음을 인쇄합니다.

(lambda(&aux(n 4)(d 2))
#1=(CATCH '$
 (LET ((S (* N N)) (C D))
   (LABELS ((R (W % @ B ! &AUX R H V A)
              (LOOP FOR U FROM % BELOW S
                    DO (SETF H (MOD U N)
                             V (FLOOR U N)
                             A #2=(AREF B U)) (WHEN (< 0 (LOGAND A W) 4)
                                                (AND (= 6 W) !
                                                     (THROW '! T))
                                                (LET ((B (COPY-SEQ B))
                                                      (O 5))
                                                  (LOOP FOR (K D) ON '(-1
                                                                       -2
                                                                       -1 2
                                                                       1 -2
                                                                       1 2)
                                                        FOR Y = (+ K V)
                                                        FOR X = (+
                                                                 (OR D -1)
                                                                 H)
                                                        FOR U = (AND
                                                                 (< -1 Y N)
                                                                 (< -1 X N)
                                                                 (+ (* Y N)
                                                                    X))
                                                        IF U
                                                        DO #3=(IF (< #2# 4)
                                                                  (SETF #2#
                                                                          (LOGAND
                                                                           #2#
                                                                           O
                                                                           (IF (=
                                                                                W
                                                                                O)
                                                                               3
                                                                               0)))))
                                                  (DOTIMES (Y N)
                                                    (DOTIMES (X N)
                                                      (LET ((U
                                                             (+ (* Y N) X))
                                                            (O 6))
                                                        (IF (OR (= X H)
                                                                (= Y V)
                                                                (=
                                                                 (ABS
                                                                  (- H X))
                                                                 (ABS
                                                                  (- V
                                                                     Y))))
                                                            #3#))))
                                                  (SETF #2# W
                                                        R
                                                          (OR
                                                           (COND
                                                            ((= W 5)
                                                             (R 6 @ U B !))
                                                            ((R 5 @ U B
                                                                NIL)
                                                             T)
                                                            ((CATCH '!
                                                               (R 5 0 0 B
                                                                  T))
                                                             T)
                                                            (T
                                                             (AND
                                                              (= (DECF C)
                                                                 0)
                                                              (INCF D)
                                                              (OR
                                                               (FORMAT T
                                                                       "~%(lambda(&aux(n ~A)(d ~A))~%~S)"
                                                                       N D
                                                                       '#1#)
                                                               (THROW '$
                                                                 B)))
                                                             T))
                                                           R)))))
              R))
     (R 5 0 0 (FILL (MAKE-ARRAY S) 3) NIL)))))

또한이 함수가 반환하는 값은 다음과 같습니다.

#(5 0 0 0 0 0 0 6 0 0 0 2 0 2 0 0)

... 배열 리터럴입니다. 숫자 5는 여왕을 나타내고, 6은 기사를 나타내고 다른 것은 내부에 더 많은 정보가 저장되어있는 것을 제외하고는 빈 칸을 나타냅니다. 반환 된 함수를 repl에 복사하여 붙여 넣으면 새로운 함수를 얻습니다.

#<FUNCTION (LAMBDA (&AUX (N 4) (D 2))) {100819148B}>

그리고 우리는 논쟁없이 그것을 부를 수 있습니다 :

QN> (funcall * )

이 호출은 새로운 솔루션 #(5 0 0 0 0 0 0 2 0 0 0 6 0 0 2 0)과 다른 함수의 소스를 반환 합니다 (여기에 표시되지 않음). 원래 함수 또는 마지막으로 생성 된 함수가 솔루션을 찾지 못하면 아무것도 인쇄되지 않으며 아무것도 리턴되지 않습니다.

내부 가치

|----------+--------+---------+--------+-----------------|
|          | Binary | Decimal | Symbol | Meaning         |
|----------+--------+---------+--------+-----------------|
| Empty    |    000 |       0 | -      | safe for none   |
|          |    001 |       1 | q      | safe for queen  |
|          |    010 |       2 | n      | safe for knight |
|          |    011 |       3 | #      | safe for both   |
|----------+--------+---------+--------+-----------------|
| Occupied |    101 |       5 | Q      | a queen         |
|          |    110 |       6 | K      | a knight        |
|----------+--------+---------+--------+-----------------|

솔루션을 너무 적게 생성했습니다. 이제 저는 여왕과 기사에게 어떤 세포가 안전한지 독립적으로 전파합니다. 예를 들어, 다음은 꽤 인쇄 된 n = 5의 출력입니다.

Q - - - - 
- - - n N 
- q - n n 
- # n - n 
- n # # - 

우리가 여왕을 배치했을 때 Q,이 여왕으로부터 기사가 떨어져있는 위치는 여전히 여왕에게 안전하며 표시되어 q있습니다. 마찬가지로, 여왕 만이 접근 할 수있는 기사는 다른 기사에게 안전합니다. 비트 값이다 가능한 움직임을 나타내는 -ed 일부 세포 조각없는 종류로 연결할 수 있습니다.

보다 정확하게, 여기에 자유 셀이 다른 값으로 점차 제한되는 다음 솔루션 (왼쪽에서 오른쪽으로)으로 이어지는 일련의 보드가 있습니다.

# # # # # #     q - - - q #     - - - - - #     - - - - - #     - - - - - n
# # # # # #     - - Q - - -     - - Q - - -     - - Q - - -     - - Q - - -
# # # # # #     q - - - q #     q - - - - -     Q - - - - -     Q - - - - -
# # # # # #     - q - q - #     - q - - - n     - - - - - n     - - - - - n
# # # # # #     # # - # # -     n n - n N -     - - - n N -     - - - - N -
# # # # # #     # # - # # #     # # - n n n     - # - - n n     - n - - n N

비퀸 접근

Ungolfed, 댓글 버전

(defun queens-and-knights
    (n    ; size of problem
     fn   ; function called for each solution

     ;; AUX parameters are like LET* bindings but shorter.
     &aux
       ;; total number of cells in a board
       (s (* n n)))

  (labels
      ;; Define recursive function R
      ((R (w      ; what piece to place: 5=queen, 6=knight 
           %      ; min position for piece of type W
           @      ; min position for the other kind of piece
           b      ; current board
           !      ; T iff we are in "check" mode (see below)
           &aux  
           r      ; result of this function: will be "true" iff we can
                  ; place at least one piece of type W on the board b
           h      ; current horizontal position 
           v      ; current vertical position
           a      ; current piece at position (h,v)
           )

         (loop
            ;; only consider position U starting from position %,
            ;; because any other position below % was already visited
            ;; at a higher level of recursion (e.g. the second queen
            ;; we place is being placed in a recursive call, and we
            ;; don't visit position before the first queen).
            for u from % below s

            do
              (setf h (mod u n)         ; Intialize H, V and A
                    v (floor u n)       ; 
                    a (aref b u))       ; 

            ;; Apply an AND mask to current value A in the board
            ;; with the type of chess piece W. In order to consider
            ;; position U as "safe", the result of the bitwise AND
            ;; must be below 4 (empty cell) and non-null.
              (when (< 0 (logand a w) 4)

                ;; WE FOUND A SAFE PLACE TO PUT PIECE W

                (when (and ! (= 6 w))
                  ;; In "check" mode, when we place a knight, we knwo
                  ;; that the check is successful. In other words, it
                  ;; is possible to place an additional queen and
                  ;; knight in some board up the call stack. Instead
                  ;; of updating the board we can directly exit from
                  ;; here (that gave a major speed improvement since
                  ;; we do this a lot). Here we do a non-local exit to
                  ;; the catch named "!".
                  (throw '! t))

                ;; We make a copy of current board b and bind it to the
                ;; same symbol b. This allocates a lot of memory
                ;; compared to the previous approach where I used a
                ;; single board and an "undo" list, but it is shorter
                ;; both in code size and in runtime.
                (let ((b (copy-seq b)))

                  ;; Propagate knights' constraints
                  (loop
                     ;; O is the other kind of piece, i.e. queen here
                     ;; because be propagate knights. This is used as
                     ;; a mask to remove knights pieces as possible
                     ;; choices.
                     with o = 5

                     ;; The list below is arranged so that two
                     ;; consecutive numbers form a knight-move. The ON
                     ;; iteration keyword descend sublist by sublist,
                     ;; i.e. (-1 -2), (-2 -1), (-1 2), ..., (2 NIL). We
                     ;; destructure each list being iterated as (K D),
                     ;; and when D is NIL, we use value -1.
                     for (K D) on '(-1 -2 -1 2 1 -2 1 2)

                     ;; Compute position X, Y and index U in board,
                     ;; while checking that the position is inside the
                     ;; board.
                     for y = (+ K v)
                     for x = (+ (or D -1) h)
                     for u = (and (< -1 y n)
                                  (< -1 x n)
                                  (+(* y n)x))

                     ;; if U is a valid position...
                     if u
                     do
                     ;; The reader variable #1# is affected to the
                     ;; following expression and reused below for
                     ;; queens. That's why the expression is not
                     ;; specific to knights. The trick here is to
                     ;; use the symbols with different lexical
                     ;; bindings.
                       #1=(when (< (aref b u) 4) ; empty?
                            (setf (aref b u)

                                  (logand
                                   ;; Bitwise AND of current value ...
                                   (aref b u)

                                   ;; ... with o: position U is not a
                                   ;; safe place for W (inverse of O)
                                   ;; anymore, because if we put a W
                                   ;; there, it would attack our
                                   ;; current cell (H,V).
                                   o

                                   ;; ... and with zero (unsafe for
                                   ;; all) if our piece W is also a
                                   ;; knight (resp. queen). Indeed, we
                                   ;; cannot put anything at position
                                   ;; U because we are attacking it.
                                   (if (= w o) 3 0)))))

                  ;; Propagate queens' constraints
                  (dotimes (y N)
                    (dotimes (x N)
                      (let ((u(+(* y n)x))(o 6))
                        (if (or (= x h)
                                (= y v)
                                (= (abs(- h x)) (abs(- v y))))

                            ;; Same code as above #1=(if ...)
                            #1#))))

                  (setf
                   ;; Place piece
                   (aref b u) w

                   ;; Set result value
                   r (or (cond
                           ;; Queen? Try to place a Knight and maybe
                           ;; other queens. The result is true only if
                           ;; the recursive call is.
                           ((= w 5) (R 6 @ U b !))

                           ;; Not a queen, so all below concern   
                           ;; knights: we always return T because
                           ;; we found a safe position.
                           ;; But we still need to know if
                           ;; board B is an actual solution and 
                           ;; call FN if it is.
                           ;; ------------------------------------

                           ;; Can be place a queen too? then current
                           ;; board is not a solution.
                           ((R 5 @ U b()) t)

                           ;; Try to place a queen and a knight
                           ;; without constraining the min positions
                           ;; (% and @); this is the "check" mode that
                           ;; is represented by the last argument to
                           ;; R, set to T here. If it throws true,
                           ;; then board B is a duplicate of a
                           ;; previous one, except that it is missing
                           ;; pieces due to constraints % and @. The
                           ;; "check" mode is a fix to a bug where we
                           ;; reported as solutions boards where there
                           ;; was still room for other pieces.
                           ((catch'!(R 5 0 0 b t)) t)

                           ;; Default case: we could not add one more
                           ;; layer of pieces, and so current board B
                           ;; is a solution. Call function FN.
                           (t (funcall fn b) t))

                         ;; R keeps being true if it already was for
                         ;; another position.
                         r)))))

         ;; Return result R
         r))

    ;; Start search with a queen and an empty board.
    (R 5 0 0 (fill (make-array s) 3)  nil)))

중복 및 버그

내 첫 번째 솔루션은 중복 솔루션을 출력했습니다. 이를 해결하기 위해 여왕과 기사를위한 두 개의 카운터를 소개했습니다. 여왕 (기사 기사) 카운터는 여왕 (기사 기사)이 존재하는 보드의 첫 번째 위치를 추적합니다. 나는 그 최소 위치를 따르는 위치에만 여왕 (기사 기사)을 추가합니다.

이 방법을 사용하면 이전 반복에서 이미 발견 된 솔루션을 다시 방문하지 못하게됩니다. 왜냐하면 여왕의 위치가 증가함에 따라 반복하기 때문입니다.

그러나 Sleafar는 여왕과 기사를위한 방이있을 수있는 해결책이 있다는 것을 알아 차 렸습니다. 잠시 동안 나는 정상적인 검색으로 되돌리고 중복을 방지하기 위해 알려진 모든 솔루션을 저장해야했습니다.

대신에, 여기에 내가 지금 무엇을 : 잠재적 인 솔루션 보드가 발견되었을 때, 나는 정확히 추가하려고 여왕과 하나 개 (보드의 모든 셀에 대한 예) 계정으로 카운터를 복용하지 않고, 기사. 이것이 가능하다면 현재 보드는 이전 보드와 중복되며 해결책을 거부합니다.

테스트

|---+---------+------------+--------------|
| N |  boards |    seconds |        bytes |
|---+---------+------------+--------------|
| 3 |       0 |          0 |        32768 |
| 4 |      40 |          0 |       360416 |
| 5 |     172 |          0 |      3440016 |
| 6 |    2836 |   0.085907 |     61251584 |
| 7 |   23876 |   1.265178 |    869666288 |
| 8 |  383586 |  24.991300 |  17235142848 |
| 9 | 6064506 | 524.982987 | 359952648832 |
|---+---------+------------+--------------|

Quine-ification

나는 연속적인 quine을 만들기 위해 다른 아이디어를 가지고있었습니다. 가장 쉬운 방법은 모든 솔루션을 먼저 문자열 목록으로 생성하고 각 세대마다 해당 목록에서 나타나는 순차적 퀴인을 작성하는 것입니다. 그러나 이것은 현재의 접근법보다 짧지 않은 것으로 보입니다. 또는 사용자 정의 스택으로 재귀 코드를 다시 작성하고 솔루션을 찾을 때마다 모든 상태 변수를 덤프하려고했습니다. 목표는 다음 단계가 현재 단계의 연속으로 처리 될 수 있다는 것입니다. 아마도 이것은 스택 기반 언어에 더 적합 할 것입니다. 현재는 매우 간단하고 항상 사용하기 쉬운 Common Lisp 판독기 변수에 의존합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.