Уважаемые специалисты в языке LISP. Вынужден обратиться к Вам с просьбой. Завтра мне кровь из носу нужно сдать программу на классы. В Лиспе я не силён, но две попытки я уже предпринимал: 1) Игра "Жизнь" | Код |
Код исходная матрица задается в таком виде: 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 правила просты - в след поколение проходят только единички, окруженные ровно 2 или 3 единичками. Если нолик окружен ровно 3 единичками - там рождается новая единичка
;игра "Жизнь" (defclass Life () ( (x :initarg :xi :initform 10) (y :initarg :yi :initform 10) (field) (temp-field) ) )
;считать из файла исходную матрицу (defmethod read_field (life-class filename) (setq fin (open filename :direction :input))
(setf (slot-value life-class 'x) (read fin)) (setf (slot-value life-class 'y) (read fin)) (setf (slot-value life-class 'field) (make-array (list (+ (slot-value life-class 'x) 2) (+ (slot-value life-class 'y) 2)) :initial-element 0 ) ) (setf (slot-value life-class 'temp-field) (make-array (list (+ (slot-value life-class 'x) 2) (+ (slot-value life-class 'y) 2)) :initial-element 0 ) )
(do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T) (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T) (setf (aref (slot-value life-class 'field) i j) (read fin) ) (setq j (+ j 1)) ) (setq i (+ i 1)) )
(close fin) )
;ф-я возвращает количество соседей данной клетки (defmethod neighbours (life-class i j) (+ (aref (slot-value life-class 'field) (+ i -1) (+ j -1)) (aref (slot-value life-class 'field) (+ i -1) (+ j 0)) (aref (slot-value life-class 'field) (+ i -1) (+ j 1)) (aref (slot-value life-class 'field) (+ i 0) (+ j -1)) (aref (slot-value life-class 'field) (+ i 0) (+ j 1)) (aref (slot-value life-class 'field) (+ i 1) (+ j -1)) (aref (slot-value life-class 'field) (+ i 1) (+ j 0)) (aref (slot-value life-class 'field) (+ i 1) (+ j 1)) ) )
;ф-я находит след. поколение. Для этого создается временная матрица в которой ; получается ответ, и которая потом заменяет старую (defmethod next_generation (life-class) (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T) (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T) (setf (aref (slot-value life-class 'temp-field) i j) (cond ((= (neighbours life-class i j) 3) 1) ((= (neighbours life-class i j) 2) (aref (slot-value life-class 'field) i j)) (T 0) ) ) (setq j (+ j 1)) ) (setq i (+ i 1)) )
(do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T) (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T) (setf (aref (slot-value life-class 'field) i j) (aref (slot-value life-class 'temp-field) i j) ) (setq j (+ j 1)) ) (setq i (+ i 1)) ) )
;вывести текущую матрицу на экран (defmethod print_field (life-class) (do ((i 1)) ((= i (+ (slot-value life-class 'x) 1)) T) (do ((j 1)) ((= j (+ (slot-value life-class 'y) 1)) T) (prin1 (aref (slot-value life-class 'field) i j)) (princ " ") (setq j (+ j 1)) ) (terpri) (setq i (+ i 1)) ) )
(defmethod next_and_print (life-class) (next_generation life-class) (print_field life-class) )
;это типа инициализация (setf l (make-instance 'Life)) (read_field l "c:\life.txt") ;(read_field l 'life.txt)
;чтобы поюзать прогу, надо, когда ее запустишь, вызывать ф-ю (next_and_print l) ;должно выводиться след. поколение
|
2) Класс "Множество" и операции с ними (пересечение, объединение итд) | Код | Код Создать класс “Множества” с методами, реализующими операции с ними. Сначала создадим сам класс: (defclass Sets ()((list1 :accessor set-list1 :initform nil :initarg :sl1) (list2 :accessor set-list2 :initform nil :initarg :sl2) ))
Создадим экземпляры этих классов с помощью функции make-sets: (defun make-sets (&optional S1 S2) (make-instance 'Sets :sl1 S1 :sl2 S2)) MAKE-SETS
(setf S11 (make-sets))
(setf S22 (make-sets))
Методы заполнения множеств значениями: (defmethod S1-load ((prList Sets) S1 &optional nz) (setf (set-list1 prlist) S1))
(defmethod S2-load ((prList Sets) S2 &optional ns) (setf (set-list2 prlist) S2))
При вызове данных метод множествам с начальными значениями Nil присваивается некое значение, например: (setf q (S1-load S11 '(A S C D E F))) (A S C D E F)
(setf qq (S2-load S22 '(B C D))) (B C D)
Метод для распечатки множеств: (выводит на экран множества) defmethod print-sets ((prList1 Sets)(prList2 Sets) ) (print (set-list1 prlist1)) (print (set-list2 prlist2)))
(print-sets S11 S22) (A S C D E F) (B C D)
Метод проверяет, пересекаются ли множества, если пересекаются, то выводит результат пересечения: (defmethod Inter ( ) (defun Intersec (S SS) (cond ((null S) nil) ((member (car S) SS) (cons (car S) (Intersec (cdr S) SS) )) (T (Intersec (cdr S) SS)))))
Вызов: (progn (Inter) (Intersec q qq) ) (C D)
Метод применяет операцию объединения к двум множествам и выдает результат объединения: (defmethod Unio () (defun Uni (S SS) (cond ((null S) SS) ((member (car S) SS) (Uni (cdr S) SS)) (T (cons (car S) (Uni (cdr S) SS))))))
Вызов: (progn (Unio) (Uni q qq) ) (A S E F B C D)
Метод применяет операцию дополнения к двум множествам и выдает результат дополнения: (defmethod Raznoct () (defun Deff (S1 S2 ) (cond ((null S1) nil) ((member (car S1) S2) (Deff (cdr S1) S2)) (T (cons (car S1) (Deff (cdr S1) S2)) ))))
Вызов: (progn (Raznoct) (Deff q qq) ) (A S E F)
|
Однако мой преподаватель ни одну из них мне не зачёл. Сказал, что ООП в программах применено плохо, нет наследования, преобразования методов. Необходимо сделать более гармоничную программу, чтобы методы можно было применять к каким-то другим классам. Очень прошу знатоков ЛИСПа откликнуться и придти мне на помощь. Горю, если завтра не сдам - к сессии не допустят . Может ли кто-нибудь написать программы на классы, с использованием наследования, преобразования методов и, может, каких-то ещё основных принципов ООП?
|