반음계 퍼즐 풀기


35

Puzzling.SE 친구에게 다음 퍼즐이 게시되었습니다. 이 반음계 퍼즐은 항상 풀 수 있습니까? Edgar G에 의해. 당신은 여기에서 재생할 수 있습니다 .

퍼즐 설명

m x n세 가지 다른 색상의 타일이 있는 격자가 있으면 색상이 다른 두 개의 인접한 타일을 선택할 수 있습니다 . 그런 다음이 두 타일은 세 번째 색상, 즉이 두 타일로 표시되지 않은 하나의 색상으로 변환됩니다. 모든 타일의 색상이 같으면 퍼즐이 풀 립니다 . 분명히이 퍼즐은 3으로 나눌 수 없거나 나눌 수 없다면 항상 해결할 수 있음증명할 수 있습니다 .mn

8x8 3 색 퍼즐

물론 이것은 해결 알고리즘을 요구합니다. 이 퍼즐을 해결하는 기능이나 프로그램을 작성합니다. '부작용'이있는 함수 (즉, stdout일부 어색한 데이터 형식 반환 값이 아닌 출력이 켜져 있음 )가 명시 적으로 허용됩니다.

입출력

입력은 것 m x n정수 이루어진 행렬 1, 23(또는 0, 1, 2편리한 경우). 이 입력을 임의의 형식으로 가져올 수 있습니다. 둘 다 m하고 n있습니다 >1과 나눌 수없는 당신은 퍼즐을 가정 할 수있다 (3)에 의해 해결되지 않는다

그런 다음 퍼즐을 해결합니다. 여기에는 '변환'할 두 개의 인접한 타일을 반복해서 선택해야합니다 (위 참조). 해결 알고리즘이 수행 한 각 단계마다이 타일의 두 좌표를 출력합니다. 이것은 정상적인 출력 형식 일 수도 있습니다. 좌표의 0 기반 및 1 기반 색인화와 행 또는 열의 색인화 여부를 자유롭게 선택할 수 있습니다. 그러나 귀하의 답변에 이것을 언급하십시오.

알고리즘은 원래 8x8 사례에서 적절한 시간 내에 실행되어야합니다. 명시 적으로 허용되지 않습니다 완전히 브 루트 - 강제 알고리즘 아래에 실행해야합니다 즉 O(k^[m*(n-1)+(m-1)*n])k솔루션에 필요한 단계의 수. 그러나 솔루션 이 최적 일 필요 는 없습니다 . 링크 된 질문에 제공된 증거는이 작업을 수행하는 방법에 대한 아이디어를 제공 할 수 있습니다 (예 : 먼저 세로로 인접한 타일 만 사용하여 모든 열을 수행 한 다음 모든 행을 수행)

테스트 사례

이 테스트 사례에서는 좌표가 1 기반이며 행이 먼저 색인됩니다 (MATLAB / Octave 및 기타 여러 유형).

