Kết nối 4: Phát hiện sự giả mạo!


35

Ngân hàng đã bị đột nhập và tất cả những tên côn đồ mafia địa phương đều có một chứng cứ ngoại phạm khác thường: họ ở nhà chơi Connect 4! Để hỗ trợ điều tra, bạn được yêu cầu viết chương trình để xác thực tất cả các bảng Connect 4 đã bị tịch thu để kiểm tra xem các vị trí có thực sự là vị trí trong trò chơi Connect 4 hợp lệ không và chưa được kết hợp vội vàng ngay khi cảnh sát gõ cửa.

Các quy tắc để kết nối 4: người chơi RYthực hiện lần lượt để thả các ô màu của họ vào các cột của lưới 7x6. Khi một người chơi thả một viên gạch vào cột, nó sẽ rơi xuống chiếm vị trí thấp nhất trong cột đó. Nếu người chơi quản lý để có được một đường chạy ngang, dọc hoặc chéo của bốn ô màu của họ trên bảng, thì họ thắng và trò chơi kết thúc ngay lập tức.

Ví dụ: ( Rbắt đầu), sau đây là vị trí Kết nối 4 không thể.

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | |
| | |Y| | | | |
|R| |Y| | | | |

Chương trình hoặc chức năng của bạn phải có trong bảng Connect 4 và trả lại

  • Một giá trị giả, chỉ ra rằng vị trí là không thể hoặc
  • Một chuỗi các số 1-7, cho thấy một chuỗi có thể di chuyển dẫn đến vị trí đó (các cột được đánh số 1để 7từ trái sang phải, và do đó trình tự 112, ví dụ, chỉ một động thái đỏ trong cột 1, tiếp theo là một động thái vàng trong cột 1, tiếp theo là di chuyển màu đỏ trong cột 2). Bạn có thể chọn đánh số cột khác với 1234567 nếu muốn, miễn là bạn chỉ định trong giải pháp của mình. Nếu bạn muốn trả về danh sách ở một số định dạng khác; ví dụ như là một mảng [2, 4, 3, 1, 1, 3]thì điều đó cũng tốt, miễn là dễ dàng để xem những gì di chuyển.

Bạn có thể chọn đọc bảng theo bất kỳ định dạng hợp lý nào, kể cả sử dụng các chữ cái khác RYcho người chơi, nhưng bạn phải chỉ định người chơi nào đi trước. Bạn có thể giả định rằng bảng sẽ luôn là 6x7, với hai người chơi.

Bạn có thể cho rằng các vị trí bạn nhận được ít nhất có thể về mặt vật lý để tạo trên bảng Connect 4 tiêu chuẩn; tức là, sẽ không có mảnh 'nổi'. Bạn có thể cho rằng bảng sẽ không trống.

Đây là mã golf, vì vậy câu trả lời ngắn nhất sẽ thắng. Tiêu chuẩn áp dụng.

Ví dụ

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | --> 1234567 (one possible answer)
| | | | | | | |
|R|Y|R|Y|R|Y|R|

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | | --> false
| | |Y| | | | |
|R| |Y| | | | |

| | | | | | | |
| | |Y| | | | |
| | |R| | | | |
| | |Y| | | | | --> 323333 (only possible answer)
| | |R| | | | |
| |Y|R| | | | |

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> false (this is the position arising after
| |Y|Y|Y|Y| | |     the moves 11223344, but using those moves
| |R|R|R|R| | |     the game would have ended once R made a 4)

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> 2134231211 (among other possibilities)
|R|R|Y| | | | |
|Y|R|R|Y| | | |

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> false (for example, 21342312117 does not
|R|R|Y| | | | |     work, because Y has already made a diagonal 4)
|Y|R|R|Y| | |R|

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> 112244553 or similar
|Y|Y| |Y|Y| | |
|R|R|R|R|R| | |

John, vì tò mò, bạn có biết liệu thuật toán không vũ phu có tồn tại không?
Giô-na

Câu trả lời:


9

Thạch , 57 byte

ŒṪŒ!µ0ịŒṬ¬a³ZU,Ɗ;ŒD$€Ẏṡ€4Ḅo1%15;Ḋ€ṢṚ$Ƒƙ$Ȧȧœị³$2R¤ṁ$ƑµƇṪṪ€

Đưa ra một ma trận trong đó 0không được lấp đầy, 1chơi đầu tiên và 2chơi thứ hai. Mang lại một danh sách các cột được lập chỉ mục 1, trống nếu xác định giả mạo.

Hãy thử trực tuyến! (quá kém hiệu quả đối với hơn 7 phần để chạy trong vòng một phút)

Chú thích:

  1. Giả sử rằng không có phần "nổi" nào (khắc phục điều này bằng cách trả trước ZṠṢ€Ƒȧ+6 byte)
  2. Giả sử rằng bảng trống là giả

11

JavaScript (ES6),  202 194 187  183 byte

Lấy đầu vào dưới dạng ma trận với cho màu đỏ, cho màu vàng và cho trống. Trả về một chuỗi các di chuyển được lập chỉ mục 0 (hoặc một chuỗi trống nếu không có giải pháp). Quỷ đỏ bắt đầu trò chơi.240

