Mini Golf Code Golf


18

Este es un hoyo de mini golf:

El límite exterior es un círculo con radio 10 y centro (0,0). El límite interior es un círculo con radio 3 y centro (0,5). El tee está en (0, -8). Suponga que la pelota es solo un punto con radio 0.

La dinámica de la pelota se rige por las siguientes reglas:

  • La pelota es golpeada inicialmente con energía 50 y con un ángulo dado.

    • El ángulo está en disminución en el sistema de coordenadas cartesianas, por lo que 0 ° significa directamente a la derecha, 90 ° está directamente hacia arriba, y así sucesivamente.
  • Cuando la pelota golpea el borde del círculo interno o externo, rebota del círculo usando la ley de la reflexión.

    • El ángulo de colisión con el círculo en ese punto es igual al ángulo de reflexión. (Aquí los ángulos son relativos a la línea tangente del círculo en el punto de colisión).

    • Para aclarar, vea esto o esto (en la notación del segundo enlace, R_0 = 0 en este desafío).

  • La pelota pierde energía a medida que se mueve.

    • Por cada unidad de tierra que cubre, pierde 1 unidad de energía.

    • Cada vez que rebota en una pared pierde 5 unidades de energía.

  • La pelota se detiene cuando se queda sin energía o cuando cae en el hoyo.

    • Si la pelota golpea una pared con <= 5 unidades de energía, se detiene.

    • Cae en el hoyo si tiene energía <10 cuando está dentro de la distancia 1 del hoyo; de lo contrario, sigue moviéndose.

Desafío

Dadas las coordenadas xy de un hoyo, devuelve un ángulo en el que puedas golpear la pelota para que la pelota caiga en el hoyo (si existe ese ángulo).

Entrada

Tome como entrada las coordenadas x e y del centro del agujero en cualquier forma conveniente. La entrada puede tomarse de STDIN (o la alternativa más cercana), parámetros de línea de comando o argumentos de función.

Salida

Imprima o regrese un ángulo en grados en el que la pelota pueda ser golpeada desde el tee de manera que la pelota caiga en el hoyo. Si existe tal ángulo, la salida debe estar en el rango [0, 360), de lo contrario, la salida debe ser -1.


Es posible que desee especificar cómo deben leerse los valores xey (entrada estándar, argumento de función, etc.).
Loovjo

¿Qué se debe devolver si no existe tal ángulo?
Alex A.

Especifiquemos que la función devolverá un valor en [0,360) si hay una solución, y devolverá -1 en caso contrario.
Eric Brooks

Hice un par de ediciones. Si no coincide con su intención, revierta la edición.
Alex A.

Además, ¿podría proporcionar al menos un caso de prueba?
Alex A.

Respuestas:


4

C, 415 430

EDITAR: Como mencionó @Winny, los valores de salida superiores a 255 no son posibles, por lo que tuve que aumentar el tamaño de este código para imprimir valores de hasta 360.

Asume 2 (y solo 2) entradas de línea de comando (xy) como ints. La respuesta en grados se imprime o -1 si no existe ningún 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

Golfista por primera vez; probablemente podría mejorarse bastante. Si necesitamos tener más precisión, tengo una versión que toma xy y devuelve el ángulo con dobles trabajando con precisión de .01 grados en 449 caracteres.

Versión legible:

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

No creo que pueda devolver valores superiores a 255 a través de exit(code) . Probado en Linux y FreeBSD a través de echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.