Mini Golf Code Golf


18

Questa è una mini buca da golf:

Il confine esterno è un cerchio con raggio 10 e centro (0,0). Il confine interno è un cerchio con raggio 3 e centro (0,5). Il tee è a (0, -8). Supponiamo che la palla sia solo un punto con raggio 0.

Le dinamiche della palla sono regolate dalle seguenti regole:

  • Inizialmente la palla viene colpita con energia 50 e con un angolo dato.

    • L'angolo è in declino nel sistema di coordinate cartesiane, quindi 0 ° significa direttamente a destra, 90 ° è direttamente in alto e così via.
  • Quando la palla colpisce il bordo del cerchio interno o esterno, rimbalza sul cerchio usando la legge della riflessione.

    • L'angolo di collisione con il cerchio in quel punto è uguale all'angolo di riflessione. (Qui gli angoli sono relativi alla linea tangente del cerchio nel punto di collisione.)

    • Per chiarimenti, vedi questo o questo (nella notazione del secondo link, R_0 = 0 in questa sfida.)

  • La palla perde energia mentre si muove.

    • Per ogni unità di terreno coperta, perde 1 unità di energia.

    • Ogni volta che rimbalza da un muro perde 5 unità di energia.

  • La palla si ferma quando si esaurisce l'energia o quando cade nella buca.

    • Se la palla colpisce un muro con <= 5 unità di energia, si ferma.

    • Cade nel buco se ha energia <10 quando è entro la distanza 1 del buco, altrimenti continua a muoversi.

Sfida

Date le coordinate xy di una buca, restituisci un angolo in cui puoi colpire la palla per farla cadere nella buca (se esiste un tale angolo).

Ingresso

Prendi come input le coordinate x e y del centro del foro in qualsiasi forma conveniente. L'input può essere preso da STDIN (o alternativa più vicina), parametri della riga di comando o argomenti di funzione.

Produzione

Stampa o restituisci un angolo in gradi in cui la palla può essere colpita dal tee in modo tale che la palla cada nella buca. Se esiste un tale angolo, l'uscita dovrebbe essere compresa nell'intervallo [0, 360), altrimenti l'uscita dovrebbe essere -1.


Potresti voler specificare come leggere i valori xey (input standard, argomento di funzione ecc.).
Loovjo,

Cosa dovrebbe essere restituito se non esiste tale angolo?
Alex A.

Specifichiamo che la funzione restituirà un valore in [0,360) se esiste una soluzione, e restituirà -1 altrimenti.
Eric Brooks,

Ho apportato un paio di modifiche. Se non corrisponde alle tue intenzioni, ripristina la modifica.
Alex A.

Inoltre, potresti fornire almeno un caso di test?
Alex A.

Risposte:


4

C, 415 430

EDIT: Come accennato da @Winny, i valori di uscita superiori a 255 non sono possibili, quindi ho dovuto aumentare questa dimensione del codice per stampare valori fino a 360.

Presuppone 2 (e solo 2) input da riga di comando (xy) come ints. La risposta in gradi viene stampata o -1 se non esiste alcun grado.

#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

Giocatore di golf per la prima volta; probabilmente potrebbe essere migliorato un po '. Se dobbiamo avere più precisione, ho una versione che accetta xy e restituisce l'angolo con doppio che lavora con precisione di 0,01 gradi a 449 caratteri.

Versione leggibile:

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

Non credo che puoi restituire valori maggiori di 255 via exit(code). Testato su Linux e FreeBSD tramite echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.