Más caliente o más frío: Encuentra el tesoro


8

Un cierto juego infantil, a menudo llamado "Huckle Buckle Beanstalk", se juega con dos jugadores. Aquí hay una breve descripción de cómo se juega el juego:

  1. Un jugador es designado el "oculto" y el otro el "buscador".
  2. El buscador sale de la habitación mientras el ocultador esconde un pequeño objeto preseleccionado, el "tesoro".
  3. Luego, el ocultante intenta buscar el objeto mientras el buscador le da consejos útiles:
    • Si el buscador se acerca al tesoro, el ocultador gritará "¡más cálido!"
    • Si el buscador se está alejando del tesoro, el ocultador gritará "¡más fresco!"
  4. Una vez que el buscador encuentra el tesoro, anuncian que lo han encontrado.

Tus hijos quieren que juegues este juego con ellos, sin embargo, estás muy ocupado respondiendo preguntas en codegolf.SE. Entonces, decides escribir un programa para jugar con ellos. Sin embargo, desea utilizar el menor tiempo posible para escribir, por lo que intenta hacer que el programa tenga la menor cantidad de caracteres posible.

Podemos definir la sala en la que se juega el juego como un campo cuadrado toroidal bidimensional. La coordenada 0,0es la esquina inferior izquierda y la coordenada 99,99es la esquina superior derecha. El tesoro se coloca en alguna posición n,mdonde ny mson ambos números enteros positivos entre 0 y 99 inclusive.

Su programa obtendrá información del reproductor utilizando su función de entrada de usuario incorporada (p prompt(). Ej . raw_input(), Etc.) Si su idioma elegido no tiene una función de entrada de usuario, tome la entrada de STDIN en su lugar. El juego funcionará de la siguiente manera:

  1. El programa "esconde" el tesoro en una posición n,m.
  2. El programa solicita al buscador que ingrese una posición de búsqueda inicial. La entrada vendrá en la forma x ydonde xy yson enteros positivos.
  3. El programa emite "correcto" si la posición de búsqueda inicial x,yes igual a la posición del tesoro n,my termina. De otra manera:
  4. El programa le pedirá al buscador que se mueva. La entrada viene en la forma a bdonde ay bson enteros que pueden ser negativos . Esto representa el vector de dirección en el que se mueve el buscador ( aes la dirección xy bes la dirección y).
  5. Si la posición resultante del buscador está en el tesoro, el programa sale "correcto" y termina. De otra manera:
  6. El programa genera "más frío" si el buscador se está alejando del tesoro o "más caliente" si se está moviendo hacia el tesoro.
  7. Ve al paso 4.

Las palabras "alejarse" y "moverse hacia" pueden ser ambiguas. Para este desafío, si la posición resultante del buscador después de moverse está más cerca del tesoro que su posición antes de moverse, se están moviendo hacia el tesoro. De lo contrario, se están alejando. (Sí, esto significa que si la posición resultante y la anterior están a la misma distancia, el programa debería salir "más frío").

Este es el código de golf, por lo que gana el código más corto. Haga preguntas si la especificación no es clara.


¿Las solicitudes de entrada deben contener algún texto / pregunta? Si es así, por favor especifíquelo.
Martin Ender

66
He visto este juego jugar muchas veces en la televisión y lo he hecho algunas veces, pero nunca escuché el término " Huckle Buckle Beanstalk ".
Calvin Aficiones

@ Martin No, no es necesario que haya ningún texto.
ajenjo

1
@Ipi El campo es toroidal, es decir, se envolverán al otro lado del campo.
Absenta

1
Los movimientos se envuelven, pero ¿qué pasa con el cálculo de la distancia? ¿La distancia entre (0,0) y (99,99) es igual a 1 o 99 · √2?
Tobia

Respuestas:


2

Javascript, 275 279

No es un ganador de ninguna manera, pero esto debería comenzar las cosas. Utiliza un truco eval()y se define 100como una "constante" para eliminar algunos bytes. Versión sin golf a continuación.

function D(){return Math.sqrt((x-n)*(x-n)+(y-m)*(y-m))}
H=100;
n=~~(Math.random()*H);m=~~(Math.random()*H);
P="s=prompt().split(' ')";
eval(P);
x=~~s[0];y=~~s[1];i=0;
while(x!=n||y!=m)
{
    if(i)alert(i>j?"hotter":"colder");
    i=D();
    eval(P);
    x=(x+~~s[0])%H;
    y=(y+~~s[1])%H;
    j=D()
}
alert("correct")

Editar: caí víctima de las operaciones de cadena + número de Javascript, por lo tanto, ¿por qué D()no funcionaba correctamente? También arreglé un error donde se mostraba "más caliente" antes de "correcto". Esto agrega 4 bytes.


1
¿Por qué usar punto y coma?
orgulloso Haskeller

