Last active
December 11, 2018 09:30
-
-
Save reeFridge/22f3717b36cd041140fa3738cc14ac9c to your computer and use it in GitHub Desktop.
task 149
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Напишите функцию (count р х), которая подсчитывает, сколько атомов в списке х удовлетворяет предикату р | |
;; (р -функция или функциональное имя). | |
;; Список х не предполагается одноуровневым. | |
;; кол-во эл-ов | |
(defun len (l counter) | |
(if (null l) | |
counter | |
(len (cdr l) (+ counter 1)))) | |
;; итоговая реализация | |
;; добавил print чтобы видеть какие элементы попали в список | |
;; считает сколько элементов в списке x удовлетворяют предикату (функции) p | |
(defun countp (p x) | |
(len (print (filter x p nil)) 0)) | |
;; добавляет head в список l если head проходит проверку предикатом p | |
(defun add-head-if (head l p) | |
(if (funcall p head) (cons head l) l)) | |
;; просто функции для удобства чтения с более привычными именами | |
(defun tail (l) (cdr l)) | |
(defun head (l) (car l)) | |
;; бежим по списку и если очередной элемент явлется атомом | |
;; и проходит проверку предикатом (предикат возвращает истину с этим элементом) | |
;; то добавляем его в результирующий список | |
;; --- | |
;; если же элемент является не атомом тогда рекурсивно выполняем тоже самое | |
;; только на уровне этого элемента | |
;; l - это исходный список, p - функция предикат | |
;; curr - список в который будут собираться элементы которыйе удовлетворяют предикату p | |
(defun filter (l p curr) | |
(if (null l) ;; проверяем пуст ли список l | |
curr ;; если пуст значит мы просмотрели все элементы и можем вернуть список curr (в котором на этот момент лежат элементы которые прошли проверку) | |
(filter ;; если же не пуст то рекурсивно вызываем себя же, но уже с другими аргументами: | |
(tail l) ;; тут вроде понятно (переходим к очередному элементу исходного списка l) | |
p ;; предикат остается темже | |
(if (atom (head l)) ;; если текущий рассматриваемы элемент является просто атомом (то есть НЕ списком) | |
(add-head-if (head l) curr p) ;; то проверяем элемент предикатом p и если он его удовлетворяет, то добавляем этот элемент в curr | |
(filter (head l) p curr))))) ;; если же это подсписок тогда рассматриваем его таким же образом | |
;; тестовый предикат: x < 3 | |
(defun less-threep (el) (< el 3)) | |
;; пример вызова | |
;; (countp 'less-threep '(1 2 3 4 (1 2 3 4 (-5) (-6 8 9 1 -13)) 2 3 -1 -2)) | |
;; >> (-2 -1 2 -13 1 -6 -5 2 1 2 1) | |
;; >> 11 | |
(print (countp 'less-threep '(1 2 3 4 (1 2 3 4 (-5) (-6 8 9 1 -13)) 2 3 -1 -2))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment