Saya biasa memecahkan teka-teki kode golf seperti Anda, tetapi kemudian saya mengambil panah di lutut

18

Dipukul di lutut dengan panah tampaknya menjadi pilihan cedera sekarang. Karena itu, saya mengusulkan tantangan golf berikut.

Anda memiliki seorang petualang yang terlihat seperti ini:

  O
 /|\
/ | \
  |
  |
 / \
/   \

Diberikan file teks yang berisi satu busur (digambar sebagai }simbol), satu set dinding (digambar sebagai #simbol) dan satu petualang, tulis kode terkecil yang menghitung sudut dan kecepatan awal di mana Anda harus menembakkan panah untuk memukul dia di lutut.

Asumsikan yang berikut:

  • Setiap karakter dalam file adalah 0,5 x 0,5 meter.
  • Panah ditembakkan dari pusat }, yaitu offset dari0.25m, 0.25m
  • Gravitasi adalah 10ms^-2
  • Panah berbobot 0.1kg
  • Panah adalah sebuah titik, yaitu tabrakan hanya terjadi ketika koordinat panah memasuki salah satu blok.
  • Kecepatan awal maksimum adalah 50m/s
  • Sudut mungkin antara 0 (lurus ke atas) dan 180 (lurus ke bawah)
  • Memukul bagian mana pun dari kaki petualang dianggap memukul lutut.
  • Dinding ( #karakter) memakan satu blok 0,5 mx 0,5 m.
  • Panah dapat berjalan di atas "atas" file, tetapi tidak ada yang menghentikan input dari mulai dengan plafon #karakter.
  • Anda tidak dapat menembus dinding dengan panah.
  • Memukul bagian petualang lainnya tidak diperbolehkan!
  • Anda harus menampilkan kesalahan jika memukul lututnya tidak mungkin.

Input contoh:

                                 #                        
}                                                     O   
                        #                            /|\  
                                                    / | \ 
            #                                         |   
                            #                         |   
                                                     / \  
                                                    /   \  

Jangan ragu untuk bertanya jika perlu :)

Polinomial
sumber
1
Bisakah panah melewati "atas" area yang digambarkan oleh file teks?
JB
2
Berapa banyak orang yang Anda kenal yang tingginya lebih dari 3m? : P
Peter Taylor
@ JK - Ya, tapi tidak ada yang menghentikan input dimulai dengan garis besar #############...
Polinomial
2
@PeterTaylor - Semua orang tahu bahwa orang-orang di game RPG sangat besar;)
Polinomial
2
Berat panah itu berlebihan, tentu?
Paul R

Jawaban:

11

Python, 599 karakter

import os,sys
from math import*
I=os.read(0,999)
O=[]
h=v=0
for i in I:
 if'#'==i:O+=[(h,v,h+1,v+1),(h+1,v,h,v+1)]
 if'O'==i:O+=[(h,v+1,h-2,v+3)];T=(h,v+5,h-2,v+7)
 if'}'==i:e=h+.5;c=v+.5
 h+=1
 if'\n'==i:v+=1;h=0

def X(K,L):
 A,B,C=K;p=L[0];q=L[2]-p;r=L[1];s=L[3]-r;A,B,C=A*q*q,2*A*p*q+B*q-s,A*p*p+B*p+C-r;d=B*B-4*A*C
 return 0 if d<0 else any(0<x<1 for x in[(sqrt(d)-B)/2/A,(-sqrt(d)-B)/2/A])

R=range(1,999)
for v in R:
 for z in R:
  z*=pi/999;d=v*sin(z)/10;b=-v*cos(z)/10
  K=20/d/d,b/d-40*e/d/d,c+20*e*e/d/d-b*e/d
  if X(K,T)and not any(X(K,x)for x in O):print v/2,z;sys.exit(0)
print'ERROR'

The X(K,L)rutin mengambil parabola K=(a,b,c)mewakili y = ax ^ 2 + bx + c dan segmen garis L=(a,b,c,d)yang mewakili segmen antara (a, b) dan (c, d) . Rintangan ( O) dan target ( T) direpresentasikan sebagai segmen garis. Semua jarak diskalakan dengan faktor 2.

Input contoh memberikan lintasan berikut (secara default, satu kecepatan minimum):

  --                             #          --            
--                                            -       O   
                        #                      -     /|\  
                                                -   / | \ 
            #                                    -    |   
                            #                     -   |   
                                                   - / \  
                                                    -   \  

Anda dapat membalikkan Runtuk mendapatkan jalur kecepatan maksimum:

                                 #                        
-------------                                         O   
             -----------#                            /|\  
                        --------                    / | \ 
            #                   -------               |   
                            #          -----          |   
                                            -----    / \  
                                                 -----  \  
Keith Randall
sumber
Kerja bagus. Satu-satunya keluhan adalah bahwa batas ukuran input adalah 999 byte. Bisa jadi lebih mudah, mengingat ukuran potensial dari gambar-gambar ASCII ini. 9999 akan lebih masuk akal, dengan biaya hanya 1 karakter. (meskipun pada titik itu Anda mungkin juga melakukannya 8**5untuk mendapatkan 64kB)
Polinomial
Cukup yakin Anda bisa menyimpan satu karakter dengan menetapkan w=v+1dan mengganti 3 contoh v+1dengan w. Saya tidak banyak kode Python, jadi saya mungkin salah.
Polinom