미니 골프 코드 골프


18

이것은 미니 골프 홀입니다.

바깥 쪽 경계는 반지름이 10이고 중심이 (0,0) 인 원입니다. 내부 경계는 반경이 3이고 중심이 (0,5) 인 원입니다. 티는 (0, -8)입니다. 공이 반지름이 0 인 지점이라고 가정합니다.

공의 역학은 다음 규칙에 따라 결정됩니다.

  • 공은 처음에는 에너지 50과 주어진 각도로 맞습니다.

    • 직교 좌표계에서 각도가 빗나가므로 0 °는 오른쪽으로 직접, 90 °는 직접 위로 등을 의미합니다.
  • 공이 내부 또는 외부 원의 가장자리에 닿으면 반사 법칙을 사용하여 원에서 튀어 오릅니다.

    • 해당 점에서 원과의 충돌 각도는 반사 각도와 같습니다. (여기서 각도는 충돌 지점에서 원의 접선을 기준으로합니다.)

    • 설명을 위해 이것 또는 이것을 참조하십시오 (두 번째 링크의 표기법 에서이 과제의 R_0 = 0).

  • 공은 움직일 때 에너지를 잃습니다.

    • 접지하는 모든 단위에 대해 1 단위의 에너지를 잃습니다.

    • 벽에서 튕길 때마다 5 단위의 에너지를 잃습니다.

  • 공은 에너지가 떨어지거나 구멍에 떨어지면 멈 춥니 다.

    • 공이 <= 5 단위의 에너지로 벽에 부딪 치면 공이 멈 춥니 다.

    • 구멍의 거리 1 내에있을 때 에너지가 <10이면 구멍에 빠집니다. 그렇지 않으면 계속 움직입니다.

도전

구멍의 xy 좌표가 주어지면 공이 구멍에 빠지도록 공을 칠 수있는 각도를 반환하십시오 (각도가 존재하는 경우).

입력

구멍 중심의 x 및 y 좌표를 편리한 형태로 입력하십시오. STDIN (또는 가장 가까운 대안), 명령 행 매개 변수 또는 함수 인수에서 입력을 가져올 수 있습니다.

산출

공이 구멍에 들어가도록 티에서 공을 칠 수있는 각도로 인쇄하거나 반환하십시오. 이러한 각도가 존재하는 경우 출력은 [0, 360) 범위에 있어야하며, 그렇지 않으면 출력은 -1이어야합니다.


x 및 y 값을 읽는 방법 (표준 입력, 함수 인수 등)을 지정할 수 있습니다.
Loovjo

그러한 각도가 없으면 무엇을 돌려 주어야합니까?
Alex A.

해가있는 경우 함수가 [0,360)으로 값을 반환하고 그렇지 않으면 -1을 반환하도록 지정하겠습니다.
에릭 브룩스

몇 가지 수정을했습니다. 의도와 일치하지 않으면 편집을 롤백하십시오.
Alex A.

또한 하나 이상의 테스트 사례를 제공 할 수 있습니까?
Alex A.

답변:


4

C, 415 430

편집 : @Winny 언급 한 것처럼 255 이상의 종료 값을 사용할 수 없으므로 값을 최대 360까지 인쇄하려면이 코드 크기를 늘려야했습니다.

2 (및 2) 명령 줄 입력 (xy)을 정수로 가정합니다. 도 단위의 답변이 인쇄되거나 도가없는 경우 -1이 인쇄됩니다.

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

전의.

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

처음으로 골퍼; 아마 상당히 개선 될 수 있습니다. 더 정밀 해야하는 경우 xy를 사용하고 449 자에서 .01도 정밀도로 작업하는 복식으로 각도를 반환하는 버전이 있습니다.

읽을 수있는 버전 :

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

via를 통해 255보다 큰 값을 반환 할 수 있다고 생각하지 않습니다 exit(code). 를 통해 Linux 및 FreeBSD에서 테스트되었습니다 echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.