熱くなったり冷たくなったり:宝物を見つける


8

「ハックルバックルビーンズトーク」と呼ばれることもある特定の子供向けゲームは、2人のプレーヤーでプレイされます。ここでは、ゲームのプレイ方法について簡単に説明します。

  1. 一方のプレイヤーは「ハイダー」に指定され、もう一方のプレイヤーは「シーカー」に指定されます。
  2. シーカーは部屋の外に出ますが、ハイダーはあらかじめ選択された小さなオブジェクト「宝物」を隠します。
  3. 次に、探索者が役立つヒントを提供している間、ハイダーはオブジェクトを探します。
    • シーカーが宝物に近づいている場合、ハイダーは「暖かい!」と呼びます。
    • シーカーが宝物から離れている場合、ハイダーは「クーラー!」と呼びます。
  4. 探求者が宝物を見つけたら、彼らはそれを見つけたと発表します。

あなたの子供はあなたと一緒にこのゲームをプレイしてほしいと思っていますが、代わりにcodegolf.SEの質問に答えるのに忙しいです。それで、あなたは彼らとゲームをするプログラムを書くことにしました。ただし、入力する時間をできるだけ短くしたいので、プログラムの文字数をできるだけ少なくするようにしてください。

ゲームがプレイされる部屋を2次元トロイダル正方形フィールドとして定義できます。座標0,0は左下隅、座標99,99は右上隅です。宝物は、いくつかの位置に配置されているn,m場合nm0から99までの間の両方の正の整数です。

あなたのプログラムは、その作り付けのユーザ入力機能を使用してプレイヤー(例えばからの入力を取得するprompt()raw_input()あなたの選択した言語がいる場合など)はありません、ユーザーの入力機能を持っている代わりに、STDINからの入力を取ります。ゲームは次のように機能します。

  1. プログラムは、ある位置に宝を「隠し」n,mます。
  2. プログラムは、探索者に初期探索位置を入力するように促します。入力はx ywhere xおよびwhere の形式でy正の整数になります。
  3. 最初の検索位置x,yが宝物の位置n,mと等しい場合、プログラムは「正しい」を出力して終了します。さもないと:
  4. プログラムはシーカーに移動を促します。入力フォームで来るとされている整数負でもよいです。これは、シーカーが移動する方向ベクトルを表します(x方向とy方向です)。 a babab
  5. 結果のシーカーの位置が宝物である場合、プログラムは「正しい」を出力して終了します。さもないと:
  6. 探求者が宝物から離れている場合、プログラムは「クーラー」を出力し、宝物に向かって移動している場合、「ホッター」を出力します。
  7. 手順4に進みます。

「遠ざかる」と「近づく」という言葉があいまいかもしれません。この課題では、移動後のシーカーの位置が、移動する前の位置よりも宝物に近い場合、宝物に向かって移動しています。そうでなければ、彼らは離れて移動しています。(はい、これは、結果の位置と前の位置が同じ距離にある場合、プログラムは「クーラー」を出力する必要があることを意味します)。

これはコードゴルフなので、最短のコードが勝ちます。仕様が明確でない場合は質問してください。


入力プロンプトにはテキスト/質問を含める必要がありますか?その場合は明記してください。
マーティンエンダー

6
このゲームをテレビで何度もプレイし、自分で何度かプレイしたことはありますが、「ハックルバックルビーンズトーク」という言葉を聞いたことはありません。
Calvin's Hobbies

マーティンいいえ、テキストは必要ありません。
アブサン

1
@ipiフィールドはトロイダルです。つまり、フィールドの反対側に回り込みます。
アブサン

1
動きは循環しますが、距離の計算はどうですか?(0,0)と(99,99)の間の距離は1または99・√2に等しいですか?
トビア2014

回答:


2

Javascript、275 279

決して勝者ではありませんが、これで物事が始まるはずです。トリックを使用eval()して定義する100数バイト剃り落とすに「定数」として。以下の非ゴルフバージョン。

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

編集:私はJavascriptの文字列+数値演算の犠牲になったので、なぜD()正しく動作しなかったのですか。「hotter」が「correct」の前に表示されるバグも修正しました。これにより、4バイトが追加されます。


1
セミコロンを使用する理由
誇り高いハスケラー2014