Si ny mse establecen en cero (para propósitos de prueba), y 0 1se introduce como la posición inicial, tanto 0 -1y 0 1de retorno más frío.
es1024

En el bucle for, ¿por qué tienes nuevas líneas? Ponga todo el código en una línea y podrá guardar 22 caracteres (quizás más).
Beta Decay

1
Esta es la versión sin golf. La versión original es todo en una línea (275 caracteres de largo).
Sean Latham el

broma javascriptcolder == cooler
ajax333221

2

Python 3 - 238 bytes


Código:

from random import*
r=randint;a=100;X=r(0,a);Y=r(0,a);d=0;F=lambda:((X-x%a)**2+(Y-y%a)**2)**0.5;i=lambda:map(int,input().split());x,y=i()
while F():
 if d:print(["cooler","hotter"][d<D])
 D=F();Z,K=i();x+=Z+a;y+=K+a;d=F()
print("correct")

Sin golf:

from random import*

treasure_x = random.randint(0,100)
treasure_y = random.randint(0,100)
distance = lambda:((treasure_x - x % 100) ** 2 + (treasure_y - y % 100) ** 2) ** 0.5
x, y = map(int, input("Coordinates in the form x y: ").split())
new_distance = 0

while distance():
    if new_distance:
        if new_distance < prev_distance:
            print("hotter")
        else:
            print("cooler")
    prev_distance = distance()
    dx, dy = map(int, input("Move in the form dx dy: ").split())
    x = (dx + x) % 100
    y = (dy + y) % 100
    new_distance = distance()

print("correct")

Ejecución de muestra:

$ python hotter_colder.py 
50 50
10 0
cooler
-10 0
hotter
-10 0
hotter
-10 0
hotter
-10 0
hotter
-10 0
cooler
5 0
hotter
1 0
hotter
1 0
hotter
1 0
hotter
1 0
hotter
1 0
cooler
-1 0
hotter
0 10
cooler
0 -10
hotter
0 -10
hotter
0 -10
cooler
0 5
hotter
0 1
hotter
0 1
correct

No diré que mi estrategia para encontrar el tesoro es particularmente rápida ...


2

Groovy - 278 266 262

Golfizado:

def x,y,n,m,d,D=999,S=100,r=newScanner(System.in);n=Math.floor(Math.random()*S);m=Math.floor(Math.random()*S);while(true){x=r.nextInt();y=r.nextInt();d=Math.sqrt((x-n)**2+(y-m)**2);if(d==0){print"Correct";break;}else if(d<D){print"Cooler"}else{print"Hotter"}D=d}

Sin golf:

def x,y,n,m,d
def dist = 99999
def r = new Scanner(System.in)
def S = 100
n = Math.floor(Math.random()*S)
m = Math.floor(Math.random()*S)
println "Treasure is at: $n $m"
while(true){
    x = r.nextInt()
    y = r.nextInt()
    d = Math.sqrt((x-n)**2+(y-m)**2)
    if(d == 0){print "Correct"; break;}
    else if(d > dist){print "Hotter" }
    else{print "Cooler"}
    dist = d
}

Juicio:

-1 -1
Cooler 12 12
Cooler 14 14
Cooler 13 13
Hotter 15 15
Cooler 90 55
Cooler 95 -100
Hotter 95 83
Correct

¿Puede documentar algunas ejecuciones de muestra de esta solución en acción? Creo que Math.sqrt ((xn 2) + (ym 2)) devuelve NaN cuando x <n, y <m.
Michael Easter

Si seguro. Tan pronto como llegue a casa :)
Little Child

Genial ... Nota: según entiendo el OP, la entrada inicial es una posición absoluta, y las entradas posteriores son relativas. Además, la cuadrícula se envuelve (toroidal). No veo cómo funciona esto, tal como está, y me sorprende que haya recibido un voto positivo.
Michael Easter

@MichaelEaster Por favor revise la edición. Avíseme si he hecho algo mal :)
Little Child

He publicado mi solución, ya que entiendo el problema. No puedo comentar sobre el suyo, pero dejaré que los votantes decidan :)
Michael Easter

2

Groovy - 343 caracteres

Derivado algo de la respuesta de LittleChild .

Golfizado:

z=100
f={Math.floor(Math.random()*z)}
h={println it}
r=new Scanner(System.in)
i={r.nextInt()}
n=f();m=f();x=i();y=i();p=z;a=0;b=0
g={(Math.abs(it))**2};o={i,j->(j<0)?(((i+j)<0)?(((i+j)+z)%z):(i+j)):(i+j)%z};u={Math.sqrt g(n-x)+g(m-y)};d=u()
while(d>0.1){if(d<p){h "Hotter"}else{h "Cooler"};a=i();b=i();x=o(x,a);y=o(y,b);p=d;d=u()}
h "Correct"

