Un juego de adivinanzas plano

13

Hay un juego que me gusta jugar. Sucede en una cuadrícula de tamaño finito (pero está envuelta, como una esfera). En esa cuadrícula, se selecciona un punto aleatorio (solo entero). Luego, a mí, el usuario, se me solicita una entrada de coordenadas. Si mi entrada coincide exactamente con el punto aleatorio, me dicen que he ganado. De lo contrario, me informan la distancia de punto entre mi entrada y el punto aleatorio. Por ejemplo, si supuse que (2,2)el punto aleatorio estaba en (4,3), entonces la distancia sería sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

El juego continúa hasta que el jugador llega a la ubicación correcta del punto.


Objetivo Crear una versión funcional del juego descrita anteriormente. Debe crear un programa completo para hacerlo. Esto es lo que debe hacer su programa:

  1. Solicite dos entradas: la altura y el ancho de la placa. El origen está en la esquina superior izquierda del tablero. Estas entradas no excederán 1024.
  2. Seleccione un punto aleatorio en ese tablero; este será el punto a adivinar.
  3. Aceptar entrada simulando un giro. La entrada será un par de enteros separados por espacios o dos entradas enteras separadas. En respuesta a esta entrada, el programa hará una de dos cosas:
    1. Si la entrada coincide con el punto aleatorio seleccionado, envía un mensaje que indica la victoria del usuario. Sugeriría "¡Ganaste!".
    2. De lo contrario, muestre la distancia entre el punto de entrada del usuario y el punto aleatorio.
    En cualquier caso, debe incrementar el contador de turnos.
  4. Una vez que el usuario haya logrado la victoria, muestre el número de turnos que tomó el usuario. El programa se cierra.

Bonos

Los bonos se aplican en el orden en que aparecen en esta lista

  • -150 bytes si su programa toma un entero de entrada Dque describe la dimensión en la que se desarrolla el juego. Por ejemplo, si D = 3crea un punto aleatorio de 3enteros, toma 3entradas enteras y genera la distancia entre esos puntos.
  • -50% (o + 50% si score < 0) si proporciona una representación gráfica del tablero (ASCII o imagen) que muestra dónde el usuario ha adivinado previamente en la cuadrícula de dimensiones dadas y el contador de giros. (Si opta por el primer bono, este bono solo se aplica a los modos 2Dy 1D. Si agrega una salida gráfica en 3D, obtendrá un -50% adicional).
  • -60 bytes si puede proporcionar un modo de juego (seleccionado por una entrada al principio; es decir, cuando se le dé 0, realice el modo de juego normal; cuando se le dé 1, realice este modo de juego) en el que el punto se mueve 1 unidad en una dirección ortogonal aleatoria por turno

Más sobre envoltura

El ajuste ocurre solo cuando, en el tercer bono, el punto de movimiento se mueve a través de cualquiera de los límites; en este caso, el punto móvil se deforma al punto respectivo, así:

...              ...
..R (move right) R..
...              ...

Este comportamiento de ajuste no afecta la suposición del usuario, además del hecho de que el punto ha cambiado de dirección.


Tabla de clasificación

El Fragmento de pila al final de esta publicación genera el catálogo a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

# Perl, 43 + 2 (-p flag) = 45 bytes

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Conor O'Brien
fuente
77
Nitpick menor: probablemente quieras decir que se envuelve como un toro, no como una esfera. Es imposible envolver una cuadrícula 2D en una esfera sin crear discontinuidades.
Alistair Buxton
2
Además, si el tablero se enrolla, entonces podría haber un camino más corto entre adivinar y objetivo al cruzar un borde.
Alistair Buxton
1
@NBZ Sí, puedes.
Conor O'Brien el
1
@NBZ 1 unidad en una sola dirección.
Conor O'Brien el
2
1. Todavía no estoy seguro de cuál es la topología. Para ayudar a aclarar las cosas, si el tablero es 10x10, el punto aleatorio es (9,4), y supongo (2,2), ¿es la distancia sqrt(13)o sqrt(53)? (Nota para el futuro: si está haciendo algo extraño, no incluya la aleatoriedad porque hace que sea casi imposible suministrar casos de prueba). 2. En el tercer bono, ¿se debe calcular y generar la distancia antes o después de que se mueva el punto?
Peter Taylor

Respuestas:

8

Cjam, -113 -139 -152 -157 -159 bytes

