มินิกอล์ฟรหัสกอล์ฟ


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

สิ่งที่ควรคืนหากไม่มีมุมดังกล่าวอยู่
Alex A.

ลองระบุว่าฟังก์ชั่นจะคืนค่าเป็น [0,360) ถ้ามีวิธีแก้ปัญหาและส่งคืน -1 อย่างอื่น
Eric Brooks

ฉันทำการแก้ไขสองสามครั้ง หากไม่ตรงกับความตั้งใจของคุณโปรดย้อนกลับการแก้ไข
Alex A.

คุณสามารถให้กรณีทดสอบอย่างน้อยหนึ่งกรณีได้หรือไม่
Alex A.

คำตอบ:


4

C, 415 430

แก้ไข: เช่นเดียวกับ @Winny ที่กล่าวถึงไม่สามารถออกค่าที่สูงกว่า 255 ได้ดังนั้นฉันต้องเพิ่มขนาดรหัสนี้เพื่อพิมพ์ค่าสูงสุด 360

ถือว่าอินพุตบรรทัดคำสั่ง 2 (และ 2 เท่านั้น) (xy) เป็น ints พิมพ์คำตอบเป็นองศาหรือ -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 และส่งคืนมุมด้วยการทำงานเป็นสองเท่าด้วยความแม่นยำ. 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 $?ผ่าน
Winny
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.