ミニゴルフコードゴルフ


18

これはミニゴルフホールです:

外側の境界は、半径10および中心(0,0)の円です。内部境界は、半径3および中心(0,5)の円です。ティーは(0、-8)にあります。ボールは半径0の単なる点であると仮定します。

ボールのダイナミクスは、次の規則によって管理されます。

  • ボールは最初にエネルギー50で与えられた角度で打たれます。

    • 角度はデカルト座標系で減少しているため、0°は右に直接、90°は上に、というようになります。
  • ボールが内側または外側の円の端に当たると、反射の法則を使用して円から跳ね返ります。

    • その点での円との衝突の角度は、反射の角度に等しくなります。(ここでの角度は、衝突点での円の接線に対して相対的です。)

    • 明確にするために、これまたはこれを参照してください(2番目のリンクの表記では、このチャレンジでR_0 = 0です)。

  • ボールは移動するとエネルギーを失います。

    • それが覆う地面の単位ごとに、1単位のエネルギーを失います。

    • 壁から跳ね返るたびに、5単位のエネルギーを失います。

  • ボールは、エネルギーがなくなるか、穴に落ちたときに停止します。

    • ボールが5単位以下のエネルギーで壁に衝突すると、ボールは停止します。

    • エネルギーが穴の距離1以内にある場合、エネルギーが10未満の場合、穴に落ちます。それ以外の場合は、動き続けます。

チャレンジ

穴のxy座標を指定して、ボールが穴に落ちるためにボールを打つことができる角度を返します(そのような角度が存在する場合)。

入力

入力として、任意の便利な形式で穴の中心のx座標とy座標を取ります。入力は、STDIN(または最も近い代替)、コマンドラインパラメーター、または関数引数から取得できます。

出力

ボールが穴に落ちるように、ボールがティーから打つことができる角度を印刷または返す。そのような角度が存在する場合、出力は[0、360)の範囲にある必要があります。そうでない場合、出力は-1になります。


x値とy値の読み取り方法(標準入力、関数引数など)を指定できます。
-Loovjo

そのような角度が存在しない場合、何を返す必要がありますか?
アレックスA.

関数が解がある場合は[0,360)の値を返し、そうでない場合は-1を返すように指定しましょう。
エリックブルックス

いくつかの編集を行いました。意図と一致しない場合は、編集をロールバックしてください。
アレックスA.

また、少なくとも1つのテストケースを提供できますか?
アレックスA.

回答:


4

C、415 430

編集:@Winnyが言及したように、255を超える終了値は不可能なので、値を最大360まで印刷するにはこのコードサイズを増やす必要がありました。

2つ(および2つだけ)のコマンドライン入力(xy)をintと想定します。度単位の回答が印刷されます。度単位がない場合は-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度の精度でdoubleを使用して角度を返すバージョンがあります。

読み取り可能なバージョン:

#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 $?
ウィニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.