¡Vamos a jugar a las escondidas!

12

El usuario se ocultará y la computadora intentará encontrarlos.

Primero, el programa tomará una entrada, para el tamaño de la cuadrícula. Como 5x5, 10x10, 15x15, etc. La cuadrícula no siempre será un cuadrado perfecto.

La cuadrícula es algo así como un tablero de ajedrez:

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

Ahora, el usuario elegirá un cuadrado, como B2(sin decirle a la computadora)

La computadora comenzará a adivinar cuadrados. Si elige el cuadrado correcto, el usuario responderá con y. De lo contrario, ingresarán la dirección de su mosaico desde la seleccionada (N, NE, E, SE, S, SW, W).

Entonces, si el usuario escogió B2, y la computadora adivinó C3, el usuario ingresaría NW.

Aquí hay un ejemplo de las salidas y entradas:

Grid?
5x5

C3?
NW

C2?
N

B2?
y

Puntuación:

Esto se puntuará de manera un poco diferente a un desafío normal.

El ganador es el programa que toma el menor número de conjeturas (en promedio) para adivinar el cuadrado correcto. Los casos de prueba a promediar serán todos los cuadrados posibles en un 5x5 y luego en un 10x10.

Sin embargo, también debe funcionar con cada patrón de cuadrícula de hasta 26 filas (es decir, 5x8, 6x2, 20x5, etc.).

Incluya una forma de probarlo, como un JSFiddle.

Y, por último, en caso de empate, gana el programa más corto.

JKonowitz
fuente
1
Si me estoy escondiendo A1y la computadora adivina B9, ¿es la respuesta adecuada NWo W?
Greg Martin
@ GregMartin Sería NW ... N, W, S, E debe ser todo recto, mientras que cualquier cosa en una fila / columna diferente debe ser NW, NE, SW, SE
JKonowitz
¿Hay flexibilidad en el formato específico de entrada y salida? Si hay más de 26 filas, ¿cómo se llaman?
Greg Martin
@GregMartin Puede ser flexible con la salida pero intente que sea simple. No tiene que ser exactamente igual, pero debe tener un estilo similar. No necesita dar cuenta de nada por encima de 26, lo editaré.
JKonowitz
No sé qué significa "estilo similar". ¿Podemos tomar la entrada como un par ordenado de enteros (fila #, col #)? (PD: este tipo de preguntas son razones por las cuales es una gran idea publicar previamente desafíos en el Sandbox ).
Greg Martin

Respuestas:

3

Python 3.6 , 466 398 392 bytes, 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)

La entrada y la salida deben estar en la forma que se muestra en el ejemplo. Esto encuentra el cuadrado con el "factor de división" mínimo, que es el área restante más grande que puede resultar de la respuesta del jugador (es decir, NO, E, y, etc.), y adivina eso. Sí, ese es siempre el centro del área restante en este juego, pero esta técnica de minimizar el peor de los casos funcionará de manera más general en juegos similares con reglas diferentes.

Versión ilegible:

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]
Ben Frankel
fuente
2

Mathematica, comportamiento óptimo en casos de prueba, 260 bytes

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

Este programa se puede probar cortando y pegando el código anterior en Wolfram Cloud . (Sin embargo, pruebe rápidamente: creo que hay un límite de tiempo para cada ejecución del programa). Las suposiciones del programa se ven en 2 clugar de C2, pero de lo contrario, se ejecutan de acuerdo con las especificaciones anteriores. La cuadrícula debe ingresarse como un par ordenado de enteros, como {26,100}, y las respuestas a las conjeturas del programa deben ingresarse como cadenas, como "NE"o "y".

El programa realiza un seguimiento del número de fila y columna más pequeño y más grande que sea consistente con las entradas hasta el momento, y siempre adivina el punto central de la subcuadrícula de posibilidades (redondeando NO). El programa es determinista, por lo que es fácil calcular el número de conjeturas que requiere en promedio en una cuadrícula fija. En una cuadrícula de 10x10, el programa requiere 1 conjetura para un solo cuadrado, 2 conjeturas para ocho cuadrados, 3 conjeturas para 64 cuadrados y 4 conjeturas para los 27 cuadrados restantes, para un promedio de 3.17; y este es el mínimo teórico, dada la cantidad de secuencias de 1 conjetura, 2 conjeturas, etc., que pueden conducir a conjeturas correctas. De hecho, el programa debería alcanzar el mínimo teórico en una cuadrícula de cualquier tamaño por razones similares. (En una cuadrícula de 5x5, el número promedio de conjeturas es 2.6.)

Una pequeña explicación del código, aunque es bastante sencillo aparte del golf. (Intercambié el orden de algunas declaraciones de inicialización con fines de exposición, sin efecto en el recuento de bytes).

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

Las líneas 1-3 inicializan el Forbucle, que en realidad es solo un Whilebucle disfrazado, así que bueno, dos bytes menos. Los posibles rangos de número de fila y número de columna en cualquier momento se almacenan {{a, c}, {f, h}}, y la suposición centrada en esa subcuadrícula se calcula mediante las funciones {b, g}definidas en la línea 2. La línea 3 inicializa la fila cmáxima y la columna máxima a hpartir de la entrada del usuario, y también inicializa rcuál es la variable probada en bucle y también las entradas de usuario posteriores.

Mientras se satisface la prueba en la línea 4, la línea 5 recibe información del usuario, donde la solicitud proviene de la suposición actual {b, g}( Alphabet[][[b]]]convierte el número de fila en una letra). Luego, las líneas 6-8 actualizan la subcuadrícula de posibilidades (y, por lo tanto, implícitamente, la siguiente suposición). Por ejemplo, t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}](dada la definición de ten la línea 1) se expande a

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

donde puede ver los números de fila mínima y fila máxima que se actualizan de acuerdo con la última entrada del usuario. La línea 8 convierte cualquier entrada posible en un par ordenado de caracteres del formulario { "N" | "S" | "u", "u" | "W" | "X"}; aquí "u"representa una fila o columna correcta, y "X"significa Este (solo para permitir Sortque funcione bien). Cuando el usuario finalmente ingresa "y", estas líneas arrojan un error, pero luego la prueba de bucle falla y el error nunca se propaga (el programa simplemente se detiene de todos modos).

Greg Martin
fuente
0

Lote, divide y vencerás

@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

Funciona creando el cuadro delimitador del área que aún se debe buscar. La siguiente suposición es siempre el centro de la caja. Para aquellos puntos de la brújula que no están incluidos en la respuesta, el cuadro se reduce en esa dirección. Por ejemplo, para una respuesta de N, la izquierda, la derecha y la parte inferior del cuadro se establecen en el cuadrado adivinado.

Con 369 bytes, no espero vencer a nadie, así que dejé los espacios para la lectura.

Neil
fuente
Bueno, dividir y conquistar es generalmente útil para grandes casos de prueba, pero no para casos pequeños, ¿algún algoritmo mejor?
Matthew Roh
@SIGSEGV No estoy seguro de lo que quieres decir; Las respuestas de Greg y Ben también usan el método del centro del recuadro.
Neil
Todavía necesitamos un mejor algoritmo.
Matthew Roh
@SIGSEGV El método del centro de caja es óptimo. No hay mejor algoritmo.
TheNumberOne