Mais quente ou mais frio: encontre o tesouro


8

Um jogo infantil, chamado "Huckle Buckle Beanstalk", é jogado com dois jogadores. Aqui está uma breve descrição de como o jogo é jogado:

  1. Um jogador é designado "hider" e o outro, "seeker".
  2. O buscador sai da sala enquanto o hider esconde um pequeno objeto pré-selecionado, o "tesouro".
  3. O caminhante tenta procurar o objeto enquanto o buscador dá dicas úteis:
    • Se o buscador estiver se aproximando do tesouro, o caminhante gritará "mais quente!"
    • Se o buscador estiver se afastando do tesouro, o caminhante gritará "mais frio!"
  4. Uma vez que o buscador encontra o tesouro, eles anunciam que o encontraram.

Seus filhos querem que você jogue esse jogo com eles; no entanto, você está muito ocupado respondendo perguntas no codegolf.SE. Então, você decide escrever um programa para jogar o jogo com eles. No entanto, você deseja usar o menor tempo possível digitando, para tentar tornar o programa o mínimo possível de caracteres.

Podemos definir a sala em que o jogo é jogado como um campo quadrado toroidal bidimensional. A coordenada 0,0é o canto inferior esquerdo e a coordenada 99,99é o canto superior direito. O tesouro é colocado em alguma posição n,monde ne msão números inteiros positivos entre 0 e 99, inclusive.

Seu programa obterá entrada do reprodutor usando sua função de entrada embutida do usuário (por exemplo prompt(), raw_input()etc.) Se o idioma escolhido não possuir uma função de entrada do usuário, use a entrada STDIN. O jogo funcionará da seguinte maneira:

  1. O programa "oculta" o tesouro em uma posição n,m.
  2. O programa solicita que o candidato insira uma posição de pesquisa inicial. A entrada virá na forma em x yque xe ysão números inteiros positivos.
  3. O programa emitirá "correto" se a posição de pesquisa inicial x,yfor igual à posição do tesouro n,me terminar. De outra forma:
  4. O programa solicitará que o candidato se mova. A entrada vem no formato a bonde ae bsão números inteiros que podem ser negativos . Isso representa o vetor de direção em que o buscador está se movendo ( aé a direção xe a direção by).
  5. Se a posição resultante do buscador estiver no tesouro, o programa emitirá "correto" e será encerrado. De outra forma:
  6. O programa gera "mais frio" se o buscador estiver se afastando do tesouro ou "mais quente" se estiver se movendo em direção ao tesouro.
  7. Vá para o passo 4.

As palavras "afastando-se" e "movendo-se para" podem ser ambíguas. Para este desafio, se a posição resultante do buscador depois de se mover estiver mais próxima do tesouro do que a posição anterior, eles estão se movendo em direção ao tesouro. Caso contrário, eles estão se afastando. (Sim, isso significa que, se a posição resultante e a anterior estiverem à mesma distância, o programa deverá produzir "mais frio").

Isso é código de golfe, então o código mais curto vence. Faça perguntas se a especificação não estiver clara.


Os avisos de entrada precisam conter algum texto / pergunta? Nesse caso, especifique-o.
Martin Ender

6
Eu já vi esse jogo jogar muitas vezes na TV e já o fiz algumas vezes, mas nunca ouvi o termo " Huckle Buckle Beanstalk ".
Hobbies de Calvin

@ Martin Não, não precisa haver nenhum texto.
absinto

1
@Ipi O campo é toroidal, ou seja, eles se espalham para o outro lado do campo.
absinto

1
Os movimentos envolvem, mas e o cálculo da distância? A distância entre (0,0) e (99,99) é igual a 1 ou 99 · √2?
Tobia

Respostas:


2

Javascript, 275 279

Não é um vencedor, por qualquer meio, mas isso deve começar as coisas. Usa um truque eval()e define 100como uma "constante" para economizar alguns bytes. Versão não destruída abaixo.

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

Edit: Eu fui vítima das operações de string + number do Javascript, por isso D()não estava funcionando corretamente. Eu também corrigi um erro em que "hotter" era exibido antes de "correto". Isso adiciona 4 bytes.


1
por que usar ponto e vírgula?
proud haskeller

Se ne msão ambos definidos como zero (para fins de teste) e 0 1são inseridos como a posição inicial, ambos 0 -1e 0 1retornam mais frios.
precisa saber é o seguinte