Input: 
[1 2]
Output: (result: all 3's)
[1 1],[1,2]


Input:
[ 1 2
  3 1 ]
Output: (result: all 1's)
[1 1],[2 1]        (turn left column into 2's)
[2 1],[2 2]        (turn right column into 3's)
[1 1],[1 2]        (turn top row into 1's)
[2 1],[2 2]        (turn bottom row into 1's)

Input:
[1 2 3 2
 3 2 1 1]

Output: (result: all 3's)
[1 1],[1 2] 
[1 3],[1 4] 
[1 2],[1 3] 
[1 1],[1 2] 
[1 2],[1 3] 
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]

원하는 경우 더 큰 테스트 사례의 페이스트 빈을 게시 할 수 있지만 충분하다고 생각합니다.


목표는 최소한의 움직임으로 퍼즐 세트를 해결하는 것이 목표 인 코드 챌린지 버전을보고 싶습니다.
Mego

@ Mego 나는 이것을 확실히 고려했다. 그러나 이것이 DFS 또는 BFS로 바뀌어 영원히 실행 되는 것이 두렵 습니다 . 또는이를 막기 위해 모호한 제한 사항 (예 : '1 시간 이내에 실행해야 함')은 대규모 컴퓨터 사용자에게 유리하거나 모든 솔루션을 테스트해야합니다. 또한 현재의 과제에는 여분의 제로가 없습니다. 휴리스틱 등을 요구하는 훨씬 더 어려운 버전이 더 인기가있을 것으로 의심됩니다. 설명하십시오.
Sanchises

나는 루아에서 그것을 시도 할 것이라고 생각하지만, 그것은 324 바이트 솔루션보다 길 수 있습니다 ^^
Katenkyo

@Katenkyo 알아낼 수있는 유일한 방법! 귀하의 솔루션을 기대하고 있습니다.
Sanchises

조금 슬프게도 기다려야 할 것입니다. 무차별 대입 솔루션을 막았 기 때문에 루아가 짧은 솔루션을 찾아야합니다. p
Katenkyo

답변:


5

루비, 266 바이트

옥타브 솔루션의 포트는 열 대신 행을 먼저 해결한다는 점을 제외하면 다소 그렇습니다. 입력은 배열의 배열이며 내부 배열은 행입니다. 출력 이동은입니다 [row, column, row, column]. 테스트 스위트

->m{t=->v{v.size*v.inject(:+)%3}
s=->a,x,r{g=t[a]
(q=(r=0..a.size-2).find{|i|a[i]!=a[i+1]&&g!=a[i]}||r.find{|i|a[i]!=a[i+1]}
a[q,2]=[t[a[q,2]]]*2
p r ?[x,q,x,q+1]:[q,x,q+1,x])while[]!=a-[g]}
m.size.times{|i|s[m[i],i,1]}
m=m.shift.zip *m
m.size.times{|i|s[m[i],i,p]}}

설명이 담겨 있지 않은

->m{                                  # Start lambda function, argument `m`
  t=->v{v.size*v.inject(:+)%3}        # Target color function
  s=->a,x,r{                          # Function to determine proper moves
                                      #   a = row array, x = row index, r = horizontal
    g=t[a]                            # Obtain target color
    (
      q=(r=0..a.size-2).find{|i|      # Find the first index `i` from 0 to a.size-2 where...
        a[i]!=a[i+1]                  # ...that element at `i` is different from the next...
        &&g!=a[i]                     # ...and it is not the same as the target color
      } || r.find{|i|a[i]!=a[i+1]}    # If none found just find for different colors
      a[q,2]=[t[a[q,2]]]*2            # Do the color flipping operation
      p r ?[x,q,x,q+1]:[q,x,q+1,x]    # Print the next move based on if `r` is truthy
    ) while[]!=a-[g]}                 # While row is not all the same target color, repeat
m.size.times{|i|                      # For each index `i` within the matrix's rows...
  s[m[i],i,1]                         # ...run the solving function on that row
                                      #   (`r` is truthy so the moves printed are for rows)
}
m=m.shift.zip *m                      # Dark magic to transpose the matrix
m.size.times{|i|s[m[i],i,p]}}         # Run the solving function on all the columns now
                                      #   (`r` is falsy so the moves printed are for columns)

골프가 아닌 두 언어 사이의 포트가 여전히 ~ 20 % 차이를 만들 수 있다는 점에 흥미가 있습니다. 간단한 설명을 추가해 주시겠습니까? (특히 3 행-비밀리에 intersect키워드가
너무

@sanchises 설명이 추가되었습니다. 에 관해서는 intersect, 루비가 find기본적으로 함수에서 작동하기 때문에 function키워드가 부피가 커서 내 작동 방식을 고칠 수 있는지 모르겠습니다 .
가치 잉크

실제로도 귀하의 방법을 사용할 수 있습니다 find-감사합니다! 아직도, 당신을 때리는 곳은 없습니다.
Sanchises

13

옥타브, 334313 바이트

도전은 다소 어려워 보일 수 있으므로 내 솔루션을 제시합니다. 나는이 방법이 효과가 있음을 공식적으로 증명하지는 않았지만 (알고리즘이 루프에 걸리지 않을 것이라는 것을 증명할 것이라고 생각한다), 지금까지는 15 초 이내에 100x100 테스트 케이스를 수행하면서 완벽하게 작동합니다. 몇 바이트를 절약 한 이후 모든 좌표를 반환하는 함수가 아닌 부작용이있는 함수를 사용하기로했습니다. 좌표는 행 주요, 1 기반이며 형식이 row1 col1 row2 col2입니다. 입력 색상은 0,1,2이 잘 작동하기 때문에 mod사용하지의 비용으로, numel보다 오히려 nnz. 골프 버전 : 편집 : Kevin Lau의 답변을 사용하여 몇 바이트를 더 절약했습니다.

function P(p)
k=0;[m,n]=size(p);t=@(v)mod(sum(v)*numel(v),3);for c=1:n
p(:,c)=V(p(:,c));end
k=1;for r=1:m
p(r,:)=V(p(r,:));end
function a=V(a)
while any(a-(g=t(a)))
isempty(q=find(diff(a)&a(1:end-1)-g,1))&&(q=find(diff(a),1));
a([q q+1])=t(a([q q+1]));if k
disp([r q r q+1])
else
disp([q c q+1 c])
end;end;end;end

해결 알고리즘의 GIF 예 :

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

언 골프 버전 :

function solveChromaticPuzzle(p)
[m,n]=size(p);                           % Get size
t=@(v)mod(sum(v)*numel(v),3);            % Target colour function
for c=1:n                                % Loop over columns
    p(:,c)=solveVec(p(:,c));             % Solve vector
end
for r=1:m                                % Loop over rows
    p(r,:)=solveVec(p(r,:));
end
    function a=solveVec(a)               % Nested function to get globals
        g=t(a);                          % Determine target colour
        while(any(a~=g))                 % While any is diff from target...
            % Do the finding magic. Working left-to-right, we find the
            % first pair that can be flipped (nonzero diff) that does not
            % have the left colour different from our goal colour
            q=min(intersect(find(diff(a)),find(a~=g)));
            if(isempty(q))               % In case we get stuck...
                q=find(diff(a),1);       % ... just flip the first possible
            end;
            a([q q+1])=t(a([q q+1]));    % Do the actual flipping.
            if(exist('r'))               % If we're working per row
                disp([r q r q+1])        % Print the pair, using global row
            else
                disp([q c q+1 c])        % Print the pari, using global col
            end
        end
    end
end

방금 알아 차 렸지만 제 이름은 Kenny Lau가 아닙니다. 다른 사용자이며 제 사용자 이름에 Kenny가 아니라고 명시되어 있습니다.
Value Ink

7

루아, 594 575 559 바이트

경고 I이 골프에 끝났어요 전에 여전히 작업 많이있다! 최소한 500 바이트 이하로 가져갈 수 있어야합니다. 현재로서는 이것이 첫 번째 해결책이며 여전히 노력하고 있습니다.

완료되면 전체 설명을 제공 할 것입니다.

function f(t)s=#t a=","for i=1,s do p=t[i]for i=1,s
do p.Q=p.Q and p.Q+p[i]or p[i]end p.Q=(p.Q*#p)%3 for i=1,s do for j=1,#p-1 do
x=p[j]y=p[j+1]u=x~=y and(p.S and p.R==p.S or x~=p.Q)v=(x+y)*2p[j]=u and v%3or x
p[j+1]=u and v%3or y print(i..a..j,i..a..j+1)end
p.R=p.S p.S=table.concat(p)end end
for i=1,s do Q=Q and Q+t[i][1]or t[i][1]end Q=(Q*s)%3 for i=1,s
do for j=1,s-1 do p=t[j]q=t[j+1]x=p[1]y=q[1]u=x~=y and(S and R==S or x~=Q)v=(x+y)*2
for k=1,#p do p[k]=u and v%3or x q[k]=u and v%3or y
print(j..a..k,j+1..a..k)end Y=Y and Y..x or x end
R=S S=Y end end

5

녹, 496 495 바이트

슬프게도 OP를 이길 수는 없지만 Rust 답변에 대해서는 바이트 수에 상당히 만족합니다.

let s=|mut v:Vec<_>,c|{
let p=|v:&mut[_],f,t|{
let x=|v:&mut[_],i|{
let n=v[i]^v[i+1];v[i]=n;v[i+1]=n;
for k in f..t+1{print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});}};
let l=v.len();let t=(1..4).find(|x|l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
let mut i=0;while i<l{let c=v[i];if c==t{i+=1;}else if c==v[i+1]{
let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};x(v,j);}else{x(v,i);}}t};
p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|{p(x,i,i)}).collect::<Vec<_>>(),0,c-1usize)};

입력 : 열 수뿐만 아니라 숫자로 구성된 벡터입니다. 예 :

s(vec!{1,2,1,3},2);

출력

 (row1,col1,row2,col2)

명령 행에.

먼저 모든 행을 해결 한 다음 결과 열을 한 번만 해결하지만 모든 열에 대한 단계를 인쇄하십시오. 따라서 실제로는 매우 효율적입니다.

포맷팅 :

let s=|mut v:Vec<_>,c|{  
    let p=|v:&mut[_],f,t|{     // solves a single row/column
        let x=|v:&mut[_],i|{   // makes a move and prints it 
            let n=v[i]^v[i+1]; // use xor to calculate the new color
            v[i]=n;
            v[i+1]=n;
            for k in f..t{
                print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});
            }
        };
        let l=v.len();
        // find target color
        // oh man i am so looking forward to sum() being stabilized
        let t=(1..4).find(|x|(l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
        let mut i=0;
        while i<l{
            let c=v[i];
            if c==t{             // if the color is target color move on
                i+=1;
            }else if c==v[i+1]{ // if the next color is the same
                                // find the next possible move
                let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};
                x(v,j);
            }else{              // colors are different so we can make a move
                x(v,i);         
            }
        }
        t
    };
    // first solve all rows and than sovle the resulting column c times 
    p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|p(x,i,i)).collect::<Vec<_>>(),0,c-1usize)
};

편집 : 이제 세미콜론을 절약하는 솔루션의 색상을 반환합니다 ^^


5

비 펀지 , 197 368 696 754 바이트


(예, 리버스 코드 골프를하고 있습니다. 바이트가 많을수록 좋습니다)


Befunge에서이 알고리즘을 작성하는 것이 어려울 수 있고 재미있을 수 있다고 생각했습니다.

커뮤니티 프로그램이 되길 바랍니다. 누군가이 프로그램을 만들고 싶다면 그렇게하십시오.

결국, 나는 지금까지 모든 것을 혼자서 만들었으므로 스스로 끝낼 것입니다 (거의 끝났습니다)


아직 완료된 사항 : 트롤 모양의 코드

&:19p&:09p:v:p94g92g90  <
 v94+1:g94&_$59g1+59p1-:|
 >p59gp1-: ^    vp95g93$<
v94\-1<v:g<     >  v
>g:1+v^_$v^90p94g92<
v5p94<   3>1+59p   ^
>9gg+\:^ %g   v93:g95<           v3_2         v
v1pg95g94<^95<>g-v>$v^           v ^-%3*2\gg9<
>9g39g+59g-1-|v-1_^ #^pg95+g92g90<1_09g:29g+5^
       ;  >  >  09g:29g+59gg\3%-# !^v         <
          ^p95<                  ^  <
     v  p96-1+g90g92<
     v                  p95_@
            >59g1+:39g-19g-^
     v    >p 79g:59gg\1+59gp$$$$$29g49pv
    > p59g^ |<<<<<<<<<<<<<<<<<<!-g96g94<
>:79^>29g49p>69g1+59gg49g:59gg\1+49p- v
^\-\6+gg95+1\g< v         !-g96:<-1g94_^
>"]",52*,::59g^v_::1+59gg\59gg-v^ <
^ .-g93g95,.-g<>:69g- v  v-g96:_1+^
>+" [,]",,,\29^       >#v_$:49g2-v
^1:.-g93g95,.-g92\,"[ ":<        <

(그래, 트롤이야, 날 믿어)


기본적으로 배열을 읽고 입력이 다음과 같이 주어진 행을 해결하기 위해 수행하는 이동을 계산합니다.

(number of rows) (number of columns) 1 2 3 1 1 3 2 1 2 ....

(전체 배열은 목록 [row1, row2, row3,…]으로 전달됨)

출력은

[col row],[col',row']
[col2 row2],[col2',row2']
...

행과 열은 모두 0에서 시작합니다.


이제 행이 해결되었으므로 거의 완료되었습니다! 만세!


설명 : (나중에 업데이트 될 예정)

영상

따라서 5 가지 주요 부분이 있습니다.

  • 첫 번째는 녹색으로 입력 행을 읽고 배열의 한 행을 씁니다.
  • 주황색의 두 번째 것은 배열의 다음 행으로 전달됩니다.
  • 파란색의 세 번째는 행을 합산합니다.
  • 네 번째는 핫 핑크로 합계의 계수 3을 가져 와서 해당 행의 오른쪽에 저장하고 다음 행으로 이동합니다.
  • 마지막으로, 빨간색으로, 이전에 계산 된 숫자로부터 목표 색을 계산하는 부분. 이 부분은 정말 바보이며 아마도 다시 작성해야하지만, 좋은 방법으로 어떻게 할 수 있는지 알지 못했습니다 (197 바이트에서 368로 전달)

회색 부분은 초기화입니다


다음은 결합 할 상자를 찾는 모듈에 대한 자세한 설명입니다 (여기서는 여기에서 코딩 됨).

                                       B
            @                          v
            |                  !-g96g94<
ENTRY>29g49p>69g1+59gg49g:59gg\1+49p- v
                v         !-g96:<-1g94_^
               v_::1+59gg\59gg-v^ <
               >:69g- v  v-g96:_1+^
                      >#v_$:49g2-v
                    CALL<        <

CALL 부분은 명령어 포인터가 다른 모듈로 가고 상자에 결합 할 때입니다. 'B'항목을 통해이 모듈로 돌아옵니다.

의사 코드는 다음과 같습니다. (currentx는 배열 읽기와 관련이 있습니다.)

    69g1+59gg  // read target color
    49g:59gg\1+49p // read current color and THEN shift the currentx to the next box
    if ( top != top ){  // if the current color is bad
        49g1-          //  put the current place  (or currentx - 1) in the stack
        While:
            if ( :top != 69g ){   // if you didn't reach the end of the list
                ::1+              // copy twice, add 1
                if ( 59gg == \59gg ){ // if the next color is the same than current
                   1+                // iterate
                   break While;
                }
            }

        : // copies j (the previous raw iterator)
        if ( top == 69g ){  // if you reached the end of the row (which mean you can't swap with the color after that point)
            $:              // discard j's copy and copy target
            49g2-           // put the place just before the color change on the stack
            combine_with_next;
        } else {
            combine_with_next;
        }
        29g49p   // back to the beginning of the row (there was some changes int the row)
    }

    if ( 49g != 69g ) // if you didn't reach the end of the list
        break For:

테스트하려는 경우 연결된 인터 프리트 를 사용 하려면 배열을 저장할 공간이 충분하도록 후행 공간과 후행 줄을 추가해야합니다 . 22 + 입력의 후행 줄 수와 34 + 한 행의 후행 줄 수는 괜찮습니다.


궁금한 점은 왜 이것이 경쟁이 아닌가?
밸류 잉크

이 부분 때문에 : '커뮤니티 프로그램이되고 싶습니다.' 나는 달리 부정 행위가 될 것이라고 생각
Maliafo

나는 197 바이트의 결과를 얻었습니다. 창문에서 일하십니까? (그리고 \r\n대신에 계산 \n?)
Katenkyo

흠, 나는 바이트를 계산할 때 일부 후행을 붙여 넣은 것 같아요, 감사합니다
Maliafo

결국 나는 그것을 만든 유일한 사람이라면, 나는 언급을 지울 것이지만, 나는 그렇게하지 않기를 바랍니다.
Maliafo

2

C, 404 바이트

내 첫 번째 코드 골프, 나는 그것이 어떻게 나타 났는지에 매우 만족합니다. 그래도 너무 오래 걸렸습니다. 그것은 완전한 표준 C가 아니며 특별한 플래그없이 경고를 무시하고 gcc에서 컴파일되는 모든 것입니다. 거기에 중첩 된 함수가 있습니다. 이 함수 f는 차원 mn첫 번째 인수로 사용하고 세 번째 인수는 크기 m× n( 배열로 먼저 색인화 됨 )의 배열에 (int 포인터)를 사용합니다 . 다른 인수는 더미 인수이므로 전달할 필요가 없으며 변수 선언에 바이트를 절약하기 위해 거기에 있습니다. row1,col1:row1,col1;세미콜론으로 쌍을 구분 하여 각 변경된 쌍을 형식으로 STDOUT에 씁니다 . 0 기반 인덱싱을 사용합니다.

#define A a[i*o+p
#define B A*c
f(m,n,a,i,j,o,p,b,c,d)int*a;{
int t(x){printf("%d,%d:%d,%d;",b?i:c+x,b?c+x:i,b?i:c+1+x,b?c+1+x:i);}
o=n;p=b=1;for(;~b;b--){
for(i=0;i<m;i++){c=j=0;
for(;j<n;)c+=A*j++];d=c*n%3;
for(j=0;j<n-1;j++) 
while(A*j]^d|A*j+p]^d){
for(c=j;B]==B+p];c++);
if(c<n-2&B]==d&2*(B+p]+A*(c+2)])%3==d)
B+p]=A*(c+2)]=d,t(1);else
B]=B+p]=2*(B]+B+p])%3,
t(0);}}o=m;p=m=n;n=o;o=1;}}