もしnm(目的をテストするため)がゼロに設定され、ともに0 1初期位置、両方として入力される0 -10 1戻り寒いです。
es1024 2014

forループで、なぜ新しい行があるのですか?すべてのコードを1行に入力すると、22文字(おそらくそれ以上)を節約できます。
ベータ崩壊2014

1
これは非ゴルフバージョンです。元のバージョンはすべて1行になっています(275文字)。
Sean Latham 2014

javascript jokecolder == cooler
ajax333221 2014

2

Python 3-238バイト


コード:

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

未ゴルフ:

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

サンプルの実行:

$ 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

宝物を見つける私の戦略は、特に特殊性であるとは言えません...


2

Groovyの- 278 266 262

ゴルフ:

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}

未ゴルフ:

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
}

試験:

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

このソリューションの実行例を実際に文書化していただけますか?Math.sqrt((xn 2)+(ym 2))は、x <n、y <mのときにNaNを返すと思います。
マイケルイースター

はい、そうです。私が家に帰るとすぐ:)
リトルチャイルド

クール...注:OPを理解しているように、初期入力は絶対位置であり、後続の入力は相対位置です。また、グリッドは回り込みます(トロイダル)。これがどのように機能するかは現状ではわかりませんが、賛成票を受け取ったことには驚いています。
マイケルイースター

@MichaelEaster編集内容を確認してください。私が何か間違ったことをしたかどうか知らせてください:)
リトルチャイルド

問題を理解したので、解決策を投稿しました。私はあなたについてコメントすることはできませんが、有権者に決定を任せます:)
マイケルイースター

2

Groovy-343文字

LittleChildの回答からいくぶん派生した。

ゴルフ:

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"

未ゴルフ:

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"

サンプル実行。プログラムは、説明のためにターゲットを出力します。OPについての私の理解から、初期入力は絶対的であり、後続の入力は相対的です。また、グリッドが折り返されます。

実行A:

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

実行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

私のコードが役立つことをうれしく思います!いいね :)
リトルチャイルド

2

APL、86文字

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

距離計算はラップアラウンドしませんが、動きはラップします。

未ゴルフ:

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

例:

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

入力関数と、matsjoyceの回答からの位置の更新ではなく、距離の計算にモジュロを適用するという考えが得られました。

比較に必要なのは距離だけです。正確な場所にいますか?以前よりも近いですか?これらの両方について、距離の2乗を比較すると、距離を比較する場合と同じ結果が得られます。実際の距離を取得するために必要な平方根の計算は不要です。

未ゴルフ:

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'

サンプルの実行:

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

四角のトリック、平方根のステップを無視して、非常に巧妙である+1。
アブサン

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

未ゴルフ:

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

乱数生成の節約になるに違いない。それとは別に重要な点は、xとyの読み取りは0からのオフセットとして扱われるだけなので、scanfは1つだけで十分です。ただし、最初の繰り返しでは、印刷をより高くまたはより低く抑える必要があります。

変更:

場所をxとyに直接入れ、これをm&nに入れるのではなく(0,0)に戻し、x&yを使用して検索します。

「ホッター」と「正解」を印刷していることに気付いたので、ここに3文字追加する必要がありました。

すべての条件を入れるように印刷を書き直し、puts()への追加の呼び出しを節約しました。


1

JavaScript ES6、最新のFirefox、177 173 164文字

明らかに、これはAPLに勝るものはありません。その言語はクレイジーです!コードゴルフの質問のためだけに開発されたのかもしれない:D:P

しかし、ここではES6 JavaScriptでの私のソリューションを紹介します。Webコンソールまたはスクラッチパッドで、最新のFirefox Nightly(またはリリースバージョンの可能性もあります)で実行します。

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

とりあえず、非ゴルフ版はスキップしたい。ゴルフしていないバージョンを見たい場合はコメントしてください:)

編集:たくさんゴルフをしました!9文字削減しました。ゴルフのさらなる範囲かどうかまだ見ています。


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

それimportは本当に長くて愚かに見えますが、それは実際に私に8文字を節約します。:D

ゲームの例:

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バイト

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

スペクトルは各キーワードを1バイトとして格納するため、サイズを抑えるのに役立ちます。入力後、サイズを確認してください

print "bytes:";peek 23641+256*peek 23642-(peek 23635+256*peek 23636)+1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.