Hãy chơi trốn tìm!


12

Người dùng sẽ ẩn và máy tính sẽ cố gắng tìm chúng.

Đầu tiên, chương trình sẽ lấy một đầu vào, cho kích thước của lưới. Giống như 5x5, 10x10, 15x15, v.v. Lưới sẽ không phải là một hình vuông hoàn hảo.

Lưới giống như một bàn cờ:

_______________________________
|     |     |     |     |     |
| A1  |     |     |     |     | A
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     | B2  |     |     |     | B
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     | C3  |     |     | C
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     |     | D4  |     | D
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     |     |     | E5  | E
|_____|_____|_____|_____|_____|
   1     2     3     4     5

Bây giờ, người dùng sẽ chọn một hình vuông, chẳng hạn như B2(không báo cho máy tính)

Máy tính sẽ bắt đầu đoán hình vuông. Nếu nó chọn hình vuông chính xác, người dùng sẽ trả lời y. Nếu không, họ sẽ nhập hướng mà gạch của họ là từ cái được chọn (N, NE, E, SE, S, SW, W).

Vì vậy, nếu người dùng chọn B2và máy tính đoán C3, người dùng sẽ nhập NW.

Dưới đây là một ví dụ về đầu ra và đầu vào:

Grid?
5x5

C3?
NW

C2?
N

B2?
y

Ghi điểm:

Điều này sẽ được ghi một chút khác biệt so với một thách thức bình thường.

Người chiến thắng là chương trình lấy số lần đoán thấp nhất (trung bình) để đoán đúng ô vuông. Các trường hợp thử nghiệm được tính trung bình sẽ là tất cả các ô vuông có thể có trong 5x5 và sau đó là trong 10 x 10.

Tuy nhiên, nó cũng phải hoạt động với mọi mẫu lưới lên tới 26 hàng (tức là 5x8, 6x2, 20x5, v.v.).

Vui lòng bao gồm một cách để nó được thử nghiệm, chẳng hạn như một JSFiddle.

Và cuối cùng, trong trường hợp hòa, chương trình ngắn nhất sẽ thắng.


1
Nếu tôi đang ẩn A1và máy tính đoán B9, đó là phản ứng thích hợp NWhay W?
Greg Martin

@GregMartin Đó sẽ là NW .... N, W, S, E đều phải thẳng trong khi mọi thứ trên một hàng / cột khác phải là NW, NE, SW, SE
JKonowitz 30/03/2017

Có linh hoạt trong định dạng cụ thể của đầu vào và đầu ra? Nếu có nhiều hơn 26 hàng, chúng được gọi là gì?
Greg Martin

@GregMartin Bạn có thể linh hoạt với đầu ra nhưng cố gắng giữ cho nó đơn giản. Nó không nhất thiết phải giống hệt nhau nhưng nên có kiểu dáng tương tự. Bạn không cần phải tính đến bất cứ điều gì trên 26, tôi sẽ chỉnh sửa nó.
JKonowitz