No loop for, por que você tem novas linhas? Coloque todo o código em uma linha e você poderá salvar 22 caracteres (talvez mais).
Beta Decay

1
Esta é a versão não destruída. A versão original está toda em uma linha (275 caracteres).
Sean Latham

piada javascriptcolder == cooler
ajax333221 de 11/11/14

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

Ungolfed:

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

Exemplo de execução:

$ 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

Não direi que minha estratégia para encontrar o tesouro é particularmente rápida ...


2

Groovy - 278 266 262

Golfe:

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}

Ungolfed:

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
}

Tentativas:

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

Você pode documentar alguns exemplos de execuções desta solução em ação? Eu acredito que Math.sqrt ((xn 2) + (ym 2)) retorna NaN quando x <n, y <m.
Michael Easter

Sim claro. Assim que eu chegar em casa :)
Criança pequena

Legal ... Nota: como eu entendo o OP, a entrada inicial é uma posição absoluta e as entradas subsequentes são relativas. Além disso, a grade envolve (toroidal). Não vejo como isso funciona, como está, e estou surpreso por ter recebido um voto positivo.
Michael Easter

@MichaelEaster Verifique a edição. Deixe-me saber se eu ter feito nada de errado :)
Criança pequena

Publiquei minha solução, pois entendi o problema. Eu não posso comentar sobre o seu, mas permitirá que os eleitores decidir :)
Michael Páscoa

2

Groovy - 343 caracteres

Derivado um pouco da resposta de LittleChild .

Golfe:

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"

Ungolfed:

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"

Exemplo de execução, em que o programa emite o destino para ilustração. Pelo meu entendimento do OP, a entrada inicial é absoluta e as entradas subsequentes são relativas. Além disso, a grade envolve.

execute A:

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

Execute 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

Fico feliz que meu código seja útil para você! polegares para cima :)
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

A computação à distância não se aplica, mas os movimentos se aplicam.

Ungolfed:

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

Exemplo:

⎕:
      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'

Eu obtive a função de entrada e a idéia de aplicar o módulo no cálculo da distância, em vez da atualização da localização da resposta de matsjoyce.

Só precisamos de distâncias para comparações: estamos no local exato? Estamos mais perto do que antes? Para ambos, obtemos o mesmo resultado comparando os quadrados das distâncias que comparamos as distâncias. O cálculo de raiz quadrada necessário para obter a distância real é desnecessário.

Ungolfed:

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'

Exemplo de execução:

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

O truque com as praças, ignorando a etapa raiz quadrada, é muito inteligente +1.
o absinto

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

Ungolfed:

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);}

Tenho certeza de que deve haver economia na geração de números aleatórios. Além disso, o ponto principal é que a leitura em x e y é apenas tratada como um deslocamento de 0, então eu só preciso de um scanf. Isso significa que eu tenho que suprimir a impressão mais quente ou mais fria na primeira iteração.

Alterar:

Coloque o local em x & y diretamente e, em seguida, mude para (0,0) em vez de colocá-lo em m & n e use x & y para procurá-lo.

Percebi que estava imprimindo "mais quente" e "correto", então tive que adicionar mais três caracteres aqui.

Reescreveu a impressão para colocar todas as condições nela, salvando uma chamada extra para puts ().


1

JavaScript ES6, Firefox mais recente, 177 173 164 164 caracteres

Obviamente, isso não pode superar o APL. Essa linguagem é louca! Talvez desenvolvido exclusivamente para questões de código-golfe: D: P

Mas aqui está minha solução no ES6 JavaScript. Execute-o no Firefox Nightly mais recente (ou também na versão de lançamento) no console da Web ou no Scratchpad.

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

Eu gostaria de pular a versão ungolfed por enquanto. Comente se você quiser ver a versão não destruída :)

EDIT : Golf muito! reduzido 9 caracteres. Ainda vendo se há mais escopo de golfe.


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

Isso importparece muito longo e estúpido, mas na verdade me salva 8 caracteres.:D

Exemplo de jogo:

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 o Spectrum armazena cada palavra-chave como um byte, ajuda a manter o tamanho baixo. Depois de inserido, descubra o tamanho com

print "bytes:";peek 23641+256*peek 23642-(peek 23635+256*peek 23636)+1
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.