Früher habe ich Code-Golf-Rätsel wie Sie gelöst, aber dann habe ich einen Pfeil ins Knie genommen

18

Mit Pfeilen ins Knie getroffen zu werden, scheint momentan die Verletzung der Wahl zu sein . Als solches schlage ich die folgende Golfherausforderung vor.

Du hast einen Abenteurer, der so aussieht:

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

Schreiben Sie in einer Textdatei, die einen Bogen (als }Symbol gezeichnet ), eine Reihe von Wänden (als #Symbole gezeichnet ) und einen Abenteurer enthält, den kleinsten Code, der den Winkel und die Anfangsgeschwindigkeit berechnet, mit der Sie einen Pfeil abfeuern müssen, um zu treffen ihn im Knie.

Es sei folgendes angenommen:

  • Jedes Zeichen in der Datei ist 0,5 x 0,5 Meter groß.
  • Der Pfeil wird von der Mitte des abgefeuert }, dh ein Versatz von0.25m, 0.25m
  • Die Schwerkraft ist 10ms^-2
  • Pfeil wiegt 0.1kg
  • Pfeil ist ein Punkt, dh Kollisionen treten nur auf, wenn die Pfeilkoordinate in einen der Blöcke eintritt.
  • Die maximale Anfangsgeschwindigkeit beträgt 50m/s
  • Der Winkel kann zwischen 0 (gerade nach oben) und 180 (gerade nach unten) liegen.
  • Wenn Sie einen Teil des Beines des Abenteurers treffen, wird dies als Knietreffer angesehen.
  • Eine Wand ( #Charakter) nimmt einen ganzen 0,5 mx 0,5 m großen Block ein.
  • Der Pfeil kann sich über die "Oberseite" der Datei bewegen, aber nichts hindert die Eingabe daran, mit einer Zeichenobergrenze zu beginnen #.
  • Sie können nicht Wände mit Pfeilen durchdringen.
  • Das Schlagen eines anderen Teils des Abenteurers ist nicht erlaubt!
  • Sie sollten einen Fehler anzeigen, wenn es nicht möglich ist, ihn im Knie zu treffen.

Beispiel Eingabe:

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

Fühlen Sie sich frei, Fragen zu stellen, wenn Sie müssen :)

Polynom
quelle
1
Kann sich der Pfeil "über" den in der Textdatei dargestellten Bereich bewegen?
JB
2
Wie viele Leute kennen Sie, die über 3 m groß sind? : P
Peter Taylor
@JB - Ja, aber es gibt nichts, was die Eingabe stoppen könnte, beginnend mit einer großen Zeile von #############...
Polynom
2
@ Peter Taylor - Jeder weiß, dass die Leute in RPG-Spielen überproportional groß sind;)
Polynom
2
Das Gewicht des Pfeils ist doch überflüssig?
Paul R

Antworten:

11

Python, 599 Zeichen

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'

Die X(K,L)Routine nimmt eine Parabel, K=(a,b,c)die y = ax ^ 2 + bx + c darstellt, und ein Liniensegment, L=(a,b,c,d)das das Segment zwischen (a, b) und (c, d) darstellt . Beide Hindernisse ( O) und das Ziel ( T) werden als Liniensegmente dargestellt. Alle Abstände sind um den Faktor 2 skaliert.

Die Beispieleingabe gibt die folgende Flugbahn an (standardmäßig die Mindestgeschwindigkeit eins):

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

Sie können rückwärts fahren R, um den maximalen Geschwindigkeitspfad zu erhalten:

                                 #                        
-------------                                         O   
             -----------#                            /|\  
                        --------                    / | \ 
            #                   -------               |   
                            #          -----          |   
                                            -----    / \  
                                                 -----  \  
Keith Randall
quelle
Gute Arbeit. Einzige Beschwerde ist, dass die maximale Eingabegröße 999 Bytes beträgt. Angesichts der möglichen Größe dieser ASCII-Zeichnungen könnte es durchaus mehr sein. 9999 wäre sinnvoller, auf Kosten von nur 1 Charakter. (obwohl Sie zu diesem Zeitpunkt genauso gut 8**564kB benötigen könnten)
Polynom
Ziemlich sicher, dass Sie dieses eine Zeichen dann speichern können, w=v+1indem Sie die 3 Instanzen von v+1mit zuweisen und ersetzen w. Ich codiere allerdings nicht viel Python, daher kann ich mich irren.
Polynom