개별 행 / 열을 해결하기 위해 OP와 약간 다른 알고리즘을 사용했습니다. 다음과 같이 진행됩니다 (의사 코드).

for j in range [0, rowlength):
    while row[j] != targetCol or row[j+1] != targetCol:
        e=j
        while row[e] == row[e+1]:
            e++             //e will never go out of bounds
        if e<=rowLength-3 and row[e] == targetCol 
                and (row[e+1] != row[e+2] != targetCol):
            row.changeColor(e+1, e+2)
        else:
            row.changeColor(e, e+1)

for(;~b;b--)루프가 실행하는 정확히 두 번째 패스 대신 행의 열을 해결한다. 이는와를 교환 n하고 배열을 주소 지정하기 위해 포인터 산술에 사용되는 및 m의 값을 변경하여 수행됩니다 .op

다음은 테스트 메인이있는 ungolfed 버전이며 매번 이동할 때마다 전체 배열을 인쇄합니다 (Enter를 눌러 1 단계로 돌리십시오).

#define s(x,y)b?x:y,b?y:x
#define A a[i*o+p
#define B A*e
f(m,n,a,i,j,o,p,b,c,d,e)int*a;{

    int t(x){
        printf("%d,%d:%d,%d;\n",s(i,e+x),s(i,e+1+x));
        getchar();
        printf("\n");
        for(int i2=0;i2<(b?m:n);i2++){
            for(int j2=0;j2<(b?n:m);j2++){
                printf("%d ",a[i2*(b?n:m)+j2]);
            }
            printf("\n");
        }
        printf("\n");
    }

    printf("\n");
    b=1;
    for(int i2=0;i2<(b?m:n);i2++){
        for(int j2=0;j2<(b?n:m);j2++){
            printf("%d ",a[i2*(b?n:m)+j2]);
        }
        printf("\n");
    }
    printf("\n");

    o=n;p=1;
    for(b=1;~b;b--){
        for(i=0;i<m;i++){
            c=0;
            for(j=0;j<n;j++) c+= a[i*o+p*j];
            d=0;
            d = (c*n)%3;
            for(j=0;j<n-1;j++) {
                while(a[i*o+p*j]!=d||a[i*o+p*j+p]!=d){
                    for(e=j;a[i*o+p*e]==a[i*o+p*e+p];e++);
                    if(e<=n-3 && a[i*o+p*e]==d 
                            && 2*(a[i*o+p*e+p]+a[i*o+p*(e+2)])%3==d){
                        a[i*o+p*e+p]=a[i*o+p*(e+2)]=d;
                        t(1);
                    }else{
                        a[i*o+p*e]=a[i*o+p*e+p] = 2*(a[i*o+p*e]+a[i*o+p*e+p])%3;
                        t(0);
                    }
                }
            }
        }
        o=m;p=m=n;n=o;o=1;
    }
}

