Hilf mir bei der Trigonometrie!


8

Vielen Dank für Ihre Hilfe bei der Berechnung . Jetzt brauche ich Hilfe bei meinem bevorstehenden Trigonometrietest.

Beim Test muss ich die Ausdrücke vereinfachen. Ich bekomme Eingaben wie 4sin(x)/(2cos(x))und muss einen einfacheren, aber äquivalenten Ausdruck (wie 2tan(x)) erzeugen . Alle Winkel sind in Grad angegeben, und wir werden so tun, als gäbe es keine Probleme durch Division durch Null oder ungültige Domänen. (Zum Beispiel nehmen wir an, dass tan (x + 1) cot (x + 1) sin (x) / sin (x) immer 1 ist.)

Ich schlich mich in das Büro des Professors und bekam eine Liste mit 100 Problemen, die möglicherweise auf dem Prüfstand stehen. Bitte geben Sie mir den Code, um sie alle zu lösen. Es ist möglich, dass einige der Probleme bereits so weit wie möglich vereinfacht wurden. Wenn ja, geben Sie einfach die Eingabe zurück.

Ich brauche Ausdrücke, die vereinfacht werden sollen, aber ich möchte auch ein kurzes Programm (oder eine kurze Funktion), damit der Professor es nicht bemerkt. Versuchen Sie, die Summe der Programmlänge und der Gesamtlänge aller Lösungen zu minimieren.

Zur Verdeutlichung ist es in Ordnung, wenn einige der Ausdrücke unverändert oder sogar in einer äquivalenten, aber längeren Form zurückgegeben werden. Außerdem muss das Programm nur mit den unten aufgeführten Ausdrücken arbeiten. Es kann falsche Ergebnisse zurückgeben oder sogar für andere Eingaben unterbrochen werden.

Wie Sie sehen können, haben alle Probleme ein ähnliches Format. xist die einzige verwendete Variable, es gibt keine Leerzeichen und Klammern folgen jedem Funktionsnamen. (Die Funktionen sind sin, cos, tan, sec, csc, und tan.) Es gibt keine verschachtelten Funktionen, aber innerhalb einer Funktion kann einen Ausdruck sein wie 3x+4.5oder -2-.7x. Exponenten können verwendet werden, jedoch nur für Funktionen (z. B. sin(x-.5)^7), und die Potenz ist immer eine ganze Zahl über eins. Die Multiplikation wird durch Verkettung angezeigt.

