Мини Гольф Код Гольф


18

Это отверстие для мини-гольфа:

Внешняя граница представляет собой круг с радиусом 10 и центром (0,0). Внутренняя граница представляет собой круг с радиусом 3 и центром (0,5). Тройник в (0, -8). Предположим, что шар - это просто точка с радиусом 0.

Динамика мяча регулируется следующими правилами:

  • Мяч изначально поражен энергией 50 и с заданным углом.

    • Угол отклоняется в декартовой системе координат, поэтому 0 ° означает прямо вправо, 90 ° - прямо вверх и т. Д.
  • Когда мяч ударяется о край внутреннего или внешнего круга, он отскакивает от круга, используя закон отражения.

    • Угол столкновения с окружностью в этой точке равен углу отражения. (Здесь углы относительно касательной линии круга в точке столкновения.)

    • Для пояснения см. Это или это (в обозначениях второй ссылки R_0 = 0 в этом вызове.)

  • Мяч теряет энергию при движении.

    • На каждую единицу земли, которую он покрывает, теряется 1 единица энергии.

    • Каждый раз, когда он отскакивает от стены, он теряет 5 единиц энергии.

  • Мяч останавливается, когда у него заканчивается энергия или когда он падает в лунку.

    • Если мяч ударяется о стену с энергией <= 5 единиц, он останавливается.

    • Он падает в отверстие, если у него есть энергия <10, когда он находится на расстоянии 1 от отверстия, в противном случае он продолжает двигаться.

Вызов

Учитывая координаты xy отверстия, верните угол, под которым вы можете ударить по мячу, чтобы шар упал в отверстие (если такой угол существует).

вход

В качестве входных данных возьмите x- и y-координаты центра отверстия в любой удобной форме. Входные данные могут быть взяты из STDIN (или ближайшей альтернативы), параметров командной строки или аргументов функции.

Выход

Напечатайте или верните угол в градусах, при котором шарик может попасть в тройник так, чтобы шарик упал в отверстие. Если такой угол существует, выходной сигнал должен находиться в диапазоне [0, 360), в противном случае выходной сигнал должен быть равен -1.


Возможно, вы захотите указать, как следует читать значения x и y (стандартный ввод, аргумент функции и т. Д.).
Loovjo

Что следует вернуть, если такого угла не существует?
Алекс А.

Укажем, что функция вернет значение в [0,360), если есть решение, и вернет -1 в противном случае.
Эрик Брукс,

Я сделал пару правок. Если это не соответствует вашим намерениям, откатите редактирование.
Алекс А.

Кроме того, не могли бы вы предоставить хотя бы один контрольный пример?
Алекс А.

Ответы:


4

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

Ex.

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

Первый раз игрок в гольф; возможно, можно было бы немного улучшить. Если нам нужно больше точности, у меня есть версия, которая принимает xy и возвращает угол с двойным числом, работая с точностью 0,01 градуса при 449 символах.

Читаемая версия:

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

Я не думаю, что вы можете вернуть значения больше 255 через exit(code). Протестировано на Linux и FreeBSD через echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Винни
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.