Sin golf:

z=100
f={Math.floor(Math.random()*z)}
h={println it}
r=new Scanner(System.in)
i={r.nextInt()}

n=f();m=f()
x=i();y=i()
p=z;a=0;b=0

g = {(Math.abs(it))**2}
o = {i,j->(j<0)?(((i+j)<0)?(((i+j)+z)%z):(i+j)):(i+j)%z}
u = {Math.sqrt g(n-x)+g(m-y)};d=u()

while (d>0.1) {
    if (d<p) { h "Hotter" } else { h "Cooler" }
    a=i();b=i()
    x=o(x,a);y=o(y,b)
    p=d;d=u()
}
h "Correct"

Ejecución de muestra, donde el programa emite el objetivo para ilustración. Desde mi entendimiento de OP, la entrada inicial es absoluta, y las entradas posteriores son relativas. Además, la cuadrícula se envuelve.

ejecutar A:

bash$ groovy X.groovy 
goal 98.0 19.0
1 19
Hotter
-1 0
Cooler
-1 0
Hotter
-1 0
Correct

ejecutar B:

bash$ groovy X.groovy 
goal 93.0 20.0
90 16
Hotter
2 2
Hotter
1 0
Hotter
0 -18
Cooler
0 -1
Cooler
0 -1
Hotter
0 -79
Hotter
0 1
Correct

¡Me alegra que mi código te sea útil! aprobado :)
Little Child

2

APL, 86 caracteres

h←?2⍴s←100⋄1{h≡n←s|s+⍵+⎕:⎕←"correct"⋄⍺:0∇n⋄⎕←(</+/⊃×⍨n⍵-¨⊂h)⌷"cooler" "hotter"⋄0∇n}0 0

El cálculo de la distancia no se ajusta, pero los movimientos sí.

Sin golf:

h←?2⍴s←100                  ⍝ generate random starting point
1{                          ⍝ loop starting with ⍺←1 (1 if first loop) and ⍵←0 0 (position)
    n←s|s+⍵+⎕               ⍝ n←new position, ⍵ plus the move read from input, modulo 100
    n≡h: ⎕←"correct"        ⍝ check for end condition
    ⍺: 0∇n                  ⍝ if first loop, skip the rest and ask for a move again
    t←</+/⊃×⍨n⍵-¨⊂h         ⍝ t←1 if n is closer to h than ⍵ (squared distance)
    ⎕←t⌷"cooler" "hotter"   ⍝ output thermal gradient label
    0∇n                     ⍝ loop with new position
}0 0

Ejemplo:

⎕:
      22 33
⎕:
      2 6
hotter
⎕:
      0 1
cooler
⎕:
      0 ¯3
correct

2

Python 2.7, 227

from random import*
r=randint
h=100
n=r(0,h)
m=r(0,h)
i=lambda:map(int,raw_input().split())
x,y=i()
d=lambda:(x%h-n)**2+(y%h-m)**2
e=d()
while e:
 p=e;a,b=i();x+=a;y+=b;e=d()
 if e:print e<p and'hotter'or'cooler'
print'correct'

Obtuve la función de entrada y la idea de aplicar el módulo en el cálculo de distancia en lugar de la actualización de ubicación de la respuesta de matsjoyce.

Solo necesitamos distancias para las comparaciones: ¿Estamos en la ubicación exacta? ¿Estamos más cerca que antes? Para ambos, obtenemos el mismo resultado al comparar los cuadrados de las distancias como lo haríamos al comparar las distancias. El cálculo de raíz cuadrada requerido para obtener la distancia real es innecesario.

Sin golf:

import random

h = 100 # height (and width) of the square grid

# location of item
n = random.randint(0, h)
m = random.randint(0, h)

def input_pair():
    return map(int, raw_input().split())

x,y = input_pair()

def distance_squared():
    return (x % h - n)**2 + (y % h - m)**2

er = distance_squared()
while er:
    previous_er = er
    a,b = input_pair()
    x += a
    y += b
    er = distance_squared()
    if er:
        print 'hotter' if er < previous_er else 'cooler'
print 'correct'

Ejecución de muestra:

50 50
20 0
hotter
20 0
cooler
-20 0
hotter
10 0
cooler
-10 0
hotter
-1 0
hotter
-1 0
hotter
-5 0
cooler
5 0
hotter
-1 0
cooler
1 0
hotter
1 0
cooler
-1 0
hotter
0 10
hotter
0 10
hotter
0 10
cooler
0 -5
hotter
0 -1
hotter
0 -1
hotter
0 -1
correct

El truco con los cuadrados, ignorando el paso de la raíz cuadrada, es muy inteligente. +1
ajenjo

1

ECMAScript 6, 262