Die Ausgänge müssen ebenfalls in diesem Format vorliegen. Ungültig: sin x, sin(x)/cos(x)tan(x)[? Ist die Tangente multipliziert oder dividiert], cos(x[schließen Sie alle Klammern] 4*sin(x),sec(x)^1

Ich kann jede Programmiersprache verwenden, es sei denn, sie basiert auf integrierten Vereinfachungs- oder Ausdrucksbehandlungsfunktionen. Eingebaute Triggerfunktionen sind in Ordnung. (Während des Tests habe ich einen sehr einfachen wissenschaftlichen Taschenrechner.) Da ich das auf Papier geschriebene Programm lese, kann ich auch nur druckbare ASCII-Zeichen (0x20 bis 0x7E) und Zeilenumbrüche verwenden.

1/(sec(x))
4+sin(x)+3
(cos(7x+4)-sin(-3x))/(sin(-3x))
2sin(x)2tan(x).25cos(x)^3cos(x)+1+1
7cos(x)sec(x)/(14tan(x)csc(x))
sin(x)cos(x)/sec(x)
8sin(x)cos(x)sin(x)/tan(x)+8sin(x)
sin(x)^9cos(x)cot(x)sec(x)csc(x)sec(x)tan(x)/(cot(x)^2tan(x)cos(x)^4cot(x)sin(x))
tan(x)cos(x)csc(x)
tan(x+1)sin(x-1)cos(x+1)^3tan(x-1)^2sin(-x+1)csc(x+1)tan(-x+1)/(cos(x-1)cot(x+1))
(cos(2x)+cot(2x)-sin(2x)+csc(2x)^3)/(cot(2x)+sin(2x))
cos(90-x)cos(x)
sin(x+180)sec(450-x)
tan(-x)sin(x+90)sec(x-90)
tan(x+180)^2
cot(-x)cos(-x)
cot(180-x)^3cos(270-x)^2
sin(.1x-.2)sin(.1x-.2)sin(.1x-.2)sin(.2-.1x)sin(.2-.1x)
sin(x)
sin(90-x)sin(x)+cos(90-x)/sec(x)
tan(3x+2)cos(3x+2)/sin(3x+2)-1
cos(x)cos(x)cos(x)cos(x)cos(x)
sec(2x+1)sec(-1-2x)+sec(-2x-1)sec(2x+1)
cos(4x)cot(4x)tan(4x)sin(4x)csc(4x)
-cos(x)+cos(x)+sin(2x-4)-1/csc(2x-4)
sec(x)sec(x+2)cot(x)tan(x-2)tan(x+180)
tan(x)(tan(x))
3sin(x)sin(x)/(3)
cos(x)sin(x)
tan(x)sec(x)^2
tan(x)^2-sec(x)^2
7+sin(x)csc(x)csc(x)+cot(x)^2
sin(90)+cos(-90)+sec(180)
csc(1)+csc(10)-csc(30)-csc(60)+csc(90)
sin(36000001)
csc(800)+(cot(720+x)-sec(4x-720))
sin(-x)+sin(x)
csc(-x)+csc(x)
4sin(x)-sin(x)+tan(x)-2tan(x)
cot(x)+10cot(x+90)+99cot(x+180)+.01cot(x-90)
tan(x)tan(x+180)
sec(x)sin(x+180)tan(x-270)cot(x-450)csc(x+90)
sin(x)/cot(x)+sin(x)/cot(x)
sin(x)csc(x)+tan(x)cot(x)+cos(x)sec(x)
cot(x)
9tan(x+90)+90tan(x+9)
cos(x-9999)+tan(x+99999)
2tan(x)tan(x)/2
tan(x)/tan(x-360)+cos(x+180)/cos(x)
csc(4x)sec(270-4x)
cot(91+x)tan(x-449)
csc(2x)(csc(2x)-sin(2x))
csc(x+1)^2-cot(x+1)cot(x+1)
cot(x)cot(x)+1
tan(x)^2-sec(x)sec(x)
tan(x)/cot(x)+csc(x)/csc(x)
cot(x)sin(x)/cos(x)
csc(x)tan(x)cos(x)
csc(x)cot(x)cos(x)
csc(x+90)csc(-x+270)-1
cot(x)/cot(x)+tan(x)/cot(x)+cot(x)cot(x)
sec(x)sec(x)sec(x)sec(x+90)sec(x-90)sec(x+180)
1-cos(x)cos(x+180)+sin(x)^2
sec(x)sec(x)sec(x)sec(x)/cos(x)+cot(x)
cot(x+1)csc(x-1)sec(x+1)tan(x-1)sin(x+1)cos(x-1)
sin(x)-cos(x)+tan(x)-sec(x)+cos(x)-csc(x)
tan(x+23515)-sec(-.27x-23456)
sec(-.9x)
-tan(-x)-csc(360-x)
cos(-x)sec(x)sin(x)csc(-x)
tan(-x)^2-sin(-x)/sin(x)
tan(x)tan(x)+1
csc(x)^2-1
cot(2x)cot(2x)-csc(2x)/sin(2x)
2sec(x)/(6cos(x))
sec(0)+tan(30)cos(60)-csc(90)sin(120)cot(150)+tan(180)csc(210)sin(240)-cos(270)sec(300)+cot(330)
tan(x-1234567)sec(4781053+x)^2
tan(-1234567x)sec(4781053x)^2
sin(x)^9+cos(x)^7+csc(x)^5-cot(x)^3
cos(-33x-7.7)
sec(-.1-x)+tan(-2x-77)
tan(x)+sin(x)-cos(x)+tan(x)-sin(x)
cos(x)-sec(x)/tan(x)+tan(x)/sin(x)
cot(x)-cos(x)/sin(x)
3cos(x)+2/sec(x)-10sin(x)/(2tan(x))
tan(x+3)^11+sin(x+3)^8-cos(x+3)^5+5
sec(x)+sec(x)
csc(.1x)csc(-.1x)csc(x)
cot(x-7)cot(x-7)cot(x+173)cot(x-7)cot(x+173)cot(x-367)
cos(.0001x+1234567)
cot(45)+tan(225)-sin(210)+cos(-60)
sin(12345)cos(23456)tan(34567)sec(45678)csc(56789)cot(67890)
cos(1234x)+cot(1234)+tan(1234x)+sec(1234)+csc(1234)+sin(1234x)
sec(x)sec(x)sec(x)sec(x)sec(x)sec(x)
csc(x)cot(x)sec(x)csc(x)tan(x)sec(x)cot(x)csc(x)cot(x)cos(x)cos(x)cot(x)sin(x)sin(x)cot(x)
csc(2553273)+cot(1507348)-sec(5518930)+csc(5215523)+tan(3471985)-sec(4985147)
sin(20x)+cos(20x)-tan(20x)+sin(20x)-csc(20x)+cot(20x)-tan(20x)+csc(20x)
cot(100000)+cot(100000x)+cot(100000x)+cot(100000)
csc(5x+777)sin(5x+777)
csc(4.5x)

Hinweis: Dieses Szenario ist vollständig fiktiv. Im wirklichen Leben ist es falsch und sollte niemals getan werden, anderen zu schummeln und ihnen zu helfen.


5
Ich zähle nicht weniger als vierzig verschiedene Identitäten und mathematische Axiome, die erforderlich wären, um dies zu vereinfachen. Selbst das Parsen eines der Ausdrücke und das Bringen in eine strukturierte interne Form würde einiges an Code erfordern. Zu reich für mich. Aber vielleicht gibt es hier einige, die nach einer solchen Herausforderung suchen.
COTO

@COTO du musst es nicht analysieren. Sie können versuchen, das Problem zu erkennen und die Antworten in komprimierter Form fest zu codieren. Es könnte sogar kürzer sein als das Parsen.
Ingo Bürk

3
Wenn Ihr Drucker keine Nicht-ASCII-Zeichen drucken kann, benötigen Sie einen besseren Drucker.
John Dvorak

3
Ich dachte nur, WTF, dieser Typ hat sogar UPVOTES? Dann bemerkte ich, dass es nicht math.SE war, also ... Kontext ist wichtig =)
fehlerhaft

