เล่นบิลเลียด


17

ในสนามกอล์ฟรหัสนี้คุณจะต้องมีการกำหนดทิศทางของการยิงที่สั้นที่สุดที่นิยมตรงnเบาะรองนั่งก่อนที่จะตกไปอยู่ในกระเป๋า

โต๊ะบิลเลียดเป็นโต๊ะพูล 6 พ็อตที่มีคุณสมบัติดังต่อไปนี้:

  • ขนาดเป็นตัวแปร ( a x b )
  • ไม่มีแรงเสียดทาน: ลูกบอลจะกลิ้งอย่างถาวรจนกว่ามันจะตกลงไปในกระเป๋า
  • ขนาดกระเป๋าและลูกบอลเกือบเป็นศูนย์ ซึ่งหมายความว่าลูกจะตกอยู่ในกระเป๋าเฉพาะในกรณีที่พวกเขามีตำแหน่งเดียวกัน
  • ลูกบอลถูกวางไว้ที่รูซ้ายล่างที่จุดเริ่มต้น (แต่ไม่ตกอยู่ในนั้น)

3cushion

สร้างโปรแกรมเต็มรูปแบบหรือฟังก์ชั่นที่ใช้มิติ ( , ) ของตารางและจำนวนของหมอนอิงที่จะตีnเป็น input และผลตอบแทนในมุมองศาของเส้นทางที่สั้นที่สุดกดปุ่มตรงnเบาะรองนั่งก่อนที่จะตกไปอยู่ในกระเป๋า

  • a > 0
  • b > 0
  • 0 <= n <10,000000
  • 0 < alpha <90 (เป็นองศา) ความแม่นยำ: อย่างน้อย 10 ^ -6

ตัวอย่าง :

ด้วยa = 2, b = 1, n = 1 มีสามเส้นทางที่เป็นไปได้: (1) (2) (3) ในรูปต่อไปนี้ จำนวน (1) สั้นที่สุดดังนั้นเอาต์พุตควรเป็น atan (2) = 63.43494882292201 องศา

1cushion

คำตอบสำหรับa = 2, b = 1, n = 4 คือ atan (4/3) = 53.13010235415598 องศา

4cushions

ตัวอย่างทดสอบ:

a = 2,    b = 1,    n = 1,       -> alpha = 63.43494882292201
a = 2,    b = 1,    n = 2,       -> alpha = 71.56505117707799
a = 2,    b = 1,    n = 3,       -> alpha = 75.96375653207353
a = 2,    b = 1,    n = 4,       -> alpha = 53.13010235415598
a = 2,    b = 1,    n = 5,       -> alpha = 59.03624346792648
a = 2,    b = 1,    n = 6,       -> alpha = 81.86989764584403
a = 4.76, b = 3.64, n = 27,      -> alpha = 48.503531644784466
a = 2,    b = 1,    n = 6,       -> alpha = 81.86989764584403
a = 8,    b = 3,    n = 33,      -> alpha = 73.24425107080101
a = 43,   b = 21,   n = 10005,   -> alpha = 63.97789961246943

นี่คือรหัส / บิลเลียดกอล์ฟ: รหัสที่สั้นที่สุดชนะ!


ลูกไม่ต้องตีตรง nหมอนอิงหรืออย่างน้อย nหมอน?
Peter Taylor

@PeterTaylor หมอนอิงทุกอย่าง
Damien

ไม่ใช่เส้นทางที่สั้นที่สุดเสมอไปมาระหว่างด้านบนซ้ายและล่างแล้วเข้าสู่หนึ่งในรูตรงกลางหรือไม่
Eumel

ไม่ดูตัวอย่าง 2 1 4 เส้นทางนี้คือ sqrt (25) = 5 long ในขณะที่โซลูชันของคุณคือ sqrt (26)
Damien

คำตอบ:


11

Python 2.7, 352 344 281 ไบต์

from math import*
def l(a,b,n):
 a*=1.;b*=1.
 r=set()
 for i in range(1,n+3):
  t=[]
  for k in range(1,i):
   for h in[0,.5]:
    x=(i-k-h)
    if 1-(x/k in r):r.add(x/k);t+=(x*a,k*b),
 d=(a*n+1)**2+(b*n+1)**2
 for x,y in t:
  if x*x+y*y<d:d=x*x+y*y;o=degrees(atan(y/x))
 return o
  • -16 ไบต์ขอบคุณ @Dschoni