main(){
    int g[11][11] = 
    {
        {0,2,1,2,2,1,0,1,1,0,2},
        {2,1,1,0,1,1,2,0,2,1,0},
        {1,0,2,1,0,1,0,2,1,2,0},
        {0,0,2,1,2,0,1,2,0,0,1},
        {0,2,1,2,2,1,0,0,0,2,1},
        {2,1,1,0,1,1,2,1,0,0,2},
        {1,0,2,1,0,1,0,2,2,1,2},
        {0,0,2,1,2,0,1,0,1,2,0},
        {1,2,0,1,2,0,0,2,1,2,0},
        {2,1,1,0,1,1,2,1,0,0,2},
        {0,2,1,0,1,0,2,1,0,0,2},
    };
    #define M 4
    #define N 7
    int grid[M][N];
    for(int i=0;i<M;i++) {
        for(int j=0;j<N;j++) {
            grid[i][j] = g[i][j];
        }
    }
    f(M,N,grid[0],0,0,0,0,0,0,0,0);
};

궁금한 점이 있습니다. 바이트 절약 측면에서 다른 알고리즘을 선택한 이유는 무엇입니까?
Sanchises

1
사람들이 다른 솔루션을 만들면 더 재미 있다고 생각합니다. 빠른 테스트를 통해 두 가지 방법이 바이트 수와 거의 같을 것이라고 추측했습니다. 아마 당신의 알고리즘을 시도하고 내가 더 낮아질 수 있는지 볼 것입니다.
Norg74

질문에 대해 의견을 말할 충분한 담당자가 없기 때문에 여기에 게시하십시오. 각 행과 각 열을 개별적으로 무차별 처리하는 것이 유효합니까? 기술적으로 "완벽하게 강제 실행"하지 않으며 지정된 시간 복잡도보다 낮아야합니다. 나는 실제로 그렇게하는 것을 고려했습니다.
Norg74

무차별적인 언급은 '합리적인 시간'발언을 강화하기위한 것이므로 t«O (...)로 참조하십시오. 나는 무차별 대입과 합리적인 알고리즘 사이에 회색 영역이 있다는 것을 알고 있으므로 퍼즐을 풀기 위해 노력하고 있다고 생각하는지 또는 DFS 또는 BFS에서 약간만 수정하여 '진행'에 무관심한지 판단하십시오. .
Sanchises
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.