l~]:B:mr{_ea:i~mr0a*W2mr#+*.+B:,.=_[l~].-:mh_p}g],(

El programa tiene 51 bytes de largo y califica para el bonos de -150 bytes y -60 bytes .

El modo de juego y el número de dimensiones se leen como un argumento de línea de comandos, el tamaño en cada dimensión de STDIN. Ya que el mensaje de victoria es arbitrario , el programa imprimirá 0.0(distancia al gol) para indicar que el juego ha terminado.

Pruebas de funcionamiento

$ cjam game.cjam 0 3; echo
2 2 2
1 1 1
1.4142135623730951
1 1 0
1.7320508075688774
1 0 1
1.0
0 0 1
0.0
4
$ cjam game.cjam 1 3; echo
2 2 2
0 0 0
1.0
0 0 0
0.0
2

Cómo funciona

l~]       e# Read a line from STDIN, evaluate it and collect the result.
:B        e# Save the resulting array in B. The result is [B1 ... Bd],
          e# where Bk is the board size in dimension k.
:mr       e# Pseudo-randomly select a non-negative integer below Bk,
          e# for each k between 1 and d.
{         e# Do:
  _       e#   Copy the item on the stack. The original becomes a dummy value
          e#   that will be used to count the number of turns.
  ea      e#   Push the array of command-line arguments.
  :i~     e#   Cast each to integer and dump them on the stack.
          e#   This pushes m (game mode) and d (number of dimensions).
  mr      e#   Pseudo-randomly select a non-negative integer below d.
  0a*     e#   Push an array of that many zeroes.
  W2mr#   e#   Elevate -1 to 0 or 1 (selected pseudo-randomly).
  +       e#   Append the result (1 or -1) to the array of zeroes.
  *       e#   Repeat the array m times.
  .+      e#   Perform vectorized addition to move the point.
  B:,.=   e#   Take the k-th coordinate modulo Bk.
  _[l~]   e#   Push a copy and an evaluated line from STDIN.
  .-:mh   e#   Compute their Euclidean distance.
  _p      e#   Print a copy.
}g        e# While the distance is non-zero, repeat the loop.
],(       e# Get the size of the stack and subtract 1.
          e# This pushes the number of turns.
Dennis
fuente
2
Y Dennis ha superado a todos. De nuevo.
Seadrus
1
Actualizaste accidentalmente el puntaje a 152 en lugar de -152, poniéndote en último lugar en la clasificación
Moose
7

Pyth, 91 (-150 -60) = -119

VvwaYOvw;JY#IqQ1=dOlY XYd@S[0 @Jd +@Yd?O2_1 1)1)=T[)VYaT^-Nvw2)=ZhZ=b@sT2Iqb0Bb;p"Won in "Z

Solución anterior: (54-150 = -96)

JYVQaYOvw;#=J[)VYaJ^-Nvw2)=ZhZ=b@sJ2Iqb0Bb;p"Won in "Z

Toda la entrada tiene lugar en una nueva línea.

  • El primer entero representa el modo de juego ( ya sea 1o0 )
  • Primer segundo entero Drepresenta las dimensiones del juego.
  • Las siguientes Dentradas representan el tamaño del campo
  • Todas las Dentradas a partir de este momento son conjeturas

Reproducción de muestra (las sugerencias no aparecen en el programa real):

  #Hint: Gamemode (1 or 0)
1
  #Hint: Dimensions
3
  #Hint: X-size
4
  #Hint: Y-size
4
  #Hint: Z-size
4
  #Hint: Guesses
  #Hint:[3, 2, 1]
3
2
2
1.0
  #Hint:[3, 2, 1]
3
2
1
1.0
  #Hint:[2, 2, 1]
2
2
1
1.0
  #Hint:[3, 2, 1]
3
2
1
Won in 4
Alce
fuente
¿No debería ganar el segundo movimiento?
JNF
@JNF el punto puede moverse en el modo de juego 1 (bonificación de -60 bytes)
Jakube
Santo Moly, ese es un código pyth largo. Aunque en realidad no es golf. Por ejemplo, veo dos espacios, que se pueden eliminar. Además: puede usar en J=YmOvwvwlugar de VvwaYOvw;JY, que es 2 bytes más corto. No he revisado el otro código, pero supongo que también puedes acortar algunas cosas allí.
Jakube
@ Jakube, estaba asumiendo que la pista nos dice dónde está el punto actualmente
JNF
3

Pitón 2, 210-150 = 60

from random import*
q,r,o=map,raw_input,int
a=q(randrange,q(o,r().split(' ')))
m=q(o,r().split(' '))
t=1
while m!=a:print sum([(c-d)**2for c,d in zip(m,a)])**.5;m=q(o,r().split(' '));t+=1
print'You won in %d'%t

Primer desafío solo hasta ahora. Pruébalo en línea

Mego
fuente
3

Pip, 43 42 bytes - 150 = -108

Toma las dimensiones del tablero como argumentos de línea de comandos (con D implicada por el número de argumentos). Toma conjeturas como números separados por espacios en stdin.

YRR_MgWd:++i&RT$+(y-(q^s))**2Pd"Won in ".i

Este código aprovecha al máximo las características de programación de matriz de Pip. La matriz de cmdline args se almacena en g. Generamos el punto de ser adivinado por la cartografía del operador randrange RRmás g, y un tirón a la lista resultante en la yvariable. Luego viene el ciclo while principal, donde la condición es la siguiente:

d:++i&RT$+(y-(q^s))**2

  ++i&                  Increment i, the guess counter; the result is always > 0, so the
                          short-circuiting & operator evaluates the next expression:
              q         Read a line from stdin
               ^s       Split on spaces
           y-(   )      Subtract from our chosen point itemwise
          (       )**2  Square, itemwise
        $+              Fold on +, summing the list of squares
      RT                Square root
d:                      Assign this distance to d

Si la distancia no era cero, el interior del bucle lo imprime. Si fue cero, hemos alcanzado el punto objetivo; el bucle se detiene y el programa emite el mensaje ganador y el número de turnos.

Ejemplo de ejecución:

C:\Users\dlosc> pip.py -f guessing.pip 10 5 6 4
5 2 3 2
3.1622776601683795
6 2 3 2
4.123105625617661
3 2 3 2
1.4142135623730951
3 1 3 2
2.23606797749979
3 2 2 2
1.7320508075688772
2 2 3 2
1
2 2 3 1
1.4142135623730951
2 3 3 2
Won in 8
DLosc
fuente
2

R, 134-150 = -16 bytes

function(...){G=sapply(list(...),sample,1)
C=0
repeat{g=scan()
C=C+1
if(any(G!=g))cat(sqrt(sum((G-g)^2)))else{cat("Won in",C);break}}}
flodel
fuente
2

Haskell, 240-150 = 90

import System.Random
r x=randomRIO(0,x-1)
m=map read.words
g=getLine
main=do g;(fmap m g::IO[Int])>>=mapM r>>=b 1
b c v=do i<-fmap(sqrt.fromIntegral.sum.map(^2).zipWith(-)v.m)g;if i==0 then putStrLn$"Won in "++show c else do print i;b(c+1)v
Damien
fuente
1

Dyalog APL , 77 71 - 210 = -139

S F M
P←?S
{P←S|P+(?D)⌽D↑Mׯ1 1[?2]
C+←1
P≢G←⎕:0⊣⎕←.5*⍨+/2*⍨P-G
C}⍣≢C←0

Okay:

Tenga en cuenta que esto se ejecuta en el índice de origen 0 ( ⎕IO←0), que es el predeterminado en muchas APL.
Toma el modo booleano como argumento derecho ( M) y los tamaños de dimensión como argumento izquierdo ( S).
El número de dimensiones es D, que debe establecerse (por ejemplo, D←3antes de llamar, según OP).
P←?Sel objetivo obtiene un punto aleatorio en el rango 1, aunque cada uno de los límites de la dimensión
{... }⍣≢C←0repita la función hasta que el resultado sea diferente de C, que inicialmente obtiene 0
?2el número aleatorio 0 o 1
¯1 1[... el ]índice de la lista de dos números se
multiplica por modo; hace que 0si el modo es 0
D↑pad con 0s para que coincida con el número de dimensiones, ajuste el objetivo actual módulo de tamaño mundial
(?D)⌽ gire la lista al azar (0 a través del número de dimensiones-1)
P+
S|
P←guarde una nueva entrada de
C+←1contador de incremento de punto objetivo
P≢G←⎕:y, si es diferente del punto objetivo, entonces ... las
P-Gdistancias en cada dimensión al
2*⍨cuadrado
+/suman
.5*⍨la
⎕←impresión de raíz cuadrada que
0⊣devuelve 0 (es decir, idéntico al valor inicial, repita)
C... de lo contrario, devuelve el número de conjeturas (que, al ser diferente de 0, detiene el bucle y devuelve el último valor)

Adán
fuente
@Dennis En realidad, lo rompí cuando lo convertí en una función, así que ahora es un programa nuevamente. Ahorré tantos bytes como me costó "programmity" al cambiar al origen de índice 0, que OP permite.
Adám
1
OKAY. Por curiosidad: ¿qué dialecto es este? No tengo idea de lo que se supone que debe hacer la primera línea ...
Dennis
@Dennis Dyalog. Esta es una función tradicional, la primera línea es la línea [0], es decir, el encabezado de la función, pero parece inusual porque tiene left-arg fn-name right-arg, pero ningún resultado.
Adám