Mini Golf Kod Golf


18

Bu bir mini golf deliği:

Dış sınır yarıçapı 10 ve merkezi (0,0) olan bir dairedir. İç sınır, yarıçap 3 ve orta (0,5) olan bir dairedir. Tee (0, -8) 'de. Topun yarıçapı 0 olan bir nokta olduğunu varsayın.

Topun dinamikleri aşağıdaki kurallara tabidir:

  • Top başlangıçta enerji 50 ve belirli bir açıyla vurulur.

    • Kartezyen koordinat sisteminde açı bozuluyor, bu nedenle 0 ° doğrudan sağa doğru, 90 ° doğrudan yukarı doğru vb.
  • Top, iç veya dış dairenin kenarına çarptığında, yansıma yasasını kullanarak daireden seker.

    • Bu noktada daire ile çarpışma açısı yansıma açısına eşittir. (Burada açılar, çarpışma noktasında dairenin teğet çizgisine göredir.)

    • Açıklama için bakınız bu ya bu (bu mücadelede, ikinci bağlantının gösterimde R_0 = 0.)

  • Top hareket ettikçe enerji kaybeder.

    • Kapladığı her toprak birimi için 1 birim enerji kaybeder.

    • Bir duvardan her seferinde 5 birim enerji kaybeder.

  • Top, enerji tükendiğinde veya deliğe düştüğünde durur.

    • Top, <= 5 birim enerji ile bir duvara çarparsa durur.

    • Deliğin 1 mesafesi yakınında olduğunda enerjisi <10 ise deliğe düşer, aksi halde hareket etmeye devam eder.

Meydan okuma

Bir deliğin xy koordinatları göz önüne alındığında, topun deliğe düşmesi için topa vurabileceğiniz bir açı döndürün (eğer böyle bir açı varsa).

Giriş

Herhangi bir uygun biçimde deliğin merkezinin x ve y koordinatlarını girdi olarak alın. Giriş STDIN (veya en yakın alternatif), komut satırı parametreleri veya işlev bağımsız değişkenlerinden alınabilir.

Çıktı

Top deliğe düşecek şekilde topa tee'den vurulabilecek derece cinsinden bir açı yazdırın veya döndürün. Böyle bir açı varsa, çıktı [0, 360) aralığında olmalıdır, aksi takdirde çıktı -1 olmalıdır.


X ve y değerlerinin nasıl okunması gerektiğini belirtmek isteyebilirsiniz (standart girdi, işlev bağımsız değişkeni vb.).
Loovjo

Böyle bir açı yoksa ne iade edilmelidir?
Alex

Bir çözüm varsa işlevin [0,360) içinde bir değer döndüreceğini ve aksi halde -1 döndüreceğini belirtelim.
Eric Brooks

Birkaç düzenleme yaptım. Amacınızla eşleşmiyorsa, lütfen düzenlemeyi geri alın.
Alex

Ayrıca, en az bir test durumu sağlayabilir misiniz?
Alex

Yanıtlar:


4

Cı, 415 430

EDIT: @Winny belirtildiği gibi, 255 üzerinde çıkış değerleri mümkün değildir, bu nedenle 360'a kadar değerleri yazdırmak için bu kod boyutunu artırmak zorunda kaldı.

2 (ve yalnızca 2) komut satırı girişini (xy) giriş olarak kabul eder. Derece cinsinden cevap yazdırılır veya derece yoksa -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");}

Ör.

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

İlk kez golfçü; muhtemelen biraz daha geliştirilebilir. Daha fazla hassasiyete ihtiyacımız varsa, xy alan ve 449 karakterde .01 derece hassasiyetle çalışan çiftlerle açıyı döndüren bir versiyonum var.

Okunabilir sürüm:

#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'ten daha büyük değerler döndürebileceğinizi sanmıyorum exit(code). Linux ve FreeBSD üzerinden test edildi echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?.
Winny
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.