Макрос, позволяющий перечислить все симметричные числа из заданного диапазона - Lisp
Формулировка задачи:
Написать макрос symmetric, который позволяет перечислить все симметричные числа из заданного диапазона. Будем называть симметричными целые положительные числа (в десятичной системе счисления), которые состоят из двух и более цифр и которые читаются слева направо и справа налево одинаково, например: 121, 5665, 988889.
Макрос должен иметь следующий вид:
Аргумент var – имя переменной, которая на каждой итерации принимает значение очередного симметричного числа; аргумент startv – значение, с которого начинается проверка (начало диапазона); endv – значение, на котором заканчивается проверка (конец диапазона).
Пример: Вызов (symmetric (n 1 43) (fresh-line) (prinс n)) должен вывести на экран следующие числа:
11
22
33
Я попробовал написать, как это будет выглядеть в виде функции, но как подвязать это к макросу и коду для проверки, предложенному в задании, так и не понял:
(defmacro symmetric ((var startv endv) &body body) ;; Здесь будет код макроса ) ;;;; !!! не удаляйте и не изменяйте этот код, он необходим для проверки !!! ;;;; (defparameter s (read)) (print (with-output-to-string (*standard-output*) (symmetric (i (elt s 0) (elt s 1)) (princ i)) (symmetric (i (elt s 2) (elt s 3)) (princ i)))) ;;;; !!! не удаляйте и не изменяйте этот код, он необходим для проверки !!! ;;;;
(defmacro symmetric ((var startv endv) &body body) (loop for i from startv to endv do (setf c i) (setf cc 0) (loop while (>= c 1) do ((setf cc (+ (* cc 10) (mod c 10))) (setf c (/ c 10)))) (if (= c i) (print i))))
Решение задачи: «Макрос, позволяющий перечислить все симметричные числа из заданного диапазона»
textual
Листинг программы
(measure-syms (expt 10 7)) ; measure #<Compiled-function SYMMETRICP #x3020032E35BF> from 10 to 10000000 ; (LOOP :FOR X :FROM START :TO END :WHEN (FUNCALL PREDICATE X) :COUNT :IT) ; took 2,930,003 microseconds (2.930003 seconds) to run. ; During that period, and with 4 available CPU cores, ; 2,985,281 microseconds (2.985281 seconds) were spent in user mode ; 50,118 microseconds (0.050118 seconds) were spent in system mode ; 3,653 minor page faults, 0 major page faults, 0 swaps. ; result = 10989 ; measure #<Compiled-function IS-SYM #x3020032E0B8F> from 10 to 10000000 ; (LOOP :FOR X :FROM START :TO END :WHEN (FUNCALL PREDICATE X) :COUNT :IT) ; took 4,894,920 microseconds (4.894920 seconds) to run. ; During that period, and with 4 available CPU cores, ; 4,862,373 microseconds (4.862373 seconds) were spent in user mode ; 74,544 microseconds (0.074544 seconds) were spent in system mode ; 2,876 minor page faults, 0 major page faults, 0 swaps. ; result = 10989 ; measure #<Compiled-function IS-SYM-2 #x3020032E058F> from 10 to 10000000 ; (LOOP :FOR X :FROM START :TO END :WHEN (FUNCALL PREDICATE X) :COUNT :IT) ; took 4,363,200 microseconds (4.363200 seconds) to run. ; During that period, and with 4 available CPU cores, ; 4,369,525 microseconds (4.369525 seconds) were spent in user mode ; 108,016 microseconds (0.108016 seconds) were spent in system mode ; 7,474 minor page faults, 1 major page faults, 0 swaps. ; result = 10989