Hier ist eine mögliche Lösung ohne die Verwendung einer power
-Funktion (beachten Sie, dass eine solche Funktion bereits in Common Lisp, expt
definiert ist).
(defun ord (n r)
(if (> (gcd r n) 1)
0
(loop for k from 1
for v = r then (* v r)
when (= 1 (mod v n))
do (return k))))
Um die multiplikative Ordnung von ein Modulo n berechnet man die Funktion mit (ord a n)
nennen sollte. Zum Beispiel:
(ord 7 10) ; => 6
seit 10 ≡ 1 (mod 7)
Die Funktion prüft zuerst, um zu sehen, ob die beiden Parameter coprimes sind, sonst kehrt sie 0. Dann ist das erweiterte loop
Form verwendet wird eine Schleife über zwei Variablen, k
(das Ergebnis), beginnend bei 1 und bei jeder Iteration um 1, und v
, die aktuelle Leistung von r
, ausgehend von r
und zunehmende Multiplikation des vorhergehenden Wertes mit r
bei jeder Iteration (so Bei jeder Iteration die Invar iant ist v = rk). Wenn wir den Wert k
so erreichen, dass v mod n = 1 ist, beenden wir die Iteration, die k
zurückgibt.
Für eine detaillierte Beschreibung von loop
sehen entweder die formal definition oder eine praktische Erklärung (in Kapitel 7 und 22) des wirklich nützlichen Buchs Practical Common Lisp (ein „Muss lesen“ Common Lisp lernen).
Ich würde mit einer besseren Formatierung beginnen. Im Moment ist Ihr Code nicht lesbar. Als nächstes müssen Sie eine Fehlerbeschreibung schreiben: Was schief gelaufen ist und wie! Dann müssen Sie sich fragen, ob das DEFVAR-Konstrukt in diesem Kontext nützlich ist ... –
danke, weil ich neu bin mit Lisp, also muss es eine Menge Fehler geben –