Hintergrund (zu den Definitionen springen)
Euler hat einen schönen Satz über die komplexen Zahlen bewiesen: e ix = cos (x) + i sin (x).
Damit ist der Satz von de Moivre leicht zu beweisen:
(e ix ) n = e i (nx)
(cos (x) + i sin (x)) n = cos (nx) + i sin (nx)
Wir können komplexe Zahlen mit der zweidimensionalen euklidischen Ebene zeichnen, wobei die horizontale Achse den Realteil und die vertikale Achse den Imaginärteil darstellt. Auf diese Weise würde (3,4) der komplexen Zahl 3 + 4i entsprechen.
Wenn Sie mit Polarkoordinaten vertraut sind, wäre (3,4) (5, arctan (4/3)) in Polarkoordinaten. Die erste Zahl r ist der Abstand des Punktes vom Ursprung; die zweite Zahl θ ist der Winkel, der von der positiven x-Achse zum Punkt gegen den Uhrzeigersinn gemessen wird. Infolgedessen ist 3 = r cosθ und 4 = r sinθ. Daher können wir 3 + 4i schreiben als r cosθ + ri sinθ = r (cosθ + i sinθ) = re iθ .
Lösen wir die komplexe Gleichung z n = 1, wobei n eine positive ganze Zahl ist.
Wir lassen z = re iθ . Dann z n = R n e inθ . Der Abstand von Z n vom Ursprung r n , und n & theta; der Winkel ist. Wir wissen jedoch, dass der Abstand von 1 vom Ursprung 1 und der Winkel 0 ist. Daher ist r n = 1 und n & thgr; = 0. Wenn Sie sich jedoch um 2π mehr drehen, bleiben Sie am selben Punkt, da 2π nur ein voller Kreis ist. Daher ist r = 1 und n & thgr; = 2 k & pgr ;, was uns z = e 2ik & pgr; / n ergibt .
Wir wiederholen unsere Entdeckung: Die Lösungen für z n = 1 sind z = e 2ikπ / n .
Ein Polynom kann durch seine Wurzeln ausgedrückt werden. Zum Beispiel sind die Wurzeln von x 2 -3x + 2 1 und 2, also x 2 -3x + 2 = (x-1) (x-2). Ebenso aus unserer Entdeckung oben:
Dieses Produkt enthielt jedoch sicherlich Wurzeln anderer n. Nehmen Sie zum Beispiel n = 8. Die Wurzeln von z 4 = 1 würden auch innerhalb der Wurzeln von z 8 = 1 enthalten sein, da z 4 = 1 z 8 = (z 4 ) 2 = 1 2 = 1 impliziert . Nehmen Sie als Beispiel n = 6. Wenn z 2 = 1, dann hätten wir auch z 6 = 1. In ähnlicher Weise ist z 6 = 1 , wenn z 3 = 1 ist .
Wenn wir die für z n = 1 eindeutigen Wurzeln extrahieren wollen, brauchen wir k und n, um keinen gemeinsamen Teiler außer 1 zu teilen. Wenn sie sich einen gemeinsamen Teiler d teilen, wobei d> 1 ist, dann wäre z (k) / d) -te Wurzel von z n / d = 1. Unter Verwendung der obigen Technik, um das Polynom hinsichtlich seiner Wurzeln zu schreiben, erhalten wir das Polynom:
Beachten Sie, dass dieses Polynom durch Entfernen der Wurzeln von z n / d = 1 erstellt wird, wobei d ein Teiler von n ist. Wir behaupten, dass das obige Polynom ganzzahlige Koeffizienten hat. Betrachten Sie die LCM der Polynome in Form von z n / d -1, wobei d> 1 und d n dividieren. Die Wurzeln des LCM sind genau die Wurzeln, die wir entfernen möchten. Da jede Komponente ganzzahlige Koeffizienten hat, hat die LCM auch ganzzahlige Koeffizienten. Da die LCM z n -1 teilt , muss der Quotient ein Polynom mit ganzzahligem Koeffizienten sein, und der Quotient ist das obige Polynom.
Die Wurzeln von z n = 1 haben alle den Radius 1, bilden also einen Kreis. Das Polynom stellt die Punkte des Kreises dar, die für n eindeutig sind. In gewissem Sinne bilden die Polynome eine Teilung des Kreises. Daher ist das obige Polynom das n-te zyklotomische Polynom. (cyclo- = Kreis; tom- = schneiden)
Definition 1
Die n-te Kreisteilungspolynom, bezeichnet , ist die eindeutige Polynom mit ganzzahligen Koeffizienten , dass divide x n -1 aber nicht x k -1 für k <n.
Definition 2
Die zyklotomischen Polynome sind eine Menge von Polynomen, eine für jede positive ganze Zahl, so dass:
wo k | n bedeutet k dividiert n.
Definition 3
Das n-te zyklotomische Polynom ist das Polynom x n –1 geteilt durch die LCM der Polynome in der Form x k –1, wobei k n und k <n teilt.
Beispiele
- ≤ 1 (x) = x - 1
- ≤ 2 (x) = x + 1
- ≤ 3 (x) = x 2 + x + 1
- ≤ 30 (x) = x 8 + x 7 - x 5 - x 4 - x 3 + x + 1
- Φ 105 (x) = x 48 + x 47 + x 46 - x 43 - x 42 - 2x 41 - x 40 - x 39 + x 36 + x 35 + x 34 + x 33 + x 32 + x 31 - x 28 - x 26 - x 24 - x 22 - x 20 + x 17 + x 16 + x 15 + x 14 + x 13 + x 12 - x9 - x 8 - 2x 7 - x 6 - x 5 + x 2 + x + 1
Aufgabe
Bei einer positiven ganzen Zahl n
wird das n
-te zyklotomische Polynom wie oben definiert in einem vernünftigen Format zurückgegeben (z. B. eine Liste von Koeffizienten ist zulässig).
Regeln
Sie können Gleitkommazahlen / komplexe Zahlen zurückgeben, solange sie auf den richtigen Wert gerundet werden.
Wertung
Das ist Code-Golf . Kürzeste Antwort in Bytes gewinnt.
Verweise
quelle
Antworten:
Haskell , 120 Bytes
Probieren Sie es online!
Gibt eine Liste komplexer Floats mit Einträgen wie
1.0000000000000078 :+ 3.314015728506092e-14
Gleitkommazahlen an , die auf Gleitkommazahlen zurückzuführen sind. Eine direkte Methode zur Multiplikation, um das Polynom aus seinen Wurzeln zu gewinnen.Das
fromInteger
ist ein großes Zugeständnis an Haskells Typensystem. Es muss einen besseren Weg geben. Vorschläge sind willkommen. Der symbolische Umgang mit den Wurzeln der Einheit könnte ebenfalls funktionieren.Haskell , 127 Bytes
Probieren Sie es online!
Keine Importe.
Verwendet die Formel
Berechnet Φ_n (x) durch Teilen der LHS durch die anderen Terme in der RHS.
Der Operator
%
teilt Polynome und verlässt sich darauf, dass der Rest Null ist. Es wird angenommen, dass der Divisor monisch ist, und er wird ohne die führende 1 und mit unendlich nachgestellten Nullen angegeben, um ein Abschneiden zu vermeidenzipWith
.quelle
[0,0..]
ist ein Byte kürzer alsrepeat 0
.Mathematica,
4341 BytesNatürlich können wir immer den eingebauten Teiler verwenden , aber wenn wir dies nicht tun, dividiert dies x n -1 durch Φ k ( x ) (rekursiv berechnet) für jeden richtigen Teiler k von n .
Wir verwenden
Factor
, um am Ende ein Polynom zu erhalten. Ich denke, der Grund, warum dies funktioniert, ist, dassx^#-1
Faktoren in alle zyklotomischen Polynome von Teilern von n eingehen und dann diejenigen, die wir nicht wollen, aufgeteilt werden.-2 Bytes dank Jenny_mathy, das neu geschrieben wurde,
Factor
um nur für den Zähler zu gelten.quelle
Factor@
Factor[x^#-1]/Times@@...
stattdessen zu analysieren ; Wenn wir dort keine Klammern hätten, würden wir Klammern wollen.Factor[x^#-1]/Times@@...
, und es bedeutet auch, dass ich keine Ahnung habe, wie es funktioniert.MATL ,
32312725 BytesDie Ausgabe kann aufgrund von Gleitkommaungenauigkeiten (was zulässig ist) nicht ganzzahlig sein. Die Fußzeile rundet aus Gründen der Übersichtlichkeit.
Probieren Sie es online!
quelle
Haskell ,
250 236 233 218216 BytesDies ist eine ausführliche Version, (@xnor kann es in fast tun Hälfte der Partitur ), aber es funktioniert garantiert für jede
n
, solange Sie genug Speicher haben, aber es verwendet kein eingebautes Element zum Erzeugen des n-ten zyklotomischen Polynoms. Die Eingabe ist eine Ganzzahl beliebiger Größe und die Ausgabe ist ein Polynomtyp mit (exakten) rationalen Koeffizienten.Die grobe Idee ist hier, die Polynome rekursiv zu berechnen. Für
n=1
odern
prime ist es trivial. Für alle anderen Zahlen verwendet dieser Ansatz grundsätzlich die Formel aus Definition 2gelöst für . Vielen Dank an H.PWiz für eine Menge Bytes!
Dafür
n=105
ergibt sich folgendes Polynom (ich habe alles aufgeräumt%1
Nennern):Das Polynom für
n=15015
kann gefunden werden hier (der größte Koeffizient 23).Probieren Sie es online!
quelle
+1
dafür, dass du kein Eingebauter bist.Rationals
? Es scheint gut zu funktionieren ohne siequotRemPoly
, lass es mich dann nochmal versuchen!Double
Koeffizienten ergibt , wenn Sie nichtRatio Integer
stattdessen verwenden, was Probleme für sehr (sehr) große verursachen könnten
.Jelly , 23 Bytes
Probieren Sie es online!
Ausgabe als Liste von Koeffizienten.
Hat Gleitkomma- UND komplexe Ungenauigkeiten. Die Fußzeile rundet, um die Ausgabe schöner zu machen.
quelle
J , 36 Bytes
Probieren Sie es online!
Verwendet die Formel
Es gibt einige Gleitkommaungenauigkeiten, die jedoch zulässig sind.
quelle
Mathematica, 81 Bytes
quelle
R ,
176171139112 BytesProbieren Sie es online!
Massiv einfachere Version; verwendet
for
eher eine Schleife als eineReduce
.quelle
Pari / GP , 8 Bytes
Ein eingebautes.
Probieren Sie es online!
Pari / GP , 39 Bytes, ohne eingebautes
Mit der Formel:
Probieren Sie es online!
quelle
CJam (
5251 Bytes)Online-Demo . Dies ist ein anonymer Block (Funktion), der eine Ganzzahl auf dem Stapel annimmt und ein Big-Endian-Array von Koeffizienten auf dem Stapel hinterlässt.
Präparation
quelle
JavaScript (ES6),
337333284...252250245242 ByteErklärung (ausgewählt):
Initialisiere z = (1 + 0i) * x ^ 0
GCD-Berechnung.
Da ich viele mathematische Funktionen verwenden muss, habe ich hier eine andere Variable verwendet.
Polynom-Multiplikation.
Die verwendete Formel lautet
Komprimieren Sie die Ausgabe wieder in ein ganzzahliges Array.
Ausgänge:
Ein Array von Ganzzahlen, wobei das Element an Position i den Koeffizienten von x ^ i darstellt.
Ein Problem von JS ist, dass JS keine systemeigene Bibliothek für Berechnungen von Polynomen und komplexen Zahlen bereitstellt und daher eine Array-ähnliche Implementierung benötigt.
console.log (phi (105)) gibt
337> 333 (-4): Der Code zum Prüfen undefinierter Werte wurde geändert
333> 284 (-49): Die Polynom-Multiplikationsfunktion wurde geändert, da sie vereinfacht werden kann
284> 277 (-7): Redundanten Code gelöscht
277> 265 (-12): Verwenden Sie 2 Variablen anstelle eines Arrays mit 2 Elementen, um einige Bytes in der Array-Verwendung zu löschen
265> 264 (-1): Verwenden Sie Array.push () anstelle von Array.concat (), um 4 Byte zu reduzieren, fügen Sie jedoch 3 für die Klammern für for-Schleifen und die Variable z hinzu
264> 263 (-1): Bei der letzten Änderung wurde weiter Golf gespielt
263> 262 (-1): Golf auf der for-Schleife
262> 260 (-2): Die if-Klausel wurde entfernt
260> 258 (-2): Weitere Zusammenfassung der Erklärungen
258> 252 (-6): Wird bei Wiederverwendung von Array-Referenzen verwendet
252> 250 (-2): Ersetzen Sie einige unäre Operatoren als binäre Operatoren
250> 245 (-5): Verschieben Sie das Inkrement in Array.map () zur letzten Referenz des Zählers, um Bytes zu entfernen
245> 242 (-3): Verwenden Sie die Spread-Syntax anstelle von Array.push ().
quelle