J'avais l'habitude de résoudre des énigmes de golf de code comme vous, mais ensuite j'ai pris une flèche dans le genou

18

Se faire frapper au genou avec des flèches semble être la blessure de choix en ce moment. À ce titre, je propose le défi de golf suivant.

Vous avez un aventurier qui ressemble à ceci:

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

Étant donné un fichier texte contenant un arc (dessiné comme }symbole), un ensemble de murs (dessinés comme #symboles) et un aventurier, écrivez le plus petit code qui calcule l'angle et la vitesse initiale à laquelle vous devez tirer une flèche pour frapper lui dans le genou.

Supposons ce qui suit:

  • Chaque caractère du fichier mesure 0,5 x 0,5 mètre.
  • La flèche est tirée depuis le centre de la }, c'est-à-dire un décalage de0.25m, 0.25m
  • La gravité est 10ms^-2
  • La flèche pèse 0.1kg
  • La flèche est un point, c'est-à-dire que les collisions ne se produisent que lorsque les coordonnées de la flèche pénètrent dans l'un des blocs.
  • La vitesse initiale maximale est 50m/s
  • L'angle peut être compris entre 0 (droit vers le haut) et 180 (droit vers le bas)
  • Frapper n'importe quelle partie de la jambe de l'aventurier est considéré comme un coup au genou.
  • Un mur ( #personnage) occupe un bloc entier de 0,5 mx 0,5 m.
  • La flèche peut se déplacer sur le "haut" du fichier, mais rien n'empêche l'entrée de commencer par un plafond de #caractères.
  • Vous ne pouvez pas pénétrer les murs avec des flèches.
  • Frapper toute autre partie de l'aventurier n'est pas autorisé!
  • Vous devriez afficher une erreur s'il est impossible de le frapper au genou.

Exemple d'entrée:

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

N'hésitez pas à poser des questions si vous en avez besoin :)

Polynôme
la source
1
La flèche peut-elle se déplacer sur la zone représentée par le fichier texte?
JB
2
Combien de personnes connaissez-vous qui mesurent plus de 3 mètres? : P
Peter Taylor
@JB - Oui, mais il n'y a rien pour arrêter l'entrée en commençant par une grosse file de #############...
Polynomial
2
@PeterTaylor - Tout le monde sait que les gens dans les jeux de rôle sont démesurément énormes;)
Polynomial
2
Le poids de la flèche est redondant, sûrement?
Paul R

Réponses:

11

Python, 599 caractères

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'

La X(K,L)routine prend une parabole K=(a,b,c)représentant y = ax ^ 2 + bx + c et un segment de ligne L=(a,b,c,d)représentant le segment entre (a, b) et (c, d) . Les obstacles ( O) et la cible ( T) sont représentés comme des segments de ligne. Toutes les distances sont mises à l'échelle par un facteur de 2.

L'exemple d'entrée donne la trajectoire suivante (par défaut, la vitesse minimale):

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

vous pouvez inverser Rpour obtenir le chemin de vitesse maximum:

                                 #                        
-------------                                         O   
             -----------#                            /|\  
                        --------                    / | \ 
            #                   -------               |   
                            #          -----          |   
                                            -----    / \  
                                                 -----  \  
Keith Randall
la source
Bon travail. Le seul problème est que la taille limite d'entrée est de 999 octets. Cela pourrait très facilement être plus, compte tenu de la taille potentielle de ces dessins ASCII. 9999 serait plus sensé, au prix d'un seul caractère. (bien qu'à ce stade, vous feriez aussi bien 8**5de faire 64 Ko)
Polynomial
Je suis presque sûr que vous pourriez alors sauvegarder ce caractère en assignant w=v+1et en remplaçant les 3 instances de v+1avec w. Je ne code cependant pas beaucoup Python, donc je peux me tromper.
Polynôme