Minigolf Code Golf


18

Dies ist ein Minigolf-Loch:

Die äußere Begrenzung ist ein Kreis mit Radius 10 und Mittelpunkt (0,0). Die innere Begrenzung ist ein Kreis mit Radius 3 und Mittelpunkt (0,5). Das Tee ist bei (0, -8). Angenommen, der Ball ist nur ein Punkt mit dem Radius 0.

Die Dynamik des Balls richtet sich nach folgenden Regeln:

  • Der Ball wird anfänglich mit Energie 50 und mit einem gegebenen Winkel geschlagen.

    • Der Winkel ist im kartesischen Koordinatensystem ungleichmäßig. 0 ° bedeutet also direkt nach rechts, 90 ° ist direkt nach oben und so weiter.
  • Wenn der Ball auf die Kante des inneren oder äußeren Kreises trifft, springt er nach dem Reflexionsgesetz vom Kreis ab.

    • Der Kollisionswinkel mit dem Kreis an diesem Punkt ist gleich dem Reflexionswinkel. (Hier beziehen sich die Winkel auf die Tangente des Kreises am Kollisionspunkt.)

    • Zur Verdeutlichung siehe dies oder das (in der Notation des zweiten Links ist R_0 = 0 in dieser Herausforderung).

  • Der Ball verliert Energie, wenn er sich bewegt.

    • Für jede Bodeneinheit, die es abdeckt, verliert es 1 Energieeinheit.

    • Jedes Mal, wenn es von einer Wand abprallt, verliert es 5 Energieeinheiten.

  • Der Ball stoppt, wenn ihm die Energie ausgeht oder wenn er in das Loch fällt.

    • Trifft der Ball mit <= 5 Energieeinheiten auf eine Wand, stoppt er.

    • Es fällt in das Loch, wenn es eine Energie <10 hat, wenn es sich im Abstand von 1 zum Loch befindet, andernfalls bleibt es in Bewegung.

Herausforderung

Geben Sie anhand der xy-Koordinaten eines Lochs einen Winkel zurück, in dem Sie den Ball schlagen können, damit der Ball in das Loch fällt (sofern ein solcher Winkel vorhanden ist).

Eingang

Nehmen Sie als Eingabe die x- und y-Koordinaten der Lochmitte in einer beliebigen Form. Die Eingabe kann über STDIN (oder die nächstgelegene Alternative), Befehlszeilenparameter oder Funktionsargumente erfolgen.

Ausgabe

Drucken Sie einen Winkel in Grad aus oder geben Sie ihn zurück, in dem der Ball vom T-Stück getroffen werden kann, sodass der Ball in das Loch fällt. Wenn ein solcher Winkel existiert, sollte die Ausgabe im Bereich [0, 360) liegen, andernfalls sollte die Ausgabe -1 sein.


Möglicherweise möchten Sie festlegen, wie die x- und y-Werte gelesen werden sollen (Standardeingabe, Funktionsargument usw.).
Loovjo,

Was ist zurückzugeben, wenn kein solcher Winkel vorhanden ist?
Alex A.

Geben Sie an, dass die Funktion einen Wert in [0,360] zurückgibt, wenn es eine Lösung gibt, und geben Sie andernfalls -1 zurück.
Eric Brooks

Ich habe ein paar Änderungen vorgenommen. Wenn es Ihrer Absicht nicht entspricht, setzen Sie die Bearbeitung zurück.
Alex A.

Könnten Sie auch mindestens einen Testfall bereitstellen?
Alex A.

Antworten:


4

C 415 430

BEARBEITEN: Wie bei @Winny erwähnt, sind Exit-Werte über 255 nicht möglich. Daher musste ich diesen Code vergrößern, um Werte bis zu 360 zu drucken.

Nimmt 2 (und nur 2) Befehlszeileneingaben (xy) als Ints an. Die Antwort in Grad wird gedruckt oder -1, wenn kein Grad vorhanden ist.

#include <math.h>
#define E(z) {if((e-=5)<0)break;q=n/sqrt(n*n+pow(m-z,2));w=(m-z)/sqrt(n*n+pow(m-z,2));d=(t=d)*(1-2*q*q)-2*f*q*w;f=f*(1-2*w*w)-2*t*q*w;}
main(a,v)char**v;{float D=.01,e,d,f,n,m,p=.0174,q,t,w;a-=4;while(++a<360){n=0,m=-8,d=D*cos(a*p),f=D*sin(a*p),e=50;while(e>0){if((pow(n-atoi(v[1]),2)+pow(m-atoi(v[2]),2)<1)&(e<10)&&printf("%d",a))return;n+=d,m+=f,e-=D;if(n*n+m*m>100)E(0)if(n*n+pow(m-5,2)<9)E(5)}}puts("-1");}

Ex.

>./golfed 0 2; echo $?
90
>./golfed 0 10; echo $?
0
>./golfed -2 -7; echo $?
12

Golfspieler zum ersten Mal; könnte wohl einiges verbessern. Wenn wir mehr Präzision benötigen, habe ich eine Version, die xy berücksichtigt und den Winkel mit doppelter Genauigkeit von 0,01 Grad bei 449 Zeichen zurückgibt.

Lesbare Version:

#include <math.h>
int main(int argc, char** argv)
{
    // p is roughly pi/180 and q, t, and w are temp vars
    float Delta=.01, energy, delta_x, f(delta_y), n(cur_x), m(cur_y), p=.0174, q, t, w;
    argc -= 4; /*using argc as int for angle*/
    // iterate through each degree
    while (++argc < 360)
    {
        n=0, m=-8, d=D*cos(a*p), f=D*sin(a*p), e=50;
        // then move in discrete .01 steps
        while (e > 0)
        {
            // check to see if we're inside the hole
            if ((pow(n-atoi(v[1]),2) + pow(m-atoi(v[2]),2) < 1) 
                & (e<10) && printf("%d",a)) return;
            // move forward
            n += d, m += f, e -= D;
            // check if we've hit the outer wall
            if (n * n + m * m > 100)
            {
                // if too slow, finish this iteration
                // if not, find reflection vector
                if ((e -= 5) < 0) break;
                q = n / sqrt(n * n + pow(m,2));
                w = (m) / sqrt(n * n + pow(m,2));
                d = (t = d) * (1 - 2 * q * q) - 2 * f * q * w;
                f = f * (1 - 2 * w * w) - 2 * t * q * w;
            }
            // check inner wall collision
            if (n * n + pow(m - 5,2) < 9)
            {
                // if too slow, finish this iteration
                // if not, find reflection vector
                if ((e -= 5) < 0) break;
                q = n / sqrt(n * n + pow(m - 5,2));
                w = (m - 5) / sqrt(n * n + pow(m - 5,2));
                d = (t = d) * (1 - 2 * q * q) - 2 * f * q * w;
                f = f * (1 - 2 * w * w) - 2 * t * q * w;
            }
        }
    }
    // if an angle not found, return -1
    puts("-1");
}

Ich glaube nicht, dass Sie über Werte größer als 255 zurückgeben können exit(code). Getestet unter Linux und FreeBSD über echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.