Giải câu đố màu sắc


35

Tại bạn bè của chúng tôi tại Puzzling.SE , câu đố sau đây đã được đăng: Câu đố màu sắc này luôn có thể giải được? bởi Edgar G. Bạn có thể chơi nó ở đây .

Giải thích câu đố

Cho một m x nlưới có các ô gồm ba màu khác nhau, bạn có thể chọn bất kỳ hai ô liền kề nào , nếu màu của chúng khác nhau . Hai gạch này sau đó được chuyển đổi sang màu thứ ba, nghĩa là một màu không được đại diện bởi hai gạch này. Câu đố được giải nếu tất cả các ô có cùng màu . Rõ ràng, người ta có thể chứng minh rằng câu đố này luôn luôn có thể giải được, nếu không mcũng không nchia hết cho 3.

Câu đố ba màu 8 x 8

Tất nhiên, điều này cầu xin một thuật toán giải. Bạn sẽ viết một hàm hoặc chương trình giải câu đố này. Lưu ý rằng các chức năng có 'tác dụng phụ' (nghĩa là đầu ra được bật stdoutchứ không phải trong một số giá trị trả về kiểu dữ liệu khó xử) được cho phép rõ ràng.

Đầu ra đầu vào

Các đầu vào sẽ là một m x nma trận bao gồm các số nguyên 1, 23(hoặc 0, 1, 2nếu thuận tiện). Bạn có thể lấy đầu vào này ở bất kỳ định dạng lành mạnh. Cả hai mn>1và không chia hết cho 3. Bạn có thể giả định các câu đố không được giải quyết

Sau đó bạn sẽ giải câu đố. Điều này sẽ liên quan đến việc lựa chọn lặp lại hai gạch liền kề để được 'chuyển đổi' (xem bên trên). Bạn sẽ xuất hai tọa độ của các ô này cho mỗi bước mà thuật toán giải của bạn đã thực hiện. Điều này cũng có thể ở bất kỳ định dạng đầu ra lành mạnh. Bạn có thể tự do lựa chọn giữa lập chỉ mục dựa trên 0 và 1 dựa trên tọa độ của mình và liệu các hàng hoặc cột được lập chỉ mục trước. Hãy đề cập đến điều này trong câu trả lời của bạn, tuy nhiên.

Thuật toán của bạn sẽ chạy trong thời gian hợp lý trên trường hợp 8x8 ban đầu. Brute-buộc nó hoàn toàn là không được phép một cách rõ ràng, tức là thuật toán của bạn nên chạy theo O(k^[m*(n-1)+(m-1)*n])với ksố lượng các bước cần thiết cho việc giải quyết. Tuy nhiên, giải pháp không bắt buộc phải tối ưu. Bằng chứng được đưa ra trong câu hỏi được liên kết có thể cho bạn ý tưởng về cách thực hiện việc này (ví dụ: trước tiên, thực hiện tất cả các cột chỉ sử dụng các ô liền kề theo chiều dọc, sau đó thực hiện tất cả các hàng)

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

Trong các trường hợp thử nghiệm này, tọa độ dựa trên 1 và các hàng được lập chỉ mục đầu tiên (như MATLAB / Octave và có thể nhiều thứ khác).

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]

Nếu muốn, tôi có thể đăng một pastebin của các trường hợp thử nghiệm lớn hơn, nhưng tôi nghĩ rằng điều này là đủ.


Tôi rất thích xem phiên bản thử thách mã này, trong đó mục tiêu là giải một bộ câu đố với tổng số lần di chuyển ít nhất.
Mego

