Heißer oder kälter: Finde den Schatz

8

Ein bestimmtes Kinderspiel, oft "Huckle Buckle Beanstalk" genannt, wird mit zwei Spielern gespielt. Hier ist eine kurze Beschreibung, wie das Spiel gespielt wird:

  1. Ein Spieler wird als "Hider" und der andere als "Sucher" bezeichnet.
  2. Der Suchende verlässt den Raum, während der Versteckte ein kleines, vorgewähltes Objekt versteckt, den "Schatz".
  3. Der Hider versucht dann, nach dem Objekt zu suchen, während der Suchende ihm hilfreiche Hinweise gibt:
    • Wenn sich der Suchende dem Schatz nähert, ruft der Hider "wärmer!"
    • Wenn sich der Suchende vom Schatz entfernt, ruft der Hider "cooler"!
  4. Sobald der Suchende den Schatz gefunden hat, gibt er bekannt, dass er ihn gefunden hat.

Ihre Kinder möchten, dass Sie dieses Spiel mit ihnen spielen. Sie sind jedoch sehr damit beschäftigt, Fragen zu codegolf.SE zu beantworten. Sie beschließen also, ein Programm zu schreiben, um das Spiel mit ihnen zu spielen. Sie möchten jedoch so wenig Zeit wie möglich für die Eingabe verwenden, um das Programm so wenig Zeichen wie möglich zu machen.

Wir können den Raum, in dem das Spiel gespielt wird, als zweidimensionales toroidales quadratisches Feld definieren. Die Koordinate 0,0ist die untere linke Ecke und die Koordinate 99,99ist die obere rechte Ecke. Der Schatz ist an einer bestimmten Position platziert , n,mwo nund mbeide positive ganze Zahlen zwischen 0 und 99 inklusive.

Ihr Programm wird ein Beitrag von dem Spieler erhält ihre eingebaute Benutzereingabe - Funktion (zB prompt(), raw_input()usw.) Wenn Ihre gewählte Sprache nicht ist eine Benutzereingabe - Funktion hat, nehmen Sie eine Eingabe von STDIN statt. Das Spiel funktioniert wie folgt:

  1. Das Programm "versteckt" den Schatz an einer Position n,m.
  2. Das Programm fordert den Suchenden auf, eine anfängliche Suchposition einzugeben. Die Eingabe wird in Form kommen , x ywo xund ypositive ganze Zahlen sind .
  3. Das Programm gibt "korrekt" aus, wenn die anfängliche Suchposition x,ygleich der Position des Schatzes ist n,mund endet. Andernfalls:
  4. Das Programm fordert den Suchenden auf, sich zu bewegen. Die Eingabe erfolgt in Form a bwo aund bsind ganze Zahlen , die negativ sein können . Dies stellt den Richtungsvektor dar , in den sich der Sucher bewegt ( aist die x-Richtung und bist die y-Richtung).
  5. Befindet sich die resultierende Position des Suchers am Schatz, gibt das Programm "korrekt" aus und wird beendet. Andernfalls:
  6. Das Programm gibt "kühler" aus, wenn sich der Suchende vom Schatz entfernt, oder "heißer", wenn er sich dem Schatz nähert.
  7. Fahren Sie mit Schritt 4 fort.

Die Wörter "wegbewegen" und "wegbewegen" können mehrdeutig sein. Wenn für diese Herausforderung die resultierende Position des Suchenden nach dem Bewegen näher am Schatz liegt als seine Position vor dem Bewegen, bewegen sie sich auf den Schatz zu. Ansonsten ziehen sie weg. (Ja, dies bedeutet, dass das Programm "kühler" ausgeben sollte, wenn die resultierende und die vorherige Position gleich weit entfernt sind.)

Dies ist Code Golf, also gewinnt der kürzeste Code. Stellen Sie Fragen, wenn die Spezifikation nicht klar ist.

Absinth
quelle
Müssen die Eingabeaufforderungen Text / Fragen enthalten? Wenn ja, geben Sie dies bitte an.
Martin Ender
6
Ich habe dieses Spiel viele Male im Fernsehen gesehen und es selbst ein paar Mal gemacht, aber ich habe den Begriff " Huckle Buckle Beanstalk " noch nie gehört .
Calvins Hobbys
@ Martin Nein, es muss keinen Text geben.
Absinth
1
@Ipi Das Feld ist toroidal, dh sie werden auf die andere Seite des Feldes gewickelt.
Absinth
1
Die Bewegungen drehen sich um, aber was ist mit der Entfernungsberechnung? Ist der Abstand zwischen (0,0) und (99,99) gleich 1 oder 99 · √2?
Tobia

Antworten:

2

Javascript, 275 279

Kein Gewinner, aber das sollte den Anfang machen. Verwendet einen Trick mit eval()und definiert 100als "Konstante", um einige Bytes zu sparen. Ungolfed Version unten.

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

Bearbeiten: Ich wurde Opfer der String + Number-Operationen von Javascript, weshalb D()es nicht richtig funktionierte. Ich habe auch einen Fehler behoben, bei dem "heißer" vor "richtig" angezeigt wurde. Dies fügt 4 Bytes hinzu.

Sean Latham
quelle
1
Warum Semikolons verwenden?
stolzer Haskeller
Wenn nund mbeide (zu Testzwecken) auf Null gesetzt sind und 0 1als Ausgangsposition eingegeben werden, kehren beide 0 -1und 0 1kälter zurück.
Es1024
Warum haben Sie in der for-Schleife neue Zeilen? Wenn Sie den gesamten Code in eine Zeile einfügen, können Sie 22 Zeichen (möglicherweise mehr) speichern.
Beta Decay
1
Dies ist die ungolfed Version. Die Originalversion befindet sich in einer Zeile (275 Zeichen lang).
Sean Latham
Javascript Witzcolder == cooler
Ajax333221
2

