Найти в каждой строке наибольший элемент и элемент главной диагонали и поменять их местами - Lisp
Формулировка задачи:
Найти в каждой строке наибольший элемент и элемент главной диагонали и поменять их местами.
Решение задачи: «Найти в каждой строке наибольший элемент и элемент главной диагонали и поменять их местами»
textual
Листинг программы
(defun main-dmax (w &optional (n 0) &aux (a (car w))) (when w (cons (progn (rotatef (nth (position (reduce #'max a) a) a) (nth n a)) a) (main-dmax (cdr w) (1+ n))))) > (main-dmax '((1 2 3) (4 5 6) (7 8 9))) ((3 2 1) (4 6 5) (7 8 9)) > (main-dmax '((1 22 3) (44 5 6) (77 8 9))) ((22 1 3) (5 44 6) (9 8 77))
Объяснение кода листинга программы
В этом коде определена функция main-dmax
, которая принимает строку w
и номер строки n
в качестве входных данных.
Опциональный аргумент n
имеет значение 0 по умолчанию.
Внутри функции используется вспомогательная переменная a
, которая сначала содержит первый элемент строки w
.
Если w
не является пустой, то функция cons
создаёт новый список, содержащий два элемента:
- Результат вызова функции
progn
, которая сначала находит максимальное значение в спискеa
с помощью функцииreduce
и функцииmax
. - Затем функция
rotatef
меняет местами это максимальное значение с элементом в позицииn
в спискеa
. - После этого функция
cons
создаёт новый список, содержащий результатыprogn
иrotatef
, а также исходный списокa
. - Если
w
является пустой, то функцияcons
создаёт новый список, содержащий только исходный списокa
. - Наконец, функция
main-dmax
рекурсивно вызывается для оставшейся части строкиw
и нового значенияn
, увеличенного на 1. Пример использования функцииmain-dmax
со спискомw = '((1 22 3) (44 5 6) (77 8 9))
: — На первом шаге функцияmain-dmax
вызывает вспомогательную функциюprogn
, которая находит максимальное значение в списке(1 22 3)
, то есть3
. — Затем функцияrotatef
меняет местами3
и элемент в позиции 1 в списке(1 22 3)
, то есть результатprogn
—3
, становится2
, а элемент в позиции 1 становится3
. — На следующем шаге функцияmain-dmax
вызывается рекурсивно для списка(44 5 6)
и нового значенияn = 2
. — На этом шаге функцияprogn
находит максимальное значение в списке(44 5 6)
, то есть6
. — Затем функцияrotatef
меняет местами6
и элемент в позиции 2 в списке(44 5 6)
, то есть результатprogn
—6
, становится5
, а элемент в позиции 2 становится6
. — На следующем шаге функцияmain-dmax
вызывается рекурсивно для списка(77 8 9)
и нового значенияn = 3
. — На этом шаге функцияprogn
находит максимальное значение в списке(77 8 9)
, то есть9
. — Затем функцияrotatef
меняет местами9
и элемент в позиции 3 в списке(77 8 9)
, то есть результатprogn
—9
, становится8
, а элемент в позиции 3 становится9
. — Наконец, функцияcons
создаёт новый список, содержащий результатыprogn
иrotatef
, а также исходный списокa
, то есть(2 5 3) (6 44 9) (8 77)
.