Обобщенный алгоритм Евклида (Наибольший общий делитель) - Lisp
Формулировка задачи:
Этот алгоритм (см. скриншот), помимо нахождения наибольшего общего делителя a и b (gcd a b), должен также возвращать x и y, удовлетворяющим условию:
ax + by = (gcd a b)
Мое решение получилось громоздким и не везде работает корректно. Предложите ваш вариант.
(gcd 28 19) ==> (1 -2 3) - пример из учебника. (gcd 28 19) = 1, x = -2, y = 3. Верно. (gcd 67 20) ==> (1 3 -10). Проверка. Подставляем в условие ax + by = (gcd a b): 67*3 + 20*(-10) = 1 = (gcd 67 20). Верно. (gcd 50 30) ==> (10 -1 2). Проверка. Подставляем в ax + by = (gcd a b): 50*(-1) + 30*2 = 10 = (gcd 50 30). Верно. (gcd 101 50) ==> (1 1 -2). Проверка: 101*1 + 50*(-2) = 101 - 100 = 1 = (gcd 101 50). Верно. (gcd 100 50) ==> nil - Ошибка. (gcd 50 100) ==> (50 1 0) - ok. (defun gcd (a b &optional (U (list a 1 0)) (V (list b 0 1)) TT (q (\ (car U) (car V)))) (cond ((zerop (car V)) TT) ((zerop (car (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))))) TT) (t (gcd a b V (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))) (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))) (\ (car V) (car (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V))))) )))))
Решение задачи: «Обобщенный алгоритм Евклида (Наибольший общий делитель)»
textual
Листинг программы
(defun gcd (a b &optional (U (list a 1 0)) (V (list b 0 1)) (q (\ (car U) (car V))) (TT (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))))) (cond ((zerop (car TT)) V) ((zerop (car (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))))) TT) (t (gcd a b V (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))) (\ (car V) (car (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V))))) ) (list (% (car U) (car V)) (- (cadr U) (* q (cadr V))) (- (caddr U) (* q (caddr V)))) ))))
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д