m=>(p=[...'5555555'],g=(c,s=o='')=>/2|4/.test(m)?['',0,2,4].some(n=>m.join``.match(`(1|3)(.{1${n}}\\1){3}`))?o:p.map((y,x)=>m[m[y][x]--^c||p[g(c^6,s+x,p[x]--),x]++,y][x]++)&&o:o=s)(2)

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

Làm sao?

Hàm đệ quy cố gắng thay thế tất cả và trong ma trận đầu vào bằng và tương ứng.g2413

Trong khi làm như vậy, đảm bảo rằng chúng ta không có bất kỳ bốn giá trị lẻ liên tiếp nào cho đến khi tất cả các giá trị chẵn biến mất (nghĩa là nếu một bên thắng, đó phải là nước đi cuối cùng).

Hàng của vị trí có sẵn tiếp theo cho mỗi cột được lưu trữ trong .yxp[x]

Đã bình luận

m => (                            // m[] = input matrix
  p = [...'5555555'],             // p[] = next row for each column
  g = (c,                         // g = recursive function taking c = color,
          s = o = '') =>          //     s = current solution, o = final output
    /2|4/.test(m) ?               // if the matrix still contains at least a 2 or a 4:
      ['', 0, 2, 4]               //   see if we have four consecutive 1's or 3's
      .some(n =>                  //   by testing the four possible directions
        m.join``                  //   on the joined matrix, using
        .match(                   //   a regular expression where the number of characters
          `(1|3)(.{1${n}}\\1){3}` //   between each occurrence is either 1, 10, 12 or 14
        )                         //   (horizontal, diagonal, vertical, anti-diagonal)
      ) ?                         //   if we have a match:
        o                         //     abort and just return the current value of o
      :                           //   else:
        p.map((y, x) =>           //     for each cell at (x, y = p[x]):
          m[                      // 
            m[y][x]--             //       decrement the value of the cell
            ^ c ||                //       compare the original value with c
            p[                    //       if they're equal:
              g(                  //         do a recursive call with:
                c ^ 6,            //           the other color
                s + x,            //           the updated solution
                p[x]--            //           the updated row for this column
              ),                  //         end of recursive call
              x                   //         then:
            ]++,                  //         restore p[x]
            y                     //         and restore m[y][x]
          ][x]++                  //         to their initial values
        ) && o                    //     end of map(); yield o
    :                             // else:
      o = s                       //   we've found a solution: copy s to o
)(2)                              // initial call to g() with c = 2

Lưu ý tôi đã hỏi "Chúng tôi có thể cho rằng bảng trống sẽ không được cung cấp làm đầu vào không?" - nếu chúng ta phải xử lý việc này thì mã của bạn sẽ cần một tinh chỉnh.
Jonathan Allan

tôi không biết tại sao, f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [0,2,2,0,2,2,0], [1,1,1,1,1,1,1] ])chấm dứt 0f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])nên thành sự thật
Nahuel Fouilleul

@NahuelFouilleul Cảm ơn bạn đã báo cáo điều này. Tôi đã sửa mã thêm các trường hợp thử nghiệm này.
Arnauld

2

Python 2 , 295 285 byte

def f(a):
 if 1-any(a):return[]
 p=sum(map(len,a))%2
 for i in R(7):
	if a[i][-1:]==`p`:
	 b=a[:];b[i]=b[i][:-1];L=f(b)
	 if L>1>(`1-p`*4in','.join([J((u[j]+' '*14)[n-j]for j in R(7))for n in R(12)for u in[b,b[::-1]]]+b+map(J,zip(*[r+' '*7for r in b])))):return L+[i]
R=range;J=''.join

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

-10 thx cho Jo King .

Đầu vào là danh sách các chuỗi đại diện cho các cột; với '1' cho màu đỏ và '0' cho màu vàng. Các chuỗi không '' -padded. Vì vậy, trường hợp (falsey):

| | | | | | | |
| | | | | | | |
|Y| | | | | | |
|R|Y| | | | | |
|R|R|Y| | | | |
|Y|R|R|Y| | |R|

là đầu vào như:

[
  '0110',
  '110',
  '10',
  '0',
  '',
  '',
  '1'
]

Đầu ra là một danh sách các chỉ mục cột, được lập chỉ mục 0, có thể tạo bảng; hoặc Nonenếu nó không hợp lệ.

Chấp nhận bảng trống là hợp lệ (trả về danh sách trống []thay vì None).

Cách tiếp cận này được đệ quy từ bước di chuyển cuối cùng sang nước đi đầu tiên: dựa trên tính chẵn lẻ của tổng số lần di chuyển, chúng tôi loại bỏ bước di chuyển Đỏ cuối cùng hoặc di chuyển Vàng cuối cùng (hoặc thất bại nếu điều đó là không thể); kiểm tra bảng kết quả để xem liệu đối thủ có 4 liên tiếp không (trong trường hợp này không thành công, vì trò chơi đã dừng lại rồi); mặt khác, lặp lại cho đến khi bảng trống (có giá trị).

Mã 4 liên tiếp là phần bloaty nhất. Tất cả các chuỗi chéo cho ma trận bđược tạo bởi:

[
    ''.join(
        (u[j]+' '*14)[n-j] for j in range(7)
    )
    for u in[b,b[::-1]]for n in range(12) 
]

trong đó đầu tiên liệt kê các đường chéo 'dốc xuống', và sau đó 'đường dốc lên'.

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.