คำอธิบาย: แทนการคำนวณจำนวนหมอนรองฉันจะเพิ่มตาราง n และนำรูใหม่ที่ถูกต้อง: billard เส้นขอบดำ / หลุมเป็นต้นฉบับขอบสีเขียว / หลุมที่ถูกต้องสำหรับ n = 1, ขอบสีแดง / หลุมที่ถูกต้องสำหรับ n = 2 และต่อไป จากนั้นฉันจะลบช่องที่ไม่ถูกต้อง (เช่นลูกศรสีน้ำเงินสำหรับ n = 1) ฉันจะมีรายการของหลุมที่ถูกต้องและพิกัดของพวกเขาจากนั้นฉันคำนวณระยะทางจากจุดเริ่มต้นแล้วมุมของระยะทางที่เล็กกว่า
หมายเหตุ:
a = 4.76, b = 3.64, n = 27 - ให้ 52.66286 พยายามหาสาเหตุที่แก้ไขและบันทึก 8 ไบต์ในกระบวนการ = D
a = 43, b = 21, n = 1,0005 - ใช้เวลา ~ 80 วินาที ( แต่ให้มุมฉาก)

รุ่นที่อ่านได้:

from math import *
def bill(a,b,n):
    a=float(a)
    b=float(b)
    ratios = set()
    for i in range(0,n+2): # Create the new boards
        outter = []
        j=i+1
        for k in range(1,j): # Calculate the new holes for each board
            #y=k
            for hole_offset in [0,0.5]:
                x=(j-k-hole_offset)
                if (x/k) not in ratios:
                    ratios.add(x/k)
                    outter.append((x*a,k*b))
    min_dist = (a*n+1)**2+(b*n+1)**2
    for x,y in outter:
        if x*x+y*y<min_dist:
            min_dist = x*x+y*y
            min_alpha=degrees(atan(y/x))
    return min_alpha

คุณสามารถประหยัดไบต์ได้โดยการลบพื้นที่ใน : degrees
Morgan Thrapp

ฉันไม่รู้เลยว่าคำตอบของคุณทำงานอย่างไร (ทางคณิตศาสตร์) แต่ฉันคิดว่าคุณสามารถรับ 1 ไบต์ได้โดยการลบช่องว่างหลังเครื่องหมายจุดคู่ :) (สิ่งที่ @ MorganThrapp พูด)
basile-henry

2
เส้นทางนี้ใช้ได้ แต่ไม่ใช่สั้นที่สุดในทุกกรณีเช่นกับ 2 1 4 ..
Damien

b < aนอกจากนี้ยังสันนิษฐานว่า ที่สามารถแก้ไขได้อย่างง่ายดายโดยรับขั้นต่ำ / สูงสุดaและbแม้ว่า
user81655

คงที่ (sorta)
Rod

3

Haskell, 133 117 ไบต์

นี่คือการดำเนินการของฉัน:

ด้วยตาราง 2x1 เส้นทางจะชนหมอนรองพอดีก่อนที่จะเข้าไปในกระเป๋าถ้า: (x-1) / 2 + (y-1) == n และ x, y เป็นช่วงเวลาร่วมกัน โดยที่ x, y คือระยะทางของลูกบอลเหนือแกนแนวนอน / แนวตั้ง

พา ธ นั้นเหมือนกันกับขนาดตารางโดยพลการดังนั้นเราแค่ต้องอัพเดทความยาวและมุมด้วย (a, b) และทำให้สั้นที่สุด ความยาวเส้นทางคือ sqrt ((x * a / 2) ^ 2 + (y * b) ^ 2) และมุมคือ atan ((y * b) / (x * a / 2))

z=toEnum
f a b n=minimum[[z x^2+r^2,180/pi*atan(r/z x)]|x<-[1..2*n+2],y<-[n+1-div(x-1)2],r<-[2*b/a*z y],gcd x y<2]!!1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.