1
@Ypnypn Oh, ok, also können wir uns zum Beispiel nicht sin(36000001) auf.017452
Digital Trauma

Antworten:


8

Python, 436 + 1909 = 2345

Dies muss eine der ineffizientesten Lösungen sein, die man sich vorstellen kann, und Mathematiker werden wahrscheinlich zusammenzucken, aber ich habe es geschafft, etwas zusammen zu werfen, das tatsächlich etwa die Hälfte der Ausdrücke ohne Hardcodierung vereinfacht:

from math import*
import exrex,re
d=lambda f:lambda x:f(x*pi/180)
sin,cos,tan=d(sin),d(cos),d(tan)
i=lambda f:lambda x:1/f(x)
sec,csc,cot=i(cos),i(sin),i(tan)
t=lambda s:[round(eval(re.sub('([\d\).])([\(a-z])','\\1*\\2',s).replace('^','**')+'+0')*1e9)for x in[1,44]]
def f(I):
 try:return min((s for s in exrex.generate('(-?\d|\(1/\d\.\))?([+-]?(sin|cos|tan|cot|sec|csc)\(x\)(\^\d)?){0,4}')if s and t(s)==t(I)),key=len)
 except:return I

Die Ausgabe für die 100 Testfälle sollte wie folgt sein (wobei #Ausdrücke markiert werden, die nicht vereinfacht wurden):

cos(x)
7+sin(x)
#
2+tan(x)^2cos(x)^2
(1/2.)cos(x)
sin(x)cos(x)^2
#
sin(x)^2tan(x)^7
1
#
#
sin(x)cos(x)
-1
-1
tan(x)^2
-cot(x)cos(x)
-cot(x)cos(x)^2
#
sin(x)
2sin(x)cos(x)
0
cos(x)^5
#
#
#
#
tan(x)^2
sin(x)^2
sin(x)cos(x)
tan(x)sec(x)^2
-1
7+cot(x)^2+csc(x)
0
#
#
#
0
0
3sin(x)-tan(x)
#
tan(x)^2
-tan(x)sec(x)
2sin(x)tan(x)
3
cot(x)
#
#
tan(x)^2
0
#
1
#
1
csc(x)^2
-1
sec(x)^2
1
1
cot(x)^2
-1-sec(x)^2
cot(x)^2+sec(x)^2
sec(x)^4csc(x)^2
2
cot(x)+sec(x)^5
#
sin(x)+tan(x)-csc(x)-sec(x)
#
#
tan(x)+csc(x)
-1
sec(x)^2
sec(x)^2
cot(x)^2
-1
(1/3.)sec(x)^2
#
#
#
#
#
#
2tan(x)-cos(x)
cos(x)-csc(x)+sec(x)
0
0
#
2sec(x)
#
#
#
3
#
#
sec(x)^6
cot(x)^4csc(x)
#
#
#
1
#

Die Idee ist ganz einfach:

  • erzeugen eine große Menge möglicher Ausdrücke
  • Wählen Sie diejenigen aus, die das gleiche Ergebnis wie der Ausdruck erzielen, den Sie vereinfachen möchten, und vergleichen Sie sie für einige (hier zwei) x-Werte
  • von den äquivalenten Ausdrücken wird der kürzeste zurückgegeben

Das Problem ist, dass es eine Menge möglicher Ausdrücke gibt, die überprüft werden müssen. Deshalb habe ich sie auf eine Teilmenge beschränkt.

Um ehrlich zu sein, war ich nicht geduldig genug, um den Golfcode oben zu testen. (Sagen Sie mir, wenn Sie denken, dass dies Betrug ist.) Stattdessen habe ich eine viel längere, aber effizientere Regel verwendet, um eine noch kleinere Teilmenge von Ausdrücken zu generieren, die hoffentlich noch alle gewünschten Vereinfachungen enthält. Wenn Sie dies versuchen möchten, ersetzen Sie den regulären Ausdruck in der vorletzten Zeile des Codes durch den folgenden (und bereiten Sie sich auf einige Minuten Rechenzeit vor):

'0|((-1|\(1/[23]\.\)|[1237])[+-]?)?(sin\(x\)(\^2)?)?-?(tan\(x\)(\^[27])?)?(cot\(x\)(\^[24])?)?[+-]?(cos\(x\)(\^[25])?)?(sec\(x\)(\^[2456])?)?(csc\(x\)(\^2)?)?'

Das Programm enthält auch einige Gemeinkosten, die erforderlich waren, damit Python die mathematischen Ausdrücke versteht. Dies beinhaltete

  • neu zu definieren sin, cosund tanArgumente in Grad zu nehmen statt radiens (das ist , was ich denke , die OP beabsichtigt)
  • definieren sec, cscund cotdie nicht Teil des mathPakets sind
  • Einfügen aller implizierten Multiplikationszeichen
  • Ersetzen des Exponentiationsoperators

@Doorknob Wie sind Brute-Forcing-Ausdrücke und der Vergleich zweier Werte mehr eine "echte Lösung" als die anderen?
Ingo Bürk

@Emil Da Sie nur zwei verschiedene Werte für "x" vergleichen, haben Sie irgendwie sichergestellt, dass die Vereinfachungen tatsächlich korrekt sind?
Ingo Bürk

Wenn ich es kurz betrachte, kann ich keine falschen Vereinfachungen finden (beeindruckend), aber nach meinem Verständnis 1/3.sec(x)^2ist die Ausgabe nicht gültig.
Ingo Bürk

1
@ IngoBürk, alle Antworten wurden zuerst von Hand oder mit WolframAlpha berechnet und ich habe diese später mit der Ausgabe des Programms verglichen. In zwei oder drei Fällen fand das Programm tatsächlich Vereinfachungen, die WolframAlpha nicht ausgab, aber ich konnte bestätigen, dass diese auch korrekt waren. Aber natürlich haben Sie Recht, es kann möglicherweise zu Kollisionen kommen. Es ist nur so, dass die Art der fraglichen Funktionen es ziemlich unwahrscheinlich macht, dass sich zwei unterschiedliche Graphen an meinen beiden Punkten innerhalb der verwendeten Genauigkeit schneiden. Ich habe Kollisionen gesehen, wenn ich nur einen Punkt verwende oder wenn die beiden Punkte zu nahe beieinander liegen.
Emil

1
@ Emil Okay. Ich liebe diese Lösung übrigens wirklich!
Ingo Bürk

6

CJam, 1 + 3000 = 3001

Genau wie die Basislösung, um Menschen etwas zu schlagen:

l

Dies liest STDIN auf den Stapel, dessen Inhalt am Ende des Programms gedruckt wird.

Ich bin sicher, dass dies geschlagen werden kann, aber ich bin auch sicher, dass viele Optimierungen nicht in den Charakteren implementiert werden können, die gewonnen werden würden.


Wurde irgendwo angegeben, wie die Punktzahl berechnet werden soll? Ich mag deine Methode. Allerdings würde ich die Zeilenumbrüche nicht berücksichtigen, so dass die Basispunktzahl 3000 wäre.
Emil

@Emil "Versuchen Sie, die Summe der Programmlänge und der Gesamtlänge aller Lösungen zu minimieren." - Ich musste es auch mehrmals lesen.
Ingo Bürk

Ich frage mich, warum Martin Golfscript nicht verwendet hat. Keine Notwendigkeit, explizit den Eingang dort lesen = D
Ingo Bürk

Ich verstehe nicht Wie hängt diese und die folgende Antwort mit der Frage zusammen, die nach Trigonometrie und anderen Dingen fragt
Optimizer

2
@ IngoBürk Weil ich GolfScript nicht kenne. : P
Martin Ender

5

Javascript (438 + 2498 = 2936)

Das Objekt in der Mitte enthält optional vereinfachte Ausgaben basierend auf der Länge der Eingabe und dem ersten Zeichen. Andernfalls wird die Eingabe unverändert zurückgegeben.

s='sin(x)';(p=prompt)({
    352:s+"^2cos(x)^3+2",
    307:"cos(x)/2",
    348:s+"8(1+cos(x)^2)",
    "81s":s+"^2tan(x)^7",
    "55s":"-sin(0.2-0.1x)^5",
    "39s":"2sec(2x+1)^2",
    "35c":"cos(4x)",
    "36-":0,
    173:s+"^2",
    "25s":0,
    294:s+"3-tan(x)",
    "27s":s+"2/cot(x)",
    "40c":"1+tan(x)^2+cot(x)^2",
    "48c":1,
    "41s":s+"+tan(x)-csc(x)-sec(x)",
    "26c":-1,
    "24t":"1+tan(x)^2",
    "96s":"2.5+1/cos(30)",
    "34t":"2tan(x)-cos(x)",
    353:0,
    "36s":"6sec(x)",
    "90s":"cot(x)^4csc(x)"
}[(i=p()).length+i[0]]||i)

Das Leerzeichen dient nur zur Dekoration und ist nicht in der Anzahl der Zeichen enthalten.

Es ist eine Schande, dass mir das Hinzufügen all dieser Lösungen nur ein paar Zeichen erspart hat, aber besser als nichts. Die Vereinfachung erfolgte über Wolframalpha - ich vertraue einfach darauf.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.