Mini Golf Code Golf


18

Đây là một lỗ golf mini:

Ranh giới bên ngoài là một vòng tròn có bán kính 10 và tâm (0,0). Ranh giới bên trong là một vòng tròn có bán kính 3 và tâm (0,5). Các tee ở (0, -8). Giả sử bóng chỉ là một điểm có bán kính 0.

Động lực của quả bóng được điều chỉnh bởi các quy tắc sau:

  • Quả bóng ban đầu được đánh với năng lượng 50, và với một góc nhất định.

    • Góc bị suy giảm trong hệ tọa độ Descartes, vì vậy 0 ° có nghĩa là trực tiếp ở bên phải, 90 ° trực tiếp lên, v.v.
  • Khi quả bóng chạm vào cạnh của vòng tròn bên trong hoặc bên ngoài, nó sẽ bật ra khỏi vòng tròn bằng cách sử dụng định luật phản xạ.

    • Góc va chạm với đường tròn tại điểm đó bằng góc phản xạ. (Ở đây các góc có liên quan đến đường tiếp tuyến của đường tròn tại điểm va chạm.)

    • Để làm rõ, hãy xem cái này hoặc cái này (trong ký hiệu của liên kết thứ hai, R_0 = 0 trong thử thách này.)

  • Quả bóng mất năng lượng khi nó di chuyển.

    • Đối với mỗi đơn vị mặt đất nó bao phủ, nó mất 1 đơn vị năng lượng.

    • Mỗi lần nó bật ra khỏi bức tường, nó sẽ mất 5 đơn vị năng lượng.

  • Quả bóng dừng lại khi hết năng lượng hoặc khi rơi vào lỗ.

    • Nếu quả bóng đập vào tường với <= 5 đơn vị năng lượng, nó sẽ dừng lại.

    • Nó rơi vào lỗ nếu nó có năng lượng <10 khi nó nằm trong khoảng cách 1 của lỗ, nếu không nó sẽ tiếp tục di chuyển.

Thử thách

Cho tọa độ xy của một lỗ, trả lại một góc mà bạn có thể đánh bóng để bóng rơi vào lỗ (nếu tồn tại một góc như vậy).

Đầu vào

Lấy đầu vào tọa độ x và y của tâm lỗ dưới mọi hình thức thuận tiện. Đầu vào có thể được lấy từ STDIN (hoặc thay thế gần nhất), tham số dòng lệnh hoặc đối số chức năng.

Đầu ra

In hoặc trả lại một góc theo độ mà bóng có thể được đánh từ tee sao cho bóng sẽ rơi vào lỗ. Nếu một góc như vậy tồn tại, đầu ra phải nằm trong phạm vi [0, 360), nếu không thì đầu ra phải là -1.


Bạn có thể muốn chỉ định cách đọc các giá trị x và y (đầu vào tiêu chuẩn, đối số hàm, v.v.).
Loovjo

Những gì nên được trả lại nếu không có góc như vậy tồn tại?
Alex A.

Hãy xác định rằng hàm sẽ trả về giá trị trong [0,360) nếu có giải pháp và trả về -1 nếu không.
Eric Brooks

Tôi đã thực hiện một vài chỉnh sửa. Nếu nó không phù hợp với ý định của bạn, vui lòng quay lại chỉnh sửa.
Alex A.

Ngoài ra, bạn có thể cung cấp ít nhất một trường hợp thử nghiệm?
Alex A.

Câu trả lời:


4

C, 415 430

EDIT: Giống như @Winny đã đề cập, không thể thoát các giá trị trên 255, vì vậy tôi phải tăng kích thước mã này để in các giá trị lên tới 360.

Giả sử 2 (và chỉ 2) đầu vào dòng lệnh (xy) là ints. Trả lời bằng độ được in hoặc -1 nếu không có độ.

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

Ví dụ.

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

Người chơi gôn lần đầu; có lẽ có thể được cải thiện một chút. Nếu chúng ta cần có độ chính xác cao hơn, tôi có một phiên bản lấy xy và trả về góc với nhân đôi với độ chính xác 0,01 độ ở 449 ký tự.

Phiên bản dễ đọc:

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

Tôi không nghĩ bạn có thể trả về các giá trị lớn hơn 255 thông qua exit(code). Đã thử nghiệm trên Linux và FreeBSD thông qua echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.