Куда поставить условие? - Lisp
Формулировка задачи:
Реализовать замыкание следующим образом: необходимо, чтобы квадрат числа (которое при замыкании увеличивается на 0,01) стал приблизительно равным числу у (которое должно быть подкоренным выражением, но,когда я использую функцию sqrt возникает ошибка, но это не главное). То есть нужно сделать так,чтобы замыкание остановилось, когда мое число станет больше,чем у.
Ругается на то,что моя переменная X2 не имеет значения.
(defun power (x1) (setq y 5) #'(lambda () (setf x2 (* x1 x1)) (setq x1 (+ x1 0.01)) ) (if (> x2 y) (print "The end")) )
Решение задачи: «Куда поставить условие?»
textual
Листинг программы
(let ((y 5) (x 0)) ;; замыкание - генератор последовательных приближений кв. корня (defun reset () (setq x 0)) (defun power () (if (> (* x x) y) x (setq x (+ x 0.01))))) ;; если условие достигнуто - генератор будет возвращать одно и то же ==> power ;; в бесконечном цикле ловим момент, когда генератор начинает ;; возвращать одно и то же (let ((c (power)) (p 0) (n 0)) (loop (cond ((< (abs (- c p)) 0.000001) (printsline "The end") (return (list n c))) (t (setq p c c (power) n (+ n 1)))))) The end ==> (224 2.24) ;; достигнуто на 224-м вызове ;; Утилизировано ячеек: 0; атомов: 658. (* 2.24 2.24) ;; проверка ==> 5.0176 ;; Вторая попытка (let ((c (power)) (p 0) (n 0)) (loop (cond ((< (abs (- c p)) 0.000001) (printsline "The end") (return (list n c))) (t (setq p c c (power) n (+ n 1)))))) The end ==> (1 2.24) ;; достигнуто сразу же (reset) ;; сброс генератора ==> 0 (let ((c (power)) (p 0) (n 0)) (loop (cond ((< (abs (- c p)) 0.000001) (printsline "The end") (return (list n c))) (t (setq p c c (power) n (+ n 1)))))) The end ==> (224 2.24) ;; снова 224-й виток ;; Утилизировано ячеек: 0; атомов: 647.
Объяснение кода листинга программы
Код представляет собой реализацию метода Ньютона для вычисления квадратного корня. Вот список элементов кода с их номерами:
- (let ((y 5) (x 0)) ;; замыкание - генератор последовательных приближений кв. корня
- (defun reset () (setq x 0))
- (defun power ()
- (if (> (* x x) y) x (setq x (+ x 0.01))))) ;; если условие достигнуто - генератор будет возвращать одно и то же
- (let ((c (power)) (p 0) (n 0))
- (loop
- (cond ((< (abs (- c p)) 0.000001) (printsline
The end
) (return (list n c))) - (t (setq p c c (power) n (+ n 1))))))
- (reset) ;; сброс генератора
- (let ((c (power)) (p 0) (n 0))
- (loop
- (cond ((< (abs (- c p)) 0.000001) (printsline
The end
) (return (list n c))) - (t (setq p c c (power) n (+ n 1))))))
- The end
- (224 2.24) ;; достигнуто на 224-м вызове
- (* 2.24 2.24) ;; проверка
- 5.0176
- (let ((c (power)) (p 0) (n 0))
- (loop
- (cond ((< (abs (- c p)) 0.000001) (printsline
The end
) (return (list n c))) - (t (setq p c c (power) n (+ n 1))))))
- The end
- (1 2.24) ;; достигнуто сразу же
- (reset) ;; сброс генератора
- (let ((c (power)) (p 0) (n 0))
- (loop
- (cond ((< (abs (- c p)) 0.000001) (printsline
The end
) (return (list n c))) - (t (setq p c c (power) n (+ n 1))))))
- The end
- (224 2.24) ;; снова 224-й виток
- Утилизировано ячеек: 0; атомов: 647.
Код начинается с определения функции
power
, которая генерирует последовательность приближений квадратного корня. Функцияreset
сбрасывает генератор. Затем следует бесконечный цикл, который завершается, когда генератор начинает возвращать одно и то же значение. В этом случае выводится сообщениеThe end
и возвращается список с номером и значением, которые достигли конвергенции. После этого происходит проверка полученного значения, вычисляется квадрат этого значения, и снова проверяется, достигнуто ли условие конвергенции. Затем происходит сброс генератора и повторный расчет квадратного корня. Когда условие конвергенции достигнуто, код завершается, выводится сообщениеThe end
и возвращается список с номером и значением, которые достигли конвергенции.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д