@Mego Tôi chắc chắn đã xem xét điều này. Tuy nhiên, tôi sợ rằng điều này sẽ biến thành một DFS hoặc BFS sẽ mất mãi mãi để chạy; hoặc, để ngăn chặn điều này, một loạt các hạn chế mơ hồ (như 'phải chạy trong vòng một giờ', ưu tiên mọi người với một máy tính lớn hoặc sẽ yêu cầu tôi kiểm tra tất cả các giải pháp). Và hơn nữa, thử thách hiện tại không có câu trả lời nào cho tôi, vì vậy tôi nghi ngờ rằng một phiên bản thậm chí khó hơn đòi hỏi heuristic, v.v. sẽ chứng tỏ là phổ biến hơn ... Nhưng có lẽ nếu thử thách này tăng tốc tôi có thể đăng một thử thách anh chị em như bạn miêu tả.
Sanchise

Tôi nghĩ rằng tôi sẽ cố gắng làm điều đó ở Lua, nhưng nó có thể dài hơn giải pháp 324 Byte của bạn ^^
Katenkyo

@Katenkyo Chỉ có một cách để tìm hiểu! Tôi mong muốn được nhìn thấy giải pháp của bạn.
Sanchises

Bạn sẽ phải chờ đợi một chút buồn, bạn đã ngăn chặn giải pháp vũ phu vì vậy tôi phải tìm một giải pháp ngắn gọn trong lua: p
Katenkyo

Câu trả lời:


5

Ruby, 266 byte

Ít nhiều chỉ là một cổng của giải pháp Octave, ngoại trừ nó giải quyết các hàng trước thay vì các cột. Đầu vào là một mảng các mảng, với các mảng bên trong là các hàng. Di chuyển đầu ra là [row, column, row, column]. Bộ kiểm tra

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

Ung dung với lời giải thích

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

Thật thú vị khi thấy rằng một cổng giữa hai ngôn ngữ không chơi gôn vẫn có thể tạo ra sự khác biệt ~ 20%. Bạn có thể thêm một lời giải thích ngắn không? (Đặc biệt là dòng 3 - Tôi thầm hy vọng tôi có thể sử dụng nó trong câu trả lời của mình vì đó intersectlà một từ khóa cồng kềnh như vậy)
Sanchises

@sanchises một lời giải thích đã được thêm vào. Về intersect, tôi không biết liệu bạn có thể khắc phục cách thức hoạt động của mình không vì Ruby findvề cơ bản hoạt động theo chức năng và functiontừ khóa của bạn cũng cồng kềnh.
Mực giá trị

Tôi thực sự vẫn có thể sử dụng phương pháp của bạn cho find- cảm ơn! Tuy nhiên, không nơi nào gần để đánh bại bạn ...
Sanchise

13

Octave, 334 313 byte

Vì thử thách có vẻ hơi nan giải, tôi trình bày giải pháp của riêng mình. Tôi đã không chính thức chứng minh rằng phương pháp này hoạt động (tôi đoán rằng nó sẽ đi xuống để chứng minh rằng thuật toán sẽ không bao giờ bị mắc kẹt trong một vòng lặp), nhưng cho đến nay nó vẫn hoạt động hoàn hảo, thực hiện các thử nghiệm 100x100 trong vòng 15 giây. Lưu ý rằng tôi đã chọn sử dụng một hàm có tác dụng phụ thay vì một hàm trả về tất cả các tọa độ vì điều đó đã tiết kiệm cho tôi một vài byte. Các tọa độ là hàng chính, dựa trên 1 và được định dạng là row1 col1 row2 col2. Màu sắc đầu vào là 0,1,2do điều này hoạt động tốt hơn với mod, với chi phí phải sử dụng numelhơn là nnz. Phiên bản chơi gôn: Chỉnh sửa: đã lưu một vài byte bằng cách sử dụng một kỹ thuật từ câu trả lời của 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

Ví dụ GIF của thuật toán giải:

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

Phiên bản bị đánh cắp:

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

Chỉ cần chú ý, nhưng tên của tôi không phải là Kenny Lau ... đó là một người dùng khác và tên người dùng của tôi nói rõ rằng tôi không phải là Kenny
Value Ink

7

Lua, 594 575 559 byte

Cảnh báo Vẫn còn nhiều việc trước khi tôi hoàn thành việc chơi gôn này! Tôi sẽ có thể lấy ít nhất dưới 500 Byte. Hiện tại, đó là giải pháp đầu tiên có hiệu quả và tôi vẫn đang nghiên cứu nó.

Tôi sẽ cung cấp một lời giải thích đầy đủ sau khi tôi hoàn thành.

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

Rỉ, 496 495 byte

Đáng buồn là tôi không thể đánh bại OP, nhưng đối với câu trả lời của Rust, tôi khá hài lòng với bytecount.

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

Đầu vào: một vectơ số cũng như số cột. Ví dụ

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

đầu ra

 (row1,col1,row2,col2)

đến dòng lệnh.

Trước tiên tôi giải quyết mỗi hàng và sau đó chỉ giải quyết cột kết quả một lần, nhưng in các bước cho tất cả các cột. Vì vậy, nó thực sự khá hiệu quả :-P.

Với công thức:

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

Chỉnh sửa: bây giờ trả về màu của giải pháp giúp tôi tiết kiệm một dấu chấm phẩy ^^


5

Befunge , 197 368 696 754 byte


(vâng, tôi đang chơi golf mã ngược, càng nhiều byte càng tốt)


Tôi đã nghĩ rằng nó có thể là một thách thức để viết thuật toán này trong Befunge và nó có thể rất vui

Tôi muốn nó là một chương trình cộng đồng, vì vậy nếu bất cứ ai muốn làm việc với nó, xin vui lòng, làm như vậy.

Cuối cùng, tôi đã làm mọi thứ một mình cho đến nay, vì vậy tôi sẽ tự mình hoàn thành (gần xong rồi)


Điều gì đã được thực hiện: một mã hình troll

&: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\,"[ ":<        <

(vâng, đó là một trò troll, tin tôi đi)


Về cơ bản, nó đọc một mảng và tính toán di chuyển phải làm để giải quyết các hàng, đưa ra một đầu vào là

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

(toàn bộ mảng được truyền dưới dạng danh sách [row1, row2, row3, cám])

đầu ra là

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

hàng và cols đều bắt đầu từ 0.


Bây giờ các hàng đã được giải quyết, gần như đã hoàn tất! Hoan hô !


Giải thích: (sẽ được cập nhật sau)

hình ảnh

Vì vậy, có 5 phần chính:

  • Dòng đầu tiên, màu xanh lục, đọc dòng đầu vào và viết một hàng của mảng
  • Cái thứ hai, màu cam, chuyển sang hàng tiếp theo của mảng
  • Thứ ba, trong màu xanh, tổng hợp một hàng
  • Cái thứ tư, màu hồng nóng, lấy mô-đun 3 của tổng, lưu nó ở bên phải của hàng liên quan và đi đến hàng tiếp theo
  • Cuối cùng, trong màu đỏ, phần tính màu đích từ số được tính trước đó. Phần này thực sự ngu ngốc và có lẽ nên được viết lại, nhưng tôi đã không tìm ra cách tôi có thể làm điều đó theo cách tốt đẹp (được chuyển từ 197 byte đến 368 chỉ với phần đó)

Phần màu xám là khởi đầu


Dưới đây là một lời giải thích sâu hơn về mô-đun tìm các hộp để kết hợp (nhân tiện được mã hóa ở đây)

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

Phần CALL là khi con trỏ lệnh đi đến một mô-đun khác, để kết hợp với các hộp. Nó quay trở lại mô-đun này thông qua mục 'B'

Đây là một số mã giả: (currentx có liên quan đến việc đọc mảng) Dành cho:

    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:

Lưu ý rằng nếu bạn muốn kiểm tra nó, bạn sẽ phải đặt một số khoảng trắng ở cuối và theo dõi các dòng mới để có đủ không gian để lưu trữ mảng, nếu bạn muốn sử dụng thông dịch tôi đã liên kết. 22 + số lượng hàng trong đầu vào dưới dạng các dòng ở cuối và 34 + số lượng cột dưới dạng khoảng trắng trên một dòng sẽ ổn.


Chỉ tò mò, tại sao điều này không cạnh tranh?
Giá trị mực

Vì phần này: 'Tôi muốn nó là một chương trình cộng đồng'. Tôi nghĩ rằng tôi sẽ có một chút gian lận nếu không
Maliafo

Tôi có kết quả là 197 Byte, bạn có làm việc dưới cửa sổ không? (và được tính \r\nthay vì \nchỉ?)
Katenkyo

Hừm, tôi đoán là tôi đã sao chép một số dấu vết khi đếm các byte, cảm ơn bạn
Maliafo

Nếu cuối cùng tôi là người duy nhất tạo ra nó, tôi sẽ xóa đề cập đó, nhưng tôi hy vọng tôi sẽ không
Maliafo

2

C, 404 byte

Golf mã đầu tiên của tôi, tôi khá hài lòng với cách nó bật ra. Đã đi quá lâu, mặc dù. Nó không hoàn toàn chuẩn C, bất cứ thứ gì sẽ biên dịch theo gcc mà không có cờ đặc biệt (và bỏ qua các cảnh báo). Vì vậy, có một chức năng lồng nhau trong đó. Hàm flấy các kích thước mnlàm đối số đầu tiên của nó và vì đối số thứ ba của nó sẽ đưa một (con trỏ int) đến một mảng có kích thước m× n(được lập chỉ mục bởi các hàng trước). Các đối số khác là đối số giả, bạn không cần truyền chúng vào, chúng chỉ ở đó để lưu byte khi khai báo biến. Nó viết mỗi cặp thay đổi thành STDOUT theo định dạng row1,col1:row1,col1;, với dấu chấm phẩy phân tách các cặp. Sử dụng lập chỉ mục dựa trên 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;}}

Tôi đã sử dụng một thuật toán hơi khác so với OP để giải các hàng / cột riêng lẻ. Nó đi một cái gì đó như thế này (mã giả):

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)

Các for(;~b;b--)thực thi vòng lặp chính xác gấp đôi, trên đèo thứ hai nó giải quyết các cột thay vì hàng. Điều này được thực hiện bằng cách hoán đổi nm, và thay đổi các giá trị opđược sử dụng trong số học con trỏ để giải quyết mảng.

Đây là phiên bản không được chỉnh sửa, với bản thử nghiệm chính và in toàn bộ mảng sau mỗi lần di chuyển (nhấn enter đến bước 1 lượt):

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

Vì tò mò: tại sao bạn lại chọn một thuật toán khác (về tiết kiệm byte)?
Sanchise

1
Tôi nghĩ sẽ thú vị hơn khi mọi người đưa ra các giải pháp khác nhau và từ một số thử nghiệm nhanh, tôi đã dự đoán hai phương pháp sẽ giống nhau về số lượng byte. Có lẽ tôi cũng sẽ thử thuật toán của bạn và xem liệu tôi có thể hạ thấp hơn không.
Norg74

Đăng bài này ở đây vì tôi không có đủ đại diện để bình luận về câu hỏi. Nó có hợp lệ để vũ phu từng hàng, sau đó từng cột riêng lẻ không? Về mặt kỹ thuật đó không phải là "vũ phu buộc nó hoàn toàn" và nên thấp hơn độ phức tạp thời gian quy định. Tôi thực sự xem xét làm điều đó.
Norg74

Việc đề cập vũ phu có nghĩa là tăng cường nhận xét 'thời gian hợp lý', vì vậy hãy xem nó là t «O (...). Tôi biết có một khu vực màu xám giữa lực lượng vũ phu và một thuật toán hợp lý, vì vậy hãy sử dụng phán đoán của riêng bạn về việc bạn có cảm thấy nó đang hoạt động để giải câu đố hay nếu đó chỉ là một sửa đổi nhỏ trên DFS hoặc BFS không rõ ràng về 'tiến trình' .
Sanchise
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.