На этом шаге мы рассмотрим использование LISP для решения вычислительных задач.
А.А.Френкель
Приведенные ниже примеры показывают, как можно проверять некоторые теоретико-числовые гипотезы, относящиеся к "школьной" теории чисел.
; -------------------------------- ; ; Делится ли число 7^77 + 1 на 5 ? ; ; -------------------------------- ; (DEFUN P (LAMBDA (X A) (CAR (DIVIDE (SETQ S (+ (STEPEN X A) 1)) 5) ) (COND ( (ZEROP (MOD S 5)) T ) ( T NIL ) ) )) ; ----------------------- ; (DEFUN STEPEN (LAMBDA (X A) ; Возведение целого числа X в целую неотрицательную ; ; степень A ; (COND ( (ZEROP A) 1 ) ( (ZEROP (- A 1)) X ) ( T (* (STEPEN X (- A 1)) X) ) ) ))
; -------------------------------------------- ; ; Составить список, состоящий из простых чисел ; ; отрезка [2,N] ; ; -------------------------------------------- ; (DEFUN PAL (LAMBDA (N) (COND ( (EQ N 2) (CONS 2 NIL) ) ( (ISPRIM N) (CONS N (PAL (- N 1))) ) ( T (PAL (- N 1)) ) ) )) ; Проверка, является ли число N простым или нет ; (DEFUN ISPRIM (LAMBDA (N) (COND ( (EQ N 1) NIL ) ( T (ISPR N 2) ) ) )) ; --------------------- ; (DEFUN ISPR (LAMBDA (N M) (COND ( (EQ M N) T ) ( (EQ (MOD N M) 0) NIL ) ( T (ISPR N (+ M 1)) ) ) ))
; ------------------------------------------------ ; ; Программа нахождения нескольких палиндромических ; ; чисел меньших 10001 ; ; ------------------------------------------------ ; (DEFUN PAL (LAMBDA () (SETQ N 1) (SETQ LST NIL) (LOOP ( (EQ N 10001) (PRIN1 "Не найдено!") ) (COND ( (EQUAL (UNPACK N) (REVERSE (UNPACK N))) (PRINT N) ) ( T ) ) (SETQ N (+ N 1)) ) )) ; ------------------- ; (DEFUN PAL1 (LAMBDA (N) (COND ( (EQ N 1) (CONS 1 NIL) ) ( (EQUAL (UNPACK N) (REVERSE (UNPACK N))) (CONS N (PAL1 (- N 1))) ) ( T (PAL1 (- N 1)) ) ) ))
; ----------------------------------------------------- ; ; Установить, представимо ли данное натуральное число в ; ; виде суммы квадратов двух натуральных чисел. ; ; ----------------------------------------------------- ; (DEFUN SUM (LAMBDA (N) (SETQ FIND NIL) (SETQ I1 1) (LOOP ( (> I1 N) ) (SETQ I2 1) (LOOP ( (> I2 N) ) ( (EQ N (+ (* I1 I1) (* I2 I2)) ) (SETQ FIND T) (SETQ A I1) (SETQ B I2) ) (SETQ I2 (+ I2 1)) ) (SETQ I1 (+ I1 1)) ) (COND (FIND (PRIN1 A) (PRIN1 " ") (PRINT B) ) ( T (PRINT NO) ) ) ))
; --------------------------------------------------- ; ; Составить программу поиска среди натуральных чисел ; ; n, n+1,..., 2n так называемых близнецов, т.е. двух ; ; простых чисел, разность которых равна 2. Если близ- ; ; нецы в указанном диапазоне найдены, то вернуть 1, ; ; если близнецов нет, то вернуть 0 ; ; --------------------------------------------------- ; (DEFUN BLIZNECI (LAMBDA (X) (SETQ MAX (* 2 X)) ( LOOP ( (> X MAX) ) (SETQ Y (+ X 2)) (COND ( (AND (SIMPLE X) (SIMPLE Y)) ((PRIN1 1) (PRIN1 " ") (PRIN1 X) (PRIN1 " ") (PRINT Y)) ) ( T 0 ) ) (SETQ X (+ X 1)) ) )) ; --------------------- ; (DEFUN SIMPLE (LAMBDA (N) (SETQ FLAG 1) (COND ( (AND (EQ (MOD N 2) 0) (NOT (EQ N 2))) NIL ) ( T ( (SETQ J 3) (LOOP ( (< (CAR (DIVIDE N 2)) J) ) ( (EQ (MOD N J) 0) (SETQ FLAG 0) ) ( SETQ J (+ J 2) ) ) (COND ( (EQ FLAG 0) NIL ) ( T T )) ) ) ) ))
; --------------------------------------------------- ; ; Гольдбахом было высказано предположение, что каждое ; ; четное число, большее или равное 4, представимо в ; ; виде суммы двух простых. Это предположение до сих ; ; пор не доказано и не опровергнуто. Написать про- ; ; грамму проверки этой гипотезы для данного четного ; ; числа. Результатом выполнения программы должен быть ; ; вывод самого числа, если не удалось найти пару ; ; простых слагаемых, и вывод пары соответствующих ; ; простых чисел, если таковая пара найдена ; ; --------------------------------------------------- ; (DEFUN SM (LAMBDA (N) (SETQ J 2) (LOOP ( (EQ J N) ) ( (AND (SIMPLE J) (SIMPLE (- N J))) ( (PRIN1 J) (PRIN1 " ") (PRINT (- N J)) ) ) (SETQ J (+ J 1)) ) )) ; --------------------- ; (DEFUN SIMPLE (LAMBDA (N) (SETQ FLAG 1) (COND ( (AND (EQ (MOD N 2) 0) (NOT (EQ N 2))) NIL ) ( T ( (SETQ I 3) (LOOP ( (< (CAR (DIVIDE N 2)) I) ) ( (EQ (MOD N I) 0) (SETQ FLAG 0) ) ( SETQ I (+ I 2) ) ) (COND ( (EQ FLAG 0) NIL ) ( T T )) ) ) ) ))
; ----------------------------------------------------- ; ; Установить является ли данное целое число p простым, ; ; используя теорему Вильсона: целое число p является ; ; простым тогда и только тогда, когда (p-1)!+1 делится ; ; на p ; ; ----------------------------------------------------- ; (DEFUN PROST (LAMBDA (P) (COND ( (ZEROP (MOD (FACT P) P)) (PRIN1 "Число простое") ) ( T (PRIN1 "Число не простое") ) ) )) ; --------------------- ; (DEFUN FACT (LAMBDA (NUM) ; Вычисление (NUM-1)! + 1 ; (SETQ ANS 1) (SETQ NUM (- NUM 1)) (LOOP ( (EQ NUM 0) ANS ) (SETQ ANS (* NUM ANS)) (SETQ NUM (- NUM 1)) ) (SETQ ANS (+ ANS 1)) ))
Со следующего шага мы начнем рассматривать объектно-ориентированное программирование в системе muLISP87.