Nóng hơn hoặc lạnh hơn: Tìm kho báu


8

Một trò chơi trẻ em nhất định, thường được gọi là "Huckle Buckle Beanstalk", được chơi với hai người chơi. Dưới đây là một mô tả ngắn gọn về cách chơi trò chơi:

  1. Một người chơi được chỉ định là "người lái" và người còn lại là "người tìm kiếm".
  2. Người tìm kiếm đi ra khỏi phòng trong khi người cưỡi giấu một vật nhỏ, được chọn sẵn, "kho báu".
  3. Người đi sau đó cố gắng tìm kiếm đối tượng trong khi người tìm kiếm cho họ những gợi ý hữu ích:
    • Nếu người tìm kiếm đang tiếp cận kho báu, người cưỡi ngựa sẽ gọi "ấm hơn!"
    • Nếu người tìm kiếm đang di chuyển ra khỏi kho báu, người cưỡi ngựa sẽ gọi "mát hơn!"
  4. Một khi người tìm kiếm tìm thấy kho báu, họ thông báo rằng họ đã tìm thấy nó.

Con bạn muốn bạn chơi trò chơi này với chúng, tuy nhiên, bạn rất bận rộn khi trả lời các câu hỏi trên codegolf.SE. Vì vậy, bạn quyết định viết một chương trình để chơi trò chơi với họ. Tuy nhiên, bạn muốn sử dụng ít thời gian nhất có thể để gõ, vì vậy bạn cố gắng làm cho chương trình càng ít ký tự càng tốt.

Chúng ta có thể định nghĩa căn phòng trong đó trò chơi được chơi dưới dạng một hình vuông hình xuyến hai chiều. Tọa độ 0,0là góc dưới cùng bên trái và tọa độ 99,99là góc trên cùng bên phải. Kho báu được đặt ở một số vị trí n,mtrong đó nmcả hai số nguyên dương nằm trong khoảng từ 0 đến 99.

Chương trình của bạn sẽ có được thông tin từ người chơi sử dụng chức năng người dùng nhập vào sẵn có của nó (ví dụ prompt(), raw_input()vv) Nếu ngôn ngữ của bạn chọn không có chức năng đầu vào người sử dụng, lấy đầu vào từ STDIN để thay thế. Trò chơi sẽ hoạt động như sau:

  1. Chương trình "giấu" kho báu tại một vị trí n,m.
  2. Chương trình nhắc người tìm kiếm nhập một vị trí tìm kiếm ban đầu. Đầu vào sẽ đến dưới hình thức x ynơi xylà nguyên dương.
  3. Chương trình xuất ra "chính xác" nếu vị trí tìm kiếm ban đầu x,ybằng với vị trí của kho báu n,mvà chấm dứt. Nếu không thì:
  4. Chương trình sẽ nhắc người tìm di chuyển. Các đầu vào đến trong các hình thức a bnơi absố nguyêncó thể là tiêu cực . Điều này đại diện cho vectơ chỉ hướng mà người tìm kiếm đang di chuyển ( alà hướng x và blà hướng y).
  5. Nếu vị trí kết quả của người tìm kiếm nằm ở kho báu, chương trình sẽ xuất ra "chính xác" và chấm dứt. Nếu không thì:
  6. Chương trình xuất ra "mát" hơn nếu người tìm kiếm đang di chuyển ra khỏi kho báu hoặc "nóng hơn" nếu họ đang tiến về phía kho báu.
  7. Chuyển đến bước 4.

Các từ "di chuyển xa" và "di chuyển về phía" có thể không rõ ràng. Đối với thử thách này, nếu vị trí kết quả của người tìm kiếm sau khi di chuyển gần với kho báu hơn vị trí của họ trước khi họ di chuyển, thì họ đang tiến về phía kho báu. Nếu không, họ đang di chuyển đi. (Có, điều này không có nghĩa là nếu vị trí kết quả và vị trí trước đó ở cùng một khoảng cách, chương trình sẽ xuất ra "bộ làm mát").

Đây là mã golf, vì vậy mã ngắn nhất sẽ thắng. Đặt câu hỏi nếu đặc điểm kỹ thuật không rõ ràng.


Các lời nhắc đầu vào có cần chứa bất kỳ văn bản / câu hỏi nào không? Nếu vậy, xin vui lòng chỉ định nó.
Martin Ender

6
Tôi đã thấy trò chơi này chơi nhiều lần trên TV và đã thực hiện nó một vài lần, nhưng tôi chưa bao giờ nghe thấy thuật ngữ " Huckle Buckle Beanstalk ".
Sở thích của Calvin

@Martin Không, không cần phải có bất kỳ văn bản nào.
absinthe

1
@Ipi Trường có hình xuyến, tức là chúng sẽ quấn quanh phía bên kia của trường.
absinthe

1
Các động tác bao quanh, nhưng tính toán khoảng cách thì sao? Khoảng cách giữa (0,0) và (99,99) bằng 1 hay 99 · 2?
Tobia

Câu trả lời:


2

Javascript, 275 279

Không phải là một người chiến thắng bằng mọi cách, nhưng điều này sẽ khiến mọi thứ bắt đầu. Sử dụng một mẹo với eval()và định nghĩa 100là "hằng số" để loại bỏ một vài byte. Phiên bản Ungolfed dưới đây.

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

Chỉnh sửa: Tôi trở thành nạn nhân của các hoạt động chuỗi + số của Javascript, do đó tại sao hoạt động D()không đúng. Tôi cũng đã sửa một lỗi trong đó "nóng hơn" được hiển thị trước khi "chính xác". Điều này thêm 4 byte.


1
Tại sao nên sử dụng dấu chấm phẩy?
tự hào

Nếu nmcả hai được đặt thành không (cho mục đích thử nghiệm) và 0 1được nhập làm vị trí ban đầu, cả hai 0 -10 1trở lại lạnh hơn.
es1024

Trong vòng lặp for tại sao bạn có dòng mới? Đặt tất cả mã trên một dòng và bạn có thể lưu 22 ký tự (có thể nhiều hơn).
Beta Decay

1
Đây là phiên bản vô văn hóa. Phiên bản gốc là tất cả trên một dòng (dài 275 ký tự).
Sean Latham

trò đùa javascriptcolder == cooler
ajax333221

2

Python 3 - 238 byte


Mã số:

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

Ung dung:

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

Chạy mẫu:

$ 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

Tôi sẽ không nói rằng chiến lược của tôi trong việc tìm kiếm kho báu là đặc biệt nhanh ...


2

Groovy - 278 266 262

Chơi gôn

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}

Ung dung:

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
}

Thử nghiệm:

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

Bạn có thể vui lòng ghi lại một số hoạt động mẫu của giải pháp này không? Tôi tin rằng Math.sqrt ((xn 2) + (ym 2)) trả về NaN khi x <n, y <m.
Michael Easter

Vâng, chắc chắn rồi. Ngay khi tôi về nhà :)
Đứa trẻ nhỏ

Tuyệt vời ... Lưu ý: theo tôi hiểu OP, đầu vào ban đầu là một vị trí tuyệt đối và các đầu vào tiếp theo là tương đối. Ngoài ra, lưới bao quanh (hình xuyến). Tôi không thấy nó hoạt động như thế nào, và thật ngạc nhiên khi nó nhận được một upvote.
Michael Easter

@MichaelEaster Vui lòng kiểm tra chỉnh sửa. Hãy cho tôi biết nếu tôi đã làm gì sai :)
Đứa trẻ nhỏ

Tôi đã đăng giải pháp của mình, vì tôi hiểu vấn đề. Tôi không thể nhận xét về bạn nhưng sẽ để cử tri quyết định :)
Michael Easter

2

Groovy - 343 ký tự

Xuất phát từ câu trả lời của LittleChild .

Chơi gôn

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"

Ung dung:

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"

Chạy mẫu, nơi chương trình phát ra mục tiêu để minh họa. Theo hiểu biết của tôi về OP, đầu vào ban đầu là tuyệt đối và các đầu vào tiếp theo là tương đối. Ngoài ra, lưới kết thúc tốt đẹp xung quanh.

chạy A:

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

chạy 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

Vui mừng khi mã của tôi được sử dụng cho bạn! giơ ngón tay cái lên :)
Đứa trẻ nhỏ

2

APL, 86 ký tự

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

Tính toán khoảng cách không quấn quanh, nhưng di chuyển thì có.

Ung dung:

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

Thí dụ:

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

2

Con trăn 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'

Tôi có chức năng nhập liệu và ý tưởng áp dụng modulo trong tính toán khoảng cách thay vì cập nhật vị trí từ câu trả lời của matjoyce.

Chúng ta chỉ cần khoảng cách để so sánh: Chúng ta có ở vị trí chính xác không? Có phải chúng ta gần gũi hơn trước? Đối với cả hai điều này, chúng ta nhận được cùng một kết quả so sánh các hình vuông của khoảng cách như chúng ta sẽ so sánh khoảng cách. Tính toán căn bậc hai cần thiết để có được khoảng cách thực tế là không cần thiết.

Ung dung:

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'

Chạy mẫu:

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

Thủ thuật với các ô vuông, bỏ qua bước căn bậc hai, rất thông minh. +1
absinthe

1

Bản thảo 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")

Ung dung:

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

Tôi chắc chắn phải có tiền tiết kiệm khi tạo số ngẫu nhiên. Ngoài ra, điểm quan trọng là việc đọc bằng x & y chỉ được coi là phần bù từ 0, vì vậy tôi chỉ cần một lần quét. Điều đó có nghĩa là tôi phải loại bỏ việc in nóng hơn hoặc mát hơn trong lần lặp đầu tiên.

Thay đổi:

Đặt vị trí vào x & y trực tiếp và sau đó chuyển vị trí này trở lại (0,0) thay vì đặt nó vào m & n và sử dụng x & y để tìm kiếm nó.

Tôi nhận ra rằng tôi đã in "nóng hơn" và "chính xác" vì vậy tôi phải thêm ba ký tự ở đây.

Viết lại bản in để đặt tất cả các điều kiện trong đó, lưu một cuộc gọi thêm để đặt ().


1

JavaScript ES6, Firefox mới nhất, 177 173 164 ký tự

Rõ ràng, điều này không thể đánh bại APL. Ngôn ngữ đó thật điên rồ! Có lẽ chỉ được phát triển cho các câu hỏi về golf-code: D: P

Nhưng đây là giải pháp của tôi trong ES6 JavaScript. Chạy nó trong Firefox Nightly mới nhất (hoặc có thể là phiên bản phát hành) trong Bảng điều khiển Web hoặc 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")

Bây giờ tôi muốn bỏ qua phiên bản không có người nhận. Nhận xét nếu bạn muốn xem phiên bản chưa được chỉnh sửa :)

EDIT : Chơi golf rất nhiều! giảm 9 ký tự. Vẫn thấy nếu phạm vi chơi golf hơn nữa.


0

Con trăn 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

Điều đó importtrông thực sự dài và ngu ngốc, nhưng nó thực sự tiết kiệm cho tôi 8 ký tự.:D

Ví dụ trò chơi:

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

BASlair / ZX Spectrum BASIC - 305 byte

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

Vì Spectrum lưu trữ mỗi từ khóa dưới dạng một byte, nó giúp giảm kích thước. Sau khi được nhập, tìm ra kích thước với

print "bytes:";peek 23641+256*peek 23642-(peek 23635+256*peek 23636)+1
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.