Z=100;A=Math.abs;P=(a,b)=>(q=Math.min(A(a-b),Z-A(a-b)),q*q);G=_=>prompt().split(' ');R=_=>new Date%Z;V=_=>P(X,I)+P(Y,J);I=R();L=G();X=+L[0];Y=+L[1];J=R();for(D=V();D;D=N)T=G(),X=(+T[0]+Z+X)%Z,Y=(+T[1]+Z+Y)%Z,N=V(),N&&alert(N<D?"hotter":"cooler");alert("correct")

Sin golf:

Z=100;
M=Math.min;
A=Math.abs;
S=a=>a*a;
P=(a,b)=>S(M(A(a-b),Z-A(a-b)));
G=_=>prompt().split(' ');
R=_=>new Date%Z;
V=_=>P(X,I)+P(Y,J);
I=R();
L=G();
X=+L[0],Y=+L[1];
J=R();
for(D=V();D;D=N)
    T=G(),
    X=(+T[0]+Z+X)%Z,Y=(+T[1]+Z+Y)%Z,
    N=V(),
    N&&alert(N<D?"hotter":"cooler");
alert("correct")

1

C 193 176 171

#define F x*x+y*y
x,y,a,b,d;main(){srand(time(0));x=rand();y=rand();while(scanf("%d %d",&a,&b),x-=a,x%=100,y-=b,y%=100,puts(F?F<d?"hotter":d?"cooler":"":"correct"),d=F);}

Estoy seguro de que debe haber ahorros en la generación de números aleatorios. Aparte de eso, el punto clave es que la lectura en x & y solo se trata como un desplazamiento de 0, por lo que solo necesito un scanf. Sin embargo, significa que tengo que suprimir la impresión más caliente o más fría en la primera iteración.

Cambios:

Coloque la ubicación en x & y directamente y luego vuelva a colocarla en (0,0) en lugar de ponerla en m & n y use x & y para buscarla.

Me di cuenta de que estaba imprimiendo "más caliente" y "correcto", así que tuve que agregar tres caracteres adicionales aquí.

Reescribió la impresión para poner todas las condiciones en ella, guardando una llamada extra a Puts ().


1

JavaScript ES6, última versión de Firefox, 177 173 164 caracteres

Obviamente, esto no puede vencer al APL. ¡Ese idioma es una locura! Tal vez desarrollado únicamente para preguntas de código de golf: D: P

Pero aquí va mi solución en ES6 JavaScript. Ejecútelo en la última versión de Firefox Nightly (o también puede ser una versión de lanzamiento) en la Consola web o el Bloc de notas.

A=a=>a*a;a=alert;g=v=>[x,y]=prompt().split(" ");r=v=>Math.random()*100|0;n=r(m=r(d=0));D=v=>A(n-x)+A(m-y);while(d=D(g(l=d)))l&&a(l<d?"hotter":"cooler");a("correct")

Me gustaría omitir la versión sin golf por ahora. Comenta si quieres ver la versión sin golf :)

EDITAR : ¡Golfé mucho! reducido 9 caracteres. Todavía viendo si más alcance del golf.


0

Python 226

from random import randint as r
x=r(0,100)
y=r(0,100)
l=9**9
while True:
    i,j=map(int,raw_input().split())
    if x==i and y==j:
        print 'correct'
        break
    c=(x-i)**2+(y-j)**2
    if c<l:print 'warmer'
    elif c>l:print 'colder'
    l=c

Ese import ve muy largo y estúpido, pero en realidad me ahorra 8 caracteres.:D

Juego de ejemplo:

50 50
warmer
50 75
colder
50 25
warmer
50 13
colder
50 37
colder
50 20
warmer
50 21
warmer
50 22
warmer
50 23
warmer
50 24
warmer
50 26
colder
50 25
warmer
25 25
colder
75 25
warmer
74 25
warmer
62 25
warmer
61 25
warmer
55 25
colder
56 25
warmer
57 25
warmer
58 25
warmer
59 25
warmer
60 25
warmer
61 25
warmer
62 25
colder
61 25
warmer
61 24
correct

0

Sinclair / ZX Spectrum BASIC - 305 bytes

10 RANDOMIZE:LET o=99:LET a=INT(RND*99)+1:LET b=INT(RND*99)+1:PRINT a,b
20 INPUT "sx,sy:";c,d
30 LET g=SQR(ABS(a-c)^2+ABS(b-d)^2)
40 PRINT g'c,d
60 IF g=0 THEN PRINT "Found!":STOP
70 INPUT "mx,my:";x,y:LET c=c+x:let d=d+y
80 PRINT ("hotter" AND g<o)+("colder" AND g>o)
90 LET o=g:GOTO 30

Como Spectrum almacena cada palabra clave como un byte, ayuda a mantener el tamaño bajo. Después de ingresarlo, descubra el tamaño con

print "bytes:";peek 23641+256*peek 23642-(peek 23635+256*peek 23636)+1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.