Tôi không biết "phong cách tương tự" nghĩa là gì. Chúng ta có thể lấy đầu vào dưới dạng một cặp số nguyên theo thứ tự (hàng #, col #) không? (PS: Những loại câu hỏi này là lý do tại sao các thử thách trước khi đăng trong Sandbox là một ý tưởng tuyệt vời.)
Greg Martin

Câu trả lời:


3

Python 3.6 , 466 398 392 byte, minimax

x, y = 1, 1
w, h = [int(x) for x in input('Grid?\n').split('x')]


def split_factor(a, b):
    N = b-y
    W = a-x
    S = h+~N
    E = w+~W
    return max(1, N, W, S, E, N*W, S*W, S*E, N*E)


def move(a, b):
    *Z, = zip([a, x, a, a+1, x, x, a+1, a+1],
              [y, b, b+1, b, y, b+1, b+1, y],
              [1, a-x, 1, w+x+~a, a-x, a-x, w+x+~a, w+x+~a],
              [b-y, 1, h+y+~b, 1, b-y, h+y+~b, h+y+~b, b-y])
    return Z[['N', 'W', 'S', 'E', 'NW', 'SW', 'SE', 'NE'].index(d)]

d = ''
while d != 'y':
    print()
    splits = {(a, b): split_factor(a, b) for a in range(x, x+w) for b in range(y, y+h)}
    a, b = min(splits, key=splits.get)
    d = input(f'{a}{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[b]}?\n')
    x, y, w, h = move(a, b)

Đầu vào và đầu ra phải ở dạng hiển thị trong ví dụ. Điều này tìm thấy hình vuông có "hệ số phân tách" tối thiểu - là khu vực còn lại lớn nhất có thể xuất phát từ câu trả lời của người chơi (ví dụ: NW, E, y, v.v.) - và đoán điều đó. Đúng, đó luôn là trung tâm của khu vực còn lại trong trò chơi này, nhưng kỹ thuật giảm thiểu trường hợp xấu nhất này sẽ hoạt động chung hơn trong các trò chơi tương tự với các quy tắc khác nhau.

Phiên bản không thể đọc được:

x=y=d=1
w,h=map(int,input('Grid?\n').split('x'))
while d!='y':print();s={(a,b):max(b-y,h+y+~b)*max(w+x+~a,a-x)for a in range(x,x+w)for b in range(y,y+h)};a,b=min(s,key=s.get);d=input(f'{a}{chr(64+b)}?\n');*z,=zip([a+1,x,a+1,x,a,a,a+1,x],[b+1,b+1,y,y,b+1,y,b,b],[w+x+~a,a-x,w+x+~a,a-x,1,1,w+x+~a,a-x],[h+y+~b,h+y+~b,b-y,b-y,h+y+~b,b-y,1,1]);x,y,w,h=z[~'WENS'.find(d)or-'NWNESWSE'.find(d)//2-5]

2

Mathicala, hành vi tối ưu trên các trường hợp thử nghiệm, 260 byte

For[a=f=1;{c,h}=Input@Grid;z=Characters;t=<|Thread[z@#->#2]|>&;r="";v=Floor[+##/2]&;b:=a~v~c;g:=f~v~h,r!="y",r=Input[g Alphabet[][[b]]];{{a,c},{f,h}}={t["NSu",{{a,b-1},{b+1,c},{b,b}}]@#,t["uWX",{{g,g},{f,g-1},{g+1,h}}]@#2}&@@Sort[z@r/.{c_}:>{c,"u"}/."E"->"X"]]

Chương trình này có thể được kiểm tra bằng cách cắt và dán đoạn mã trên vào Đám mây Wolfram . (Tuy nhiên, hãy kiểm tra nhanh: Tôi nghĩ rằng có giới hạn thời gian cho mỗi lần chạy chương trình.) Dự đoán của chương trình trông giống như 2 cthay vì C2, nhưng nếu không thì nó chạy theo thông số kỹ thuật ở trên. Lưới phải được nhập dưới dạng một cặp số nguyên theo thứ tự, như {26,100}và các câu trả lời cho dự đoán của chương trình phải được nhập dưới dạng chuỗi, như "NE"hoặc "y".

Chương trình theo dõi số hàng và số cột nhỏ nhất và lớn nhất phù hợp với các đầu vào cho đến nay và luôn đoán điểm trung tâm của phần phụ của các khả năng (làm tròn số NA). Chương trình có tính xác định, do đó, thật dễ dàng để tính toán số lần đoán mà nó yêu cầu trung bình trên một lưới cố định. Trên lưới 10x10, chương trình yêu cầu 1 lần đoán cho một ô vuông duy nhất, 2 lần đoán cho tám ô vuông, 3 lần đoán cho 64 ô vuông và 4 lần đoán cho 27 ô vuông còn lại, trung bình là 3,17; và đây là mức tối thiểu theo lý thuyết, được đưa ra có bao nhiêu chuỗi 1 lần đoán, 2 lần đoán, v.v. có thể dẫn đến những dự đoán đúng. Thật vậy, chương trình nên đạt được mức tối thiểu theo lý thuyết trên bất kỳ lưới kích thước nào vì những lý do tương tự. (Trên lưới 5x5, số lần đoán trung bình là 2,6.)

Một chút giải thích về mã, mặc dù nó khá đơn giản ngoài việc chơi gôn. (Tôi đã trao đổi thứ tự của một số câu lệnh khởi tạo cho mục đích lưu trữ Không ảnh hưởng đến số byte.)

1  For[a = f = 1; z = Characters; t = <|Thread[z@# -> #2]|> &;
2      v = Floor[+##/2] &; b := a~v~c; g := f~v~h;
3      r = ""; {c, h} = Input@Grid, 
4    r != "y", 
5    r = Input[g Alphabet[][[b]]];
6      {{a, c}, {f, h}} = {t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}]@#, 
7        t["uWX", {{g, g}, {f, g - 1}, {g + 1, h}}]@#2} & @@ 
8        Sort[z@r /. {c_} :> {c, "u"} /. "E" -> "X"]
   ]

Các dòng 1-3 khởi tạo Forvòng lặp, thực sự chỉ là một Whilevòng lặp được ngụy trang, vì vậy, hai byte ít hơn. Phạm vi số hàng và số cột có thể có tại bất kỳ thời điểm nào được lưu trữ {{a, c}, {f, h}}và dự đoán chính giữa trong chuỗi con đó được tính bởi các hàm {b, g}được xác định trong dòng 2. Dòng 3 khởi tạo cột tối đa cvà cột tối đa htừ đầu vào của người dùng và cũng khởi tạo rbiến được kiểm tra vòng lặp và cũng là đầu vào của người dùng tiếp theo.

Trong khi thử nghiệm trên dòng 4 được thỏa mãn, dòng 5 nhận đầu vào từ người dùng, trong đó lời nhắc đến từ dự đoán hiện tại {b, g}( Alphabet[][[b]]]chuyển đổi số hàng thành một chữ cái). Sau đó, các dòng 6-8 cập nhật các khả năng phụ (và do đó hoàn toàn là dự đoán tiếp theo). Ví dụ: t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}](được định nghĩa ttrên dòng 1) mở rộng thành

<| "N" -> {a, b - 1}, "S" -> {b + 1, c}, "u" -> {b, b}|>

nơi bạn có thể thấy các số hàng tối thiểu và hàng tối đa được cập nhật theo đầu vào cuối cùng của người dùng. Dòng 8 chuyển đổi bất kỳ đầu vào có thể nào thành một cặp ký tự được sắp xếp theo mẫu { "N" | "S" | "u", "u" | "W" | "X"}; ở đây "u"là viết tắt của một hàng hoặc cột chính xác và "X"là viết tắt của East (chỉ để cho phép Sorthoạt động độc đáo). Khi người dùng cuối cùng nhập vào "y", các dòng này đưa ra một lỗi, nhưng sau đó kiểm tra vòng lặp thất bại và lỗi không bao giờ được đưa ra (dù sao chương trình cũng chỉ dừng lại).


0

Batch, chia và chinh phục

@echo off
set z = ABCDEFGHIJKLMNOPQRSTUVWXYZ
set /p g = Grid?
set /a w = 0, n = 0, e = %g :x= + 1, s = % + 1
:l
set /a x = (w + e) / 2, y = (n + s) / 2
call set c = %%z :~%y%,1%%
set /p g = %c %%x%?
if %g :w=.% == %g % set /a w = x
if %g :n=.% == %g % set /a n = y
if %g :e=.% == %g % set /a e = x
if %g :s=.% == %g % set /a s = y
if %g :y=.% == %g % goto l

Hoạt động bằng cách tạo hộp giới hạn của khu vực vẫn cần tìm kiếm. Dự đoán tiếp theo luôn là trung tâm của hộp. Đối với những điểm la bàn không được bao gồm trong phản hồi, hộp được giảm theo hướng đó. Ví dụ, để trả lời N, bên trái, bên phải và dưới cùng của hộp được đặt thành hình vuông được đoán.

Với 369 byte, tôi không mong đợi đánh bại bất cứ ai vì vậy tôi đã để khoảng trống ở mức dễ đọc.


Chà, phân chia và chinh phục thường hữu ích cho các thử nghiệm lớn nhưng không phải cho các trường hợp nhỏ, thuật toán nào tốt hơn?
Matthew Roh

@SIGSEGV Không chắc ý của bạn là gì; Câu trả lời của Greg và Ben cũng sử dụng trung tâm của phương pháp hộp.
Neil

Chúng ta vẫn cần một thuật toán tốt hơn.
Matthew Roh

@SIGSEGV Trung tâm của phương thức hộp là tối ưu. Không có thuật toán tốt hơn.
TheNumberOne
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.