Python 3 - 238 Bytes


Code:

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

Probelauf:

$ 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

Ich werde nicht sagen, dass meine Strategie, den Schatz zu finden, die Besonderheit schnell ist ...

matsjoyce
quelle
2

Groovy - 278 266 262

Golf:

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
}

Versuch:

-1 -1
Cooler 12 12
Cooler 14 14
Cooler 13 13
Hotter 15 15
Cooler 90 55
Cooler 95 -100
Hotter 95 83
Correct
Kleines Kind
quelle
Können Sie bitte einige Beispielläufe dieser Lösung in Aktion dokumentieren? Ich glaube, Math.sqrt ((xn 2) + (ym 2)) gibt NaN zurück, wenn x <n, y <m.
Michael Easter
Ja sicher. Sobald ich nach Hause komme :)
Kleines Kind
Cool ... Hinweis: Soweit ich das OP verstehe, ist die anfängliche Eingabe eine absolute Position und die nachfolgenden Eingaben sind relativ. Außerdem wickelt sich das Gitter um (toroidal). Ich sehe nicht, wie das funktioniert, wie es ist, und bin überrascht, dass es eine positive Bewertung erhalten hat.
Michael Easter
@MichaelEaster Bitte überprüfen Sie die Bearbeitung. Lassen Sie mich wissen, wenn ich etwas falsch gemacht habe :)
Little Child
Ich habe meine Lösung veröffentlicht, da ich das Problem verstehe. Ich kann Ihre nicht kommentieren, aber ich werde die Wähler entscheiden lassen :)
Michael Easter
2

Groovy - 343 Zeichen

Etwas abgeleitet von LittleChilds Antwort.

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"

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"

Probelauf, bei dem das Programm das Ziel zur Veranschaulichung ausgibt. Nach meinem Verständnis von OP ist die anfängliche Eingabe absolut und die nachfolgenden Eingaben sind relativ. Auch das Gitter wickelt sich um.

Lauf A:

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

Lauf 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
Michael Ostern
quelle
Ich bin froh, dass mein Code für Sie von Nutzen ist! Daumen hoch :)
Kleines Kind
2

APL, 86 Zeichen

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

Die Entfernungsberechnung dreht sich nicht um, sondern um Bewegungen.

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

Beispiel:

⎕:
      22 33
⎕:
      2 6
hotter
⎕:
      0 1
cooler
⎕:
      0 ¯3
correct
Tobia
quelle
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'

Ich habe die Eingabefunktion und die Idee, das Modulo in der Entfernungsberechnung anzuwenden, anstatt die Standortaktualisierung aus der Antwort von matsjoyce.

Wir brauchen nur Entfernungen für Vergleiche: Sind wir genau am Ort? Sind wir näher als zuvor? Für beide erhalten wir das gleiche Ergebnis beim Vergleich der Quadrate der Entfernungen wie beim Vergleich der Entfernungen. Die Quadratwurzelberechnung, die erforderlich ist, um die tatsächliche Entfernung zu erhalten, ist nicht erforderlich.

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'

Probelauf:

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
Gary Culp
quelle
Der Trick mit den Quadraten, den Quadratwurzelschritt zu ignorieren, ist sehr klug. +1
Absinth
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")
es1024
quelle
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);}

Ich bin sicher, es muss Einsparungen bei der Zufallszahlengenerierung geben. Abgesehen davon ist der entscheidende Punkt, dass das Lesen in x & y nur als Versatz von 0 behandelt wird, sodass ich nur einen Scanf benötige. Es bedeutet jedoch, dass ich das Drucken bei der ersten Iteration heißer oder kühler unterdrücken muss.

Änderungen:

Setzen Sie die Position direkt in x & y und verschieben Sie diese dann zurück zu (0,0), anstatt sie in m & n zu setzen, und verwenden Sie x & y, um danach zu suchen.

Mir wurde klar, dass ich "heißer" und "korrekt" druckte, also musste ich hier drei zusätzliche Zeichen hinzufügen.

Der Druck wurde neu geschrieben, um alle Bedingungen zu erfüllen, und ein zusätzlicher Aufruf von put () erspart.

Alchymist
quelle
1

JavaScript ES6, Neuester Firefox, 177 173 164 Zeichen

Offensichtlich kann dies die APL nicht schlagen. Diese Sprache ist verrückt! Vielleicht nur für Code-Golf-Fragen entwickelt: D: P.

Aber hier geht meine Lösung in ES6 JavaScript. Führen Sie es in der neuesten Firefox Nightly-Version (oder möglicherweise auch in der Release-Version) in der Webkonsole oder im Scratchpad aus.

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

Ich möchte die ungolfed Version vorerst überspringen. Kommentar, wenn du die ungolfed Version sehen willst :)

EDIT : Viel Golf gespielt! 9 Zeichen reduziert. Immer noch sehen, ob weitere Möglichkeiten des Golfspiels.

Optimierer
quelle
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

Das importsieht wirklich lang und dumm aus, aber es spart mir tatsächlich 8 Zeichen.:D

Beispielspiel:

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
Sammitch
quelle
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

Da das Spektrum jedes Schlüsselwort als ein Byte speichert, hilft es, die Größe niedrig zu halten. Nachdem es eingegeben wurde, ermitteln Sie die Größe mit

print "bytes:";peek 23641+256*peek 23642-(peek 23635+256*peek 23636)+1
Brian
quelle