Министерство образования и науки РФ Федеральное агенство по образованию РФ Государственное образовательное учреждение высшего профессионального образования Самарский государственный архитектурно-строительный университет О.В. Прохорова ПРАКТИКУМ_2 на языке ЛИСП 2014 1 Оглавление 1. Реализация алгоритма быстрой сортировки на языке LISP .................................................... 2 2. Написание программы на языке Лисп, которая вычисляет сумму факториалов чисел от 1 до n. ........................................................................................................................................................... 3 3. Разработка кода программы на языке LISP, что позволит переводить числа из одной системы счисления в другую автоматически ..................................................................................... 3 4. на языке Common Lisp для шифрования текста методом полиалфавитного буквенного текста с использованием ключевого слова — шифром Виженера .................................................. 5 5. Написание программы на языке Лисп, реализующей алгоритм сортировки простыми вставками ................................................................................................................................................... 8 1. Реализация алгоритма быстрой сортировки на языке LISP Автор Кузьмин (DEFUN FIRST_EL(n lst) (COND (( < = n 0) NIL) ((NULL lst) NIL) (1 (CONS (CAR lst) (FIRST_EL (- n '1) (CDR LST)))) ) ) (DEFUN LAST_EL(n lst) (COND ((<= n 0) LST) ((NULL lst) NIL) (1 (LAST_EL (- n '1) (CDR LST))) ) ) (DEFUN SPLIT(lst) (SET 'fi (FIRST_EL (/ (LENGTH lst) 2) lst)) (SET 'li (LAST_EL (LENGTH fi) lst)) (LIST fi li) ) (DEFUN MERGE(lst1 lst2) (COND ((NULL lst1) lst2) ((NULL lst2) lst1) ((> (CAR lst1) (CAR lst2)) (CONS (CAR lst2) (MERGE lst1 (CDR lst2)))) (1 (CONS (CAR lst1) (MERGE (CDR lst1) lst2))) ) ) 2 (DEFUN SORT(LST) (COND ( (eq (LENGTH (CAR (SPLIT LST))) 1) (MERGE (CAR (SPLIT LST)) (CAR(CDR (SPLIT LST))))) ( 1 (MERGE (SORT (CAR (SPLIT LST))) (SORT(CAR (CDR (SPLIT LST)))))) ) ) 2. Написание программы на языке Лисп, которая вычисляет сумму факториалов чисел от 1 до n. Автор Амзина (defun factorial (n) (loop for i from 1 to n for m = i then (* i m) sum m)) (format t "Sum-fact is: ~A~%" (factorial 10)) Ответ системы Лисп Sum-fact is 4037913 3. Разработка кода программы на языке LISP, что позволит переводить числа из одной системы счисления в другую автоматически Автор Демин (set 'z nil) (defun next(str j lst) (set 'ch (char str j)) (set 'z (foo lst (liter_to_number ch) 1)) (string_to_list str (+ j 1) z) ) (defun foo (list k n) (if (= n 1) (cons k list) (cons (car list) (foo (cdr list) k (1- n)))) 3 ) (defun liter_to_number( liter1 ) (set 'liter (char-code liter1)) (if (and (> liter 47) (< liter 58)) (set 'koef 48) (if (and (> liter 64) (< liter 91)) (set 'koef 55) (if (and (> liter 92) (< liter 119)) (set 'koef 87) (write-line "Неизвестный символ") ) ) ) (- liter koef) ) (defun string_to_list (str i lst) (if (< i (length str)) (next str i lst) (set 'lst lst) ) ) (defun encode_dec (list base) (set 'e 0) (set 'result 0) (set 'flag 0) (loop for i in list do (set 'result (+ result (* i (stepen base e)))) (set 'e (+ e 1)) (if (> i (- base 1)) (let () (write-line "В исходных данных используется символ недоступный для данной системы счисления") (set 'flag 1) ) ) ) (if (< flag 1) (set 'result result) 4 ) ) (defun stepen (i e1) (set 'ex 1) (loop for k from 1 to e1 do (set 'ex (* ex i)) ) (set 'exit ex) ) (defun encode (n base &optional tail) (if (zerop n) (format t "~{~C~}"(or tail '(#\0))) (encode (truncate n base) base (cons (digit-char (rem n base) base) tail)) ) ) (defun systems(number1 parent_base encode_base) (encode (encode_dec (string_to_list number1 0 nil) parent_base) encode_base) ) Ответ системы Лисп: Systems “36” 10-> 2 100100 Systems “F10” 16 ->2 3856 Systems “011010” 2 -> 16 1A 4. на языке Common Lisp для шифрования текста методом полиалфавитного буквенного текста с использованием ключевого слова — шифром Виженера Автор Корчагин П. ;;; ;;; ;;; ;;; ;;; ___________________________ Шифр Виженера ___________________________ Алгоритмический смысл шифрования заключается в индивидуальном сдвиге для каждого символа исходного текста. А величина этого сдвига берется из символа словаря (его позиции, кода), соотвествующего позиции рассматриваемого символа текста. 5 (defun clean-string (s) (remove-if-not ;сравниваем символы от A до Z и если это не они, то удаляем (lambda (c) (char<= #\A c #\Z)) ;переводим всё в верхний регистр, чтобы нормально отрабатывала замена ;но тут одна особенность GNU common lisp'a всплыла ;внутри программы он различает регистры, а на вывод в консоль ;он всегда выводит символы в верхнем регистре ;из-за этого провалилась моя первая идея для курсовой (Генератор паролей) (string-upcase s) ) ) (defun vigenere (s key &key decipher &aux (A (char-code #\A)) ;auxiliary variable - вспомогательные параметры (op (if decipher #'- #'+))) ;op создаёт анонимную функцию с остаточными (&rest) параметрами (labels ; делаем 2 локальные функции ( (to-char (c) (code-char (+ c A))) (to-code (c) (- (char-code c) A)) ) ;map позволяет обрабатывать строку по одному символу за раз ;http://cl-cookbook.sourceforge.net/strings.html (let ((k (map 'list #'to-code (clean-string key)))) ;# - передаём функцию как аргумент, хотя почему то не жалуют этот метод (setf (cdr (last k)) k) (map 'string (lambda (c) (prog1 ;тоже самое, что и progn, но возвращает не значение последнего выражения, а первое. (to-char (mod (funcall op (to-code c) (car k)) 26) ;26 число букв в англ. алфавите 6 ) (setf k (cdr k)) ) ) (clean-string s) ) ) ) ) (write-line "Введите фразу для шифрования: ") ;только эта функция смогла прочитать строку с пробелами ;даже READ-PRESERVING-WHITESPACE не помог (set 'msg (read-line)) (write-line "Введите ключ для шифрования: ") (set 'key (read-line)) (let* ((enc (vigenere msg key)) (dec (vigenere enc key :decipher t))) (format t "Сообщение: ~a~%Зашифрованное: ~a~%Расшифрованное: ~a~%" msg enc dec) ) Ответ системы Lisp: Введите фразу для шифрования: Attack at dawn Введите ключ для шифрования: lemon Сообщение: Attack at dawn Зашифрованное: LXFOPVEFRNHR Расшифрованное: ATTACKATDAWN 7 5. Написание программы на языке Лисп, реализующей алгоритм сортировки простыми вставками Автор Ханов М. 8 Вопрос:(insert-sort '(3 2 1 8 4 9 7)); Ответ системы Lisp: (1 2 3 